You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
4.7 KiB

4 years ago
/**
* Toggles switch
* @param {type} $
* @param {type} window
* @param {type} name
* @returns {undefined}
*/
(function($, window, name) {
var CLASS_SWITCH = $.className('switch');
var CLASS_SWITCH_HANDLE = $.className('switch-handle');
var CLASS_ACTIVE = $.className('active');
var CLASS_DRAGGING = $.className('dragging');
var CLASS_DISABLED = $.className('disabled');
var SELECTOR_SWITCH_HANDLE = '.' + CLASS_SWITCH_HANDLE;
var handle = function(event, target) {
if (target.classList && target.classList.contains(CLASS_SWITCH)) {
return target;
}
return false;
};
$.registerTarget({
name: name,
index: 100,
handle: handle,
target: false
});
var Toggle = function(element) {
this.element = element;
this.classList = this.element.classList;
this.handle = this.element.querySelector(SELECTOR_SWITCH_HANDLE);
this.init();
this.initEvent();
};
Toggle.prototype.init = function() {
this.toggleWidth = this.element.offsetWidth;
this.handleWidth = this.handle.offsetWidth;
this.handleX = this.toggleWidth - this.handleWidth - 3;
};
Toggle.prototype.initEvent = function() {
this.element.addEventListener($.EVENT_START, this);
this.element.addEventListener('drag', this);
this.element.addEventListener('swiperight', this);
this.element.addEventListener($.EVENT_END, this);
this.element.addEventListener($.EVENT_CANCEL, this);
};
Toggle.prototype.handleEvent = function(e) {
if (this.classList.contains(CLASS_DISABLED)) {
return;
}
switch (e.type) {
case $.EVENT_START:
this.start(e);
break;
case 'drag':
this.drag(e);
break;
case 'swiperight':
this.swiperight();
break;
case $.EVENT_END:
case $.EVENT_CANCEL:
this.end(e);
break;
}
};
Toggle.prototype.start = function(e) {
this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
this.classList.add(CLASS_DRAGGING);
if (this.toggleWidth === 0 || this.handleWidth === 0) { //当switch处于隐藏状态时width为0需要重新初始化
this.init();
}
};
Toggle.prototype.drag = function(e) {
var detail = e.detail;
if (!this.isDragging) {
if (detail.direction === 'left' || detail.direction === 'right') {
this.isDragging = true;
this.lastChanged = undefined;
this.initialState = this.classList.contains(CLASS_ACTIVE);
}
}
if (this.isDragging) {
this.setTranslateX(detail.deltaX);
e.stopPropagation();
detail.gesture.preventDefault();
}
};
Toggle.prototype.swiperight = function(e) {
if (this.isDragging) {
e.stopPropagation();
}
};
Toggle.prototype.end = function(e) {
this.classList.remove(CLASS_DRAGGING);
if (this.isDragging) {
this.isDragging = false;
e.stopPropagation();
$.trigger(this.element, 'toggle', {
isActive: this.classList.contains(CLASS_ACTIVE)
});
} else {
this.toggle();
}
};
Toggle.prototype.toggle = function(animate) {
var classList = this.classList;
if (animate === false) {
this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '0s';
} else {
this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
}
if (classList.contains(CLASS_ACTIVE)) {
classList.remove(CLASS_ACTIVE);
this.handle.style.webkitTransform = 'translate(0,0)';
} else {
classList.add(CLASS_ACTIVE);
this.handle.style.webkitTransform = 'translate(' + this.handleX + 'px,0)';
}
$.trigger(this.element, 'toggle', {
isActive: this.classList.contains(CLASS_ACTIVE)
});
};
Toggle.prototype.setTranslateX = $.animationFrame(function(x) {
if (!this.isDragging) {
return;
}
var isChanged = false;
if ((this.initialState && -x > (this.handleX / 2)) || (!this.initialState && x > (this.handleX / 2))) {
isChanged = true;
}
if (this.lastChanged !== isChanged) {
if (isChanged) {
this.handle.style.webkitTransform = 'translate(' + (this.initialState ? 0 : this.handleX) + 'px,0)';
this.classList[this.initialState ? 'remove' : 'add'](CLASS_ACTIVE);
} else {
this.handle.style.webkitTransform = 'translate(' + (this.initialState ? this.handleX : 0) + 'px,0)';
this.classList[this.initialState ? 'add' : 'remove'](CLASS_ACTIVE);
}
this.lastChanged = isChanged;
}
});
$.fn['switch'] = function(options) {
var switchApis = [];
this.each(function() {
var switchApi = null;
var id = this.getAttribute('data-switch');
if (!id) {
id = ++$.uuid;
$.data[id] = new Toggle(this);
this.setAttribute('data-switch', id);
} else {
switchApi = $.data[id];
}
switchApis.push(switchApi);
});
return switchApis.length > 1 ? switchApis : switchApis[0];
};
$.ready(function() {
$('.' + CLASS_SWITCH)['switch']();
});
})(mui, window, 'toggle');