ios6switch.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. //iOS6Switch.js
  2. (function(){
  3. //FastClick 0.6.7
  4. function FastClick(a){"use strict";var b,c=this;if(this.trackingClick=!1,this.trackingClickStart=0,this.targetElement=null,this.touchStartX=0,this.touchStartY=0,this.lastTouchIdentifier=0,this.touchBoundary=10,this.layer=a,!a||!a.nodeType)throw new TypeError("Layer must be a document node");this.onClick=function(){return FastClick.prototype.onClick.apply(c,arguments)},this.onMouse=function(){return FastClick.prototype.onMouse.apply(c,arguments)},this.onTouchStart=function(){return FastClick.prototype.onTouchStart.apply(c,arguments)},this.onTouchEnd=function(){return FastClick.prototype.onTouchEnd.apply(c,arguments)},this.onTouchCancel=function(){return FastClick.prototype.onTouchCancel.apply(c,arguments)},FastClick.notNeeded(a)||(this.deviceIsAndroid&&(a.addEventListener("mouseover",this.onMouse,!0),a.addEventListener("mousedown",this.onMouse,!0),a.addEventListener("mouseup",this.onMouse,!0)),a.addEventListener("click",this.onClick,!0),a.addEventListener("touchstart",this.onTouchStart,!1),a.addEventListener("touchend",this.onTouchEnd,!1),a.addEventListener("touchcancel",this.onTouchCancel,!1),Event.prototype.stopImmediatePropagation||(a.removeEventListener=function(b,c,d){var e=Node.prototype.removeEventListener;"click"===b?e.call(a,b,c.hijacked||c,d):e.call(a,b,c,d)},a.addEventListener=function(b,c,d){var e=Node.prototype.addEventListener;"click"===b?e.call(a,b,c.hijacked||(c.hijacked=function(a){a.propagationStopped||c(a)}),d):e.call(a,b,c,d)}),"function"==typeof a.onclick&&(b=a.onclick,a.addEventListener("click",function(a){b(a)},!1),a.onclick=null))}FastClick.prototype.deviceIsAndroid=navigator.userAgent.indexOf("Android")>0,FastClick.prototype.deviceIsIOS=/iP(ad|hone|od)/.test(navigator.userAgent),FastClick.prototype.deviceIsIOS4=FastClick.prototype.deviceIsIOS&&/OS 4_\d(_\d)?/.test(navigator.userAgent),FastClick.prototype.deviceIsIOSWithBadTarget=FastClick.prototype.deviceIsIOS&&/OS ([6-9]|\d{2})_\d/.test(navigator.userAgent),FastClick.prototype.needsClick=function(a){"use strict";switch(a.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(a.disabled)return!0;break;case"input":if(this.deviceIsIOS&&"file"===a.type||a.disabled)return!0;break;case"label":case"video":return!0}return/\bneedsclick\b/.test(a.className)},FastClick.prototype.needsFocus=function(a){"use strict";switch(a.nodeName.toLowerCase()){case"textarea":case"select":return!0;case"input":switch(a.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!a.disabled&&!a.readOnly;default:return/\bneedsfocus\b/.test(a.className)}},FastClick.prototype.sendClick=function(a,b){"use strict";var c,d;document.activeElement&&document.activeElement!==a&&document.activeElement.blur(),d=b.changedTouches[0],c=document.createEvent("MouseEvents"),c.initMouseEvent("click",!0,!0,window,1,d.screenX,d.screenY,d.clientX,d.clientY,!1,!1,!1,!1,0,null),c.forwardedTouchEvent=!0,a.dispatchEvent(c)},FastClick.prototype.focus=function(a){"use strict";var b;this.deviceIsIOS&&a.setSelectionRange?(b=a.value.length,a.setSelectionRange(b,b)):a.focus()},FastClick.prototype.updateScrollParent=function(a){"use strict";var b,c;if(b=a.fastClickScrollParent,!b||!b.contains(a)){c=a;do{if(c.scrollHeight>c.offsetHeight){b=c,a.fastClickScrollParent=c;break}c=c.parentElement}while(c)}b&&(b.fastClickLastScrollTop=b.scrollTop)},FastClick.prototype.getTargetElementFromEventTarget=function(a){"use strict";return a.nodeType===Node.TEXT_NODE?a.parentNode:a},FastClick.prototype.onTouchStart=function(a){"use strict";var b,c,d;if(a.targetTouches.length>1)return!0;if(b=this.getTargetElementFromEventTarget(a.target),c=a.targetTouches[0],this.deviceIsIOS){if(d=window.getSelection(),d.rangeCount&&!d.isCollapsed)return!0;if(!this.deviceIsIOS4){if(c.identifier===this.lastTouchIdentifier)return a.preventDefault(),!1;this.lastTouchIdentifier=c.identifier,this.updateScrollParent(b)}}return this.trackingClick=!0,this.trackingClickStart=a.timeStamp,this.targetElement=b,this.touchStartX=c.pageX,this.touchStartY=c.pageY,a.timeStamp-this.lastClickTime<200&&a.preventDefault(),!0},FastClick.prototype.touchHasMoved=function(a){"use strict";var b=a.changedTouches[0],c=this.touchBoundary;return Math.abs(b.pageX-this.touchStartX)>c||Math.abs(b.pageY-this.touchStartY)>c?!0:!1},FastClick.prototype.findControl=function(a){"use strict";return void 0!==a.control?a.control:a.htmlFor?document.getElementById(a.htmlFor):a.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},FastClick.prototype.onTouchEnd=function(a){"use strict";var b,c,d,e,f,g=this.targetElement;if((this.touchHasMoved(a)||a.timeStamp-this.trackingClickStart>300)&&(this.trackingClick=!1,this.targetElement=null),!this.trackingClick)return!0;if(a.timeStamp-this.lastClickTime<200)return this.cancelNextClick=!0,!0;if(this.lastClickTime=a.timeStamp,c=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,this.deviceIsIOSWithBadTarget&&(f=a.changedTouches[0],g=document.elementFromPoint(f.pageX-window.pageXOffset,f.pageY-window.pageYOffset)),d=g.tagName.toLowerCase(),"label"===d){if(b=this.findControl(g)){if(this.focus(g),this.deviceIsAndroid)return!1;g=b}}else if(this.needsFocus(g))return a.timeStamp-c>100||this.deviceIsIOS&&window.top!==window&&"input"===d?(this.targetElement=null,!1):(this.focus(g),this.deviceIsIOS4&&"select"===d||(this.targetElement=null,a.preventDefault()),!1);return this.deviceIsIOS&&!this.deviceIsIOS4&&(e=g.fastClickScrollParent,e&&e.fastClickLastScrollTop!==e.scrollTop)?!0:(this.needsClick(g)||(a.preventDefault(),this.sendClick(g,a)),!1)},FastClick.prototype.onTouchCancel=function(){"use strict";this.trackingClick=!1,this.targetElement=null},FastClick.prototype.onMouse=function(a){"use strict";return this.targetElement?a.forwardedTouchEvent?!0:a.cancelable?!this.needsClick(this.targetElement)||this.cancelNextClick?(a.stopImmediatePropagation?a.stopImmediatePropagation():a.propagationStopped=!0,a.stopPropagation(),a.preventDefault(),!1):!0:!0:!0},FastClick.prototype.onClick=function(a){"use strict";var b;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===a.target.type&&0===a.detail?!0:(b=this.onMouse(a),b||(this.targetElement=null),b)},FastClick.prototype.destroy=function(){"use strict";var a=this.layer;this.deviceIsAndroid&&(a.removeEventListener("mouseover",this.onMouse,!0),a.removeEventListener("mousedown",this.onMouse,!0),a.removeEventListener("mouseup",this.onMouse,!0)),a.removeEventListener("click",this.onClick,!0),a.removeEventListener("touchstart",this.onTouchStart,!1),a.removeEventListener("touchend",this.onTouchEnd,!1),a.removeEventListener("touchcancel",this.onTouchCancel,!1)},FastClick.notNeeded=function(a){"use strict";var b;if("undefined"==typeof window.ontouchstart)return!0;if(/Chrome\/[0-9]+/.test(navigator.userAgent)){if(!FastClick.prototype.deviceIsAndroid)return!0;if(b=document.querySelector("meta[name=viewport]"),b&&-1!==b.content.indexOf("user-scalable=no"))return!0}return"none"===a.style.msTouchAction?!0:!1},FastClick.attach=function(a){"use strict";return new FastClick(a)},"undefined"!=typeof define&&define.amd?define(function(){"use strict";return FastClick}):"undefined"!=typeof module&&module.exports?(module.exports=FastClick.attach,module.exports.FastClick=FastClick):window.FastClick=FastClick;
  5. var id = 0;
  6. var sList = new Array, hList = new Array;
  7. Array.prototype.remove = function(dx){
  8. if(isNaN(dx) || dx > this.length){
  9. return false;
  10. }
  11. for(var i = 0, n = 0; i < this.length; i ++){
  12. if(this[i] != this[dx]){
  13. this[n ++] = this[i];
  14. }
  15. }
  16. this.length -= 1;
  17. }
  18. var getBorderWidth = function(e, b){
  19. var w = Number(e.css("border-" + b + "-width").replace(/px/g, ""));
  20. isNaN(w) && (w = 0);
  21. return w;
  22. }
  23. var init = function(_elem, _opt){
  24. if(_elem.attr("ios6switch") == "true") return;
  25. _elem.attr("ios6switch", "true");
  26. _opt.showOriginalCheckbox != true && _elem.css("display", "none");
  27. var switchelement = '<div class="ios6switch ios6switch' + id + '"><div class="ios6switch_shadow_and_highlight"></div><div class="ios6switch_draglayer"><div class="ios6switch_switch_on"></div><div class="ios6switch_thumb"></div><div class="ios6switch_switch_off"></div></div></div>';
  28. _elem.after(switchelement);
  29. sList.push("ios6switch" + id);
  30. hList.push(-1);
  31. var thisid = id;
  32. var _switcher = $(".ios6switch" + id);
  33. _opt.addClass != "" && _switcher.addClass(_opt.addClass);
  34. _switcher.css({
  35. height: _opt.size + "px"
  36. });
  37. _switcher.find(".ios6switch_switch_on").html(_opt.switchonText);
  38. _switcher.find(".ios6switch_switch_off").html(_opt.switchoffText);
  39. _switcher.find(".ios6switch_switch_on").css({
  40. "background-color": _opt.switchonColor,
  41. "color": _opt.switchonTextColor,
  42. });
  43. _switcher.find(".ios6switch_switch_off").css({
  44. "background-color": _opt.switchoffColor,
  45. "color": _opt.switchoffTextColor,
  46. });
  47. _opt.thumbSwitchonColor == "" && (_opt.thumbSwitchonColor = _opt.thumbColor);
  48. _opt.thumbPressedColor == "" && (_opt.thumbPressedColor = _opt.thumbColor);
  49. _opt.thumbSwitchonPressedColor == "" && (_opt.thumbSwitchonPressedColor = _opt.thumbPressedColor);
  50. _switcher.find(".ios6switch_thumb").attr("data-thumb-color", _opt.thumbColor);
  51. _switcher.find(".ios6switch_thumb").attr("data-thumb-on-color", _opt.thumbSwitchonColor);
  52. _switcher.find(".ios6switch_thumb").attr("data-thumb-pressed-color", _opt.thumbPressedColor);
  53. _switcher.find(".ios6switch_thumb").attr("data-thumb-on-pressed-color", _opt.thumbSwitchonPressedColor);
  54. _switcher.find(".ios6switch_thumb").attr("data-pressed", "false");
  55. setSize(_switcher);
  56. setThumbColor(_switcher);
  57. var startpress = function(){
  58. _switcher.attr("data-disabled") != "true" && _switcher.find(".ios6switch_thumb").attr("data-pressed", "true");
  59. setThumbColor(_switcher);
  60. }
  61. var endpress = function(){
  62. _switcher.find(".ios6switch_thumb").attr("data-pressed", "false");
  63. setThumbColor(_switcher);
  64. }
  65. _switcher.find(".ios6switch_thumb").mousedown(startpress);
  66. $(document).mouseup(endpress);
  67. _switcher.find(".ios6switch_thumb")[0].addEventListener && _switcher.find(".ios6switch_thumb")[0].addEventListener("touchstart", startpress, false);
  68. _switcher.find(".ios6switch_thumb")[0].addEventListener && document.addEventListener('touchend', endpress, false);
  69. var disabled = false;
  70. var posX, lastX, dragged = false, dragging = false, dragging2 = false;
  71. if(_opt.draggable == true){
  72. var startdrag = function(e){
  73. if(disabled != true){
  74. if(e.changedTouches) {
  75. e.pageX = e.changedTouches[0].pageX;
  76. }
  77. posX = e.pageX - _switcher.find(".ios6switch_draglayer").position().left;
  78. _switcher.find(".ios6switch_draglayer").stop(true);
  79. lastX = e.pageX;
  80. dragging = true;
  81. }
  82. }
  83. var stopdrag = function(){
  84. if(dragging2 == true){
  85. dragged = true;
  86. toggleswitch();
  87. }
  88. dragging = false;
  89. dragging2 = false;
  90. }
  91. var move = function(e){
  92. if(e.changedTouches){
  93. e.pageX = e.changedTouches[0].pageX;
  94. }
  95. if(dragging == true && Math.abs(e.pageX - lastX) > 5){
  96. dragging2 = true;
  97. }
  98. if(dragging2 == true){
  99. var thisposX = e.pageX - posX;
  100. if(thisposX < 0){
  101. thisposX = 0;
  102. }
  103. else if(thisposX > _switcher.innerWidth() - _switcher.innerHeight()){
  104. thisposX = _switcher.innerWidth() - _switcher.innerHeight();
  105. }
  106. _switcher.find(".ios6switch_draglayer").css({
  107. "left": thisposX + "px"
  108. });
  109. setThumbColor(_switcher);
  110. }
  111. dragging && (e.preventDefault ? e.preventDefault() : window.event.returnValue = false);
  112. }
  113. _switcher.find(".ios6switch_thumb").mousedown(startdrag);
  114. $(document).mouseup(stopdrag);
  115. $(document).mousemove(move);
  116. _switcher.find(".ios6switch_thumb")[0].addEventListener && _switcher.find(".ios6switch_thumb")[0].addEventListener("touchstart", startdrag, false);
  117. document.addEventListener && document.addEventListener('touchend', stopdrag, false);
  118. document.addEventListener && document.addEventListener('touchmove', function(e){
  119. if(e.targetTouches.length <= 1 && dragging == true) move(e);
  120. }, false);
  121. }
  122. var disable = function(){
  123. disabled = true;
  124. _switcher.css("opacity", _opt.disabledOpacity);
  125. _switcher.attr("data-disabled", "true");
  126. _elem[0].disabled = true;
  127. }
  128. var enable = function(){
  129. disabled = false;
  130. _switcher.css("opacity", "");
  131. _switcher.attr("data-disabled", "false");
  132. _elem[0].disabled = false;
  133. }
  134. _elem[0].disabled == true && disable();
  135. var checkstatus = _elem[0].checked;
  136. _elem[0].checked == true && _switcher.find(".ios6switch_draglayer").css("left", ((_switcher.innerHeight() * 79 / 27) - _switcher.innerHeight()) + "px");
  137. FastClick.attach(_switcher[0]);
  138. _elem.click(function(){
  139. checkstatus = !_elem[0].checked;
  140. toggleswitch();
  141. });
  142. var soundElement;
  143. if(_opt.sound != ""){
  144. soundElement = "<audio id=\"switchsound" + thisid + "\" preload=\"auto\" src=\"" + _opt.sound + "\"></audio>";
  145. $("body").append(soundElement);
  146. };
  147. var toggleswitch = function(){
  148. if(disabled == true) return;
  149. var thumbx = _switcher.find(".ios6switch_draglayer").position().left;
  150. var switchw = _switcher.innerWidth() - _switcher.innerHeight();
  151. var evt = document.createEvent ? document.createEvent("HTMLEvents") : false;
  152. evt && evt.initEvent("change", true, true);
  153. _switcher.attr("hasAnimate", "true");
  154. if(dragged == true && thumbx <= switchw / 2 || dragged != true && checkstatus == true){
  155. _switcher.find(".ios6switch_draglayer").stop(true).animate({
  156. left: "0px"
  157. }, (thumbx / switchw) * _opt.animateSpeed, _opt.animateEasing, function(){
  158. _switcher.removeAttr("hasAnimate");
  159. _elem[0].checked = false;
  160. evt ? _elem[0].dispatchEvent(evt) : _elem[0].fireEvent("onchange");
  161. });
  162. checkstatus = false;
  163. }
  164. else{
  165. _switcher.find(".ios6switch_draglayer").stop(true).animate({
  166. left: (_switcher.innerWidth() - _switcher.innerHeight()) + "px"
  167. }, ((switchw - thumbx) / switchw) * _opt.animateSpeed, _opt.animateEasing, function(){
  168. _switcher.removeAttr("hasAnimate");
  169. _elem[0].checked = true;
  170. evt ? _elem[0].dispatchEvent(evt) : _elem[0].fireEvent("onchange");
  171. });
  172. checkstatus = true;
  173. }
  174. setTimeout(function(){
  175. dragged = false;
  176. }, 10);
  177. if(_opt.sound != "" && typeof $("#switchsound" + thisid)[0].play != "undefined"){
  178. $("#switchsound" + thisid)[0].currentTime = 0;
  179. $("#switchsound" + thisid)[0].play();
  180. }
  181. }
  182. _switcher[0].addEventListener ? _switcher[0].addEventListener("click", toggleswitch) : _switcher[0].attachEvent("onclick", toggleswitch);
  183. var switchon = function(){
  184. checkstatus = false;
  185. toggleswitch();
  186. }
  187. var switchoff = function(){
  188. checkstatus = true;
  189. toggleswitch();
  190. }
  191. var destroy = function(){
  192. sList.remove(thisid);
  193. hList.remove(thisid);
  194. id --;
  195. _elem.unbind("disable");
  196. _elem.unbind("enable");
  197. _elem.unbind("switchon");
  198. _elem.unbind("switchoff");
  199. _elem.unbind("toggleswitch");
  200. _elem.unbind("destroy");
  201. _switcher.remove();
  202. $("#switchsound" + thisid).remove();
  203. _elem.removeAttr("ios6switch");
  204. _elem.css("display", "");
  205. }
  206. id ++;
  207. _elem.bind("disable", disable);
  208. _elem.bind("enable", enable);
  209. _elem.bind("switchon", switchon);
  210. _elem.bind("switchoff", switchoff);
  211. _elem.bind("toggleswitch", toggleswitch);
  212. _elem.bind("destroy", destroy);
  213. }
  214. var startinterval = false;
  215. var interval = function(){
  216. if(startinterval != true) return;
  217. for(var i = 0; i < id; i ++){
  218. var te = $("." + sList[i]);
  219. if(hList[i] != te.innerHeight()){
  220. setSize(te);
  221. hList[i] = te.innerHeight();
  222. }
  223. te.attr("hasAnimate") == "true" && setThumbColor(te);
  224. }
  225. }
  226. setInterval(interval, 25);
  227. var setThumbColor = function(te){
  228. var switchh = te.innerHeight();
  229. var switchw = te.innerWidth();
  230. var layerx = te.find(".ios6switch_draglayer").position().left;
  231. if(te.find(".ios6switch_thumb").attr("data-pressed") == "true"){
  232. (layerx <= (switchw - switchh) / 2) ? te.find(".ios6switch_thumb").css("background-color", te.find(".ios6switch_thumb").attr("data-thumb-pressed-color")) : te.find(".ios6switch_thumb").css("background-color", te.find(".ios6switch_thumb").attr("data-thumb-on-pressed-color"));
  233. }
  234. else{
  235. (layerx <= (switchw - switchh) / 2) ? te.find(".ios6switch_thumb").css("background-color", te.find(".ios6switch_thumb").attr("data-thumb-color")) : te.find(".ios6switch_thumb").css("background-color", te.find(".ios6switch_thumb").attr("data-thumb-on-color"));
  236. }
  237. }
  238. var setSize = function(te){
  239. var layerat = te.find(".ios6switch_draglayer").position().left / te.innerWidth();
  240. te.css("width", (te.innerHeight() * 79 / 27) + "px");
  241. var thumbx = te.find(".ios6switch_thumb").position().left;
  242. var thumbb1 = getBorderWidth(te.find(".ios6switch_thumb"), "top");
  243. var thumbb2 = getBorderWidth(te.find(".ios6switch_thumb"), "bottom");
  244. var layerx = te.find(".ios6switch_draglayer").position().left;
  245. var switchh = te.innerHeight();
  246. var switchw = te.innerWidth();
  247. te.find(".ios6switch_thumb").css({
  248. width: (switchh - thumbb1 - thumbb2) + "px",
  249. height: (switchh - thumbb1 - thumbb2) + "px"
  250. });
  251. te.css("border-radius", (te.outerHeight() / 2) + "px");
  252. te.find(".ios6switch_switch_on").css("left", (thumbx + (switchh / 2) - switchw) + "px");
  253. te.find(".ios6switch_switch_off").css("left", (thumbx + (switchh / 2)) + "px");
  254. te.find(".ios6switch_draglayer").css("left", (te.innerWidth() * layerat) + "px");
  255. te.find(".ios6switch_switch_on, .ios6switch_switch_off").css({
  256. "line-height" : switchh + "px",
  257. "font-size" : (switchh * .7) + "px"
  258. });
  259. }
  260. $.fn.extend({
  261. ios6switch: function(opt){
  262. var _def = {
  263. draggable: true,
  264. size: 27,
  265. showOriginalCheckbox: false,
  266. disabledOpacity: 0.5,
  267. animateSpeed: 400,
  268. animateEasing: "swing",
  269. addClass: "",
  270. sound: "",
  271. thumbColor: "#FFFFFF",
  272. thumbPressedColor: "#CCCCCC",
  273. thumbSwitchonColor: "",
  274. thumbSwitchonPressedColor: "",
  275. switchoffColor: "#FFFFFF",
  276. switchonColor: "#008AF2",
  277. switchoffTextColor: "#555555",
  278. switchonTextColor: "#FFFFFF",
  279. switchoffText: "0",
  280. switchonText: "1"
  281. }
  282. var opt = opt || {};
  283. var _opt = $.extend(_def, opt);
  284. for(i in $(this)){
  285. var te = $(this).eq(i);
  286. startinterval = true;
  287. te.is("input[type=checkbox]") && init($(this).eq(i), _opt);
  288. }
  289. }
  290. })
  291. })(jQuery);