1
0

switches.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /**
  2. * Toggles switch
  3. * @param {type} $
  4. * @param {type} window
  5. * @param {type} name
  6. * @returns {undefined}
  7. */
  8. (function($, window, name) {
  9. var CLASS_SWITCH = $.className('switch');
  10. var CLASS_SWITCH_HANDLE = $.className('switch-handle');
  11. var CLASS_ACTIVE = $.className('active');
  12. var CLASS_DRAGGING = $.className('dragging');
  13. var CLASS_DISABLED = $.className('disabled');
  14. var SELECTOR_SWITCH_HANDLE = '.' + CLASS_SWITCH_HANDLE;
  15. var handle = function(event, target) {
  16. if (target.classList && target.classList.contains(CLASS_SWITCH)) {
  17. return target;
  18. }
  19. return false;
  20. };
  21. $.registerTarget({
  22. name: name,
  23. index: 100,
  24. handle: handle,
  25. target: false
  26. });
  27. var Toggle = function(element) {
  28. this.element = element;
  29. this.classList = this.element.classList;
  30. this.handle = this.element.querySelector(SELECTOR_SWITCH_HANDLE);
  31. this.init();
  32. this.initEvent();
  33. };
  34. Toggle.prototype.init = function() {
  35. this.toggleWidth = this.element.offsetWidth;
  36. this.handleWidth = this.handle.offsetWidth;
  37. this.handleX = this.toggleWidth - this.handleWidth - 3;
  38. };
  39. Toggle.prototype.initEvent = function() {
  40. this.element.addEventListener($.EVENT_START, this);
  41. this.element.addEventListener('drag', this);
  42. this.element.addEventListener('swiperight', this);
  43. this.element.addEventListener($.EVENT_END, this);
  44. this.element.addEventListener($.EVENT_CANCEL, this);
  45. };
  46. Toggle.prototype.handleEvent = function(e) {
  47. if (this.classList.contains(CLASS_DISABLED)) {
  48. return;
  49. }
  50. switch (e.type) {
  51. case $.EVENT_START:
  52. this.start(e);
  53. break;
  54. case 'drag':
  55. this.drag(e);
  56. break;
  57. case 'swiperight':
  58. this.swiperight();
  59. break;
  60. case $.EVENT_END:
  61. case $.EVENT_CANCEL:
  62. this.end(e);
  63. break;
  64. }
  65. };
  66. Toggle.prototype.start = function(e) {
  67. this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
  68. this.classList.add(CLASS_DRAGGING);
  69. if (this.toggleWidth === 0 || this.handleWidth === 0) { //当switch处于隐藏状态时,width为0,需要重新初始化
  70. this.init();
  71. }
  72. };
  73. Toggle.prototype.drag = function(e) {
  74. var detail = e.detail;
  75. if (!this.isDragging) {
  76. if (detail.direction === 'left' || detail.direction === 'right') {
  77. this.isDragging = true;
  78. this.lastChanged = undefined;
  79. this.initialState = this.classList.contains(CLASS_ACTIVE);
  80. }
  81. }
  82. if (this.isDragging) {
  83. this.setTranslateX(detail.deltaX);
  84. e.stopPropagation();
  85. detail.gesture.preventDefault();
  86. }
  87. };
  88. Toggle.prototype.swiperight = function(e) {
  89. if (this.isDragging) {
  90. e.stopPropagation();
  91. }
  92. };
  93. Toggle.prototype.end = function(e) {
  94. this.classList.remove(CLASS_DRAGGING);
  95. if (this.isDragging) {
  96. this.isDragging = false;
  97. e.stopPropagation();
  98. $.trigger(this.element, 'toggle', {
  99. isActive: this.classList.contains(CLASS_ACTIVE)
  100. });
  101. } else {
  102. this.toggle();
  103. }
  104. };
  105. Toggle.prototype.toggle = function(animate) {
  106. var classList = this.classList;
  107. if (animate === false) {
  108. this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '0s';
  109. } else {
  110. this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
  111. }
  112. if (classList.contains(CLASS_ACTIVE)) {
  113. classList.remove(CLASS_ACTIVE);
  114. this.handle.style.webkitTransform = 'translate(0,0)';
  115. } else {
  116. classList.add(CLASS_ACTIVE);
  117. this.handle.style.webkitTransform = 'translate(' + this.handleX + 'px,0)';
  118. }
  119. $.trigger(this.element, 'toggle', {
  120. isActive: this.classList.contains(CLASS_ACTIVE)
  121. });
  122. };
  123. Toggle.prototype.setTranslateX = $.animationFrame(function(x) {
  124. if (!this.isDragging) {
  125. return;
  126. }
  127. var isChanged = false;
  128. if ((this.initialState && -x > (this.handleX / 2)) || (!this.initialState && x > (this.handleX / 2))) {
  129. isChanged = true;
  130. }
  131. if (this.lastChanged !== isChanged) {
  132. if (isChanged) {
  133. this.handle.style.webkitTransform = 'translate(' + (this.initialState ? 0 : this.handleX) + 'px,0)';
  134. this.classList[this.initialState ? 'remove' : 'add'](CLASS_ACTIVE);
  135. } else {
  136. this.handle.style.webkitTransform = 'translate(' + (this.initialState ? this.handleX : 0) + 'px,0)';
  137. this.classList[this.initialState ? 'add' : 'remove'](CLASS_ACTIVE);
  138. }
  139. this.lastChanged = isChanged;
  140. }
  141. });
  142. $.fn['switch'] = function(options) {
  143. var switchApis = [];
  144. this.each(function() {
  145. var switchApi = null;
  146. var id = this.getAttribute('data-switch');
  147. if (!id) {
  148. id = ++$.uuid;
  149. $.data[id] = new Toggle(this);
  150. this.setAttribute('data-switch', id);
  151. } else {
  152. switchApi = $.data[id];
  153. }
  154. switchApis.push(switchApi);
  155. });
  156. return switchApis.length > 1 ? switchApis : switchApis[0];
  157. };
  158. $.ready(function() {
  159. $('.' + CLASS_SWITCH)['switch']();
  160. });
  161. })(mui, window, 'toggle');