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.

521 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* Tableviews
* @param {type} $
* @param {type} window
* @param {type} document
* @returns {undefined}
*/
(function($, window, document) {
var CLASS_ACTIVE = $.className('active');
var CLASS_SELECTED = $.className('selected');
var CLASS_GRID_VIEW = $.className('grid-view');
var CLASS_RADIO_VIEW = $.className('table-view-radio');
var CLASS_TABLE_VIEW_CELL = $.className('table-view-cell');
var CLASS_COLLAPSE_CONTENT = $.className('collapse-content');
var CLASS_DISABLED = $.className('disabled');
var CLASS_TOGGLE = $.className('switch');
var CLASS_BTN = $.className('btn');
var CLASS_SLIDER_HANDLE = $.className('slider-handle');
var CLASS_SLIDER_LEFT = $.className('slider-left');
var CLASS_SLIDER_RIGHT = $.className('slider-right');
var CLASS_TRANSITIONING = $.className('transitioning');
var SELECTOR_SLIDER_HANDLE = '.' + CLASS_SLIDER_HANDLE;
var SELECTOR_SLIDER_LEFT = '.' + CLASS_SLIDER_LEFT;
var SELECTOR_SLIDER_RIGHT = '.' + CLASS_SLIDER_RIGHT;
var SELECTOR_SELECTED = '.' + CLASS_SELECTED;
var SELECTOR_BUTTON = '.' + CLASS_BTN;
var overFactor = 0.8;
var cell, a;
var isMoved = isOpened = openedActions = progress = false;
var sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
var timer = translateX = lastTranslateX = sliderActionLeftWidth = sliderActionRightWidth = 0;
var toggleActive = function(isActive) {
if (isActive) {
if (a) {
a.classList.add(CLASS_ACTIVE);
} else if (cell) {
cell.classList.add(CLASS_ACTIVE);
}
} else {
timer && timer.cancel();
if (a) {
a.classList.remove(CLASS_ACTIVE);
} else if (cell) {
cell.classList.remove(CLASS_ACTIVE);
}
}
};
var updateTranslate = function() {
if (translateX !== lastTranslateX) {
if (buttonsRight && buttonsRight.length > 0) {
progress = translateX / sliderActionRightWidth;
if (translateX < -sliderActionRightWidth) {
translateX = -sliderActionRightWidth - Math.pow(-translateX - sliderActionRightWidth, overFactor);
}
for (var i = 0, len = buttonsRight.length; i < len; i++) {
var buttonRight = buttonsRight[i];
if (typeof buttonRight._buttonOffset === 'undefined') {
buttonRight._buttonOffset = buttonRight.offsetLeft;
}
buttonOffset = buttonRight._buttonOffset;
setTranslate(buttonRight, (translateX - buttonOffset * (1 + Math.max(progress, -1))));
}
}
if (buttonsLeft && buttonsLeft.length > 0) {
progress = translateX / sliderActionLeftWidth;
if (translateX > sliderActionLeftWidth) {
translateX = sliderActionLeftWidth + Math.pow(translateX - sliderActionLeftWidth, overFactor);
}
for (var i = 0, len = buttonsLeft.length; i < len; i++) {
var buttonLeft = buttonsLeft[i];
if (typeof buttonLeft._buttonOffset === 'undefined') {
buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
}
buttonOffset = buttonLeft._buttonOffset;
if (buttonsLeft.length > 1) {
buttonLeft.style.zIndex = buttonsLeft.length - i;
}
setTranslate(buttonLeft, (translateX + buttonOffset * (1 - Math.min(progress, 1))));
}
}
setTranslate(sliderHandle, translateX);
lastTranslateX = translateX;
}
sliderRequestAnimationFrame = requestAnimationFrame(function() {
updateTranslate();
});
};
var setTranslate = function(element, x) {
if (element) {
element.style.webkitTransform = 'translate(' + x + 'px,0)';
}
};
window.addEventListener($.EVENT_START, function(event) {
if (cell) {
toggleActive(false);
}
cell = a = false;
isMoved = isOpened = openedActions = false;
var target = event.target;
var isDisabled = false;
for (; target && target !== document; target = target.parentNode) {
if (target.classList) {
var classList = target.classList;
if ((target.tagName === 'INPUT' && target.type !== 'radio' && target.type !== 'checkbox') || target.tagName === 'BUTTON' || classList.contains(CLASS_TOGGLE) || classList.contains(CLASS_BTN) || classList.contains(CLASS_DISABLED)) {
isDisabled = true;
}
if (classList.contains(CLASS_COLLAPSE_CONTENT)) { //collapse content
break;
}
if (classList.contains(CLASS_TABLE_VIEW_CELL)) {
cell = target;
//TODO swipe to delete close
var selected = cell.parentNode.querySelector(SELECTOR_SELECTED);
if (!cell.parentNode.classList.contains(CLASS_RADIO_VIEW) && selected && selected !== cell) {
$.swipeoutClose(selected);
cell = isDisabled = false;
return;
}
if (!cell.parentNode.classList.contains(CLASS_GRID_VIEW)) {
var link = cell.querySelector('a');
if (link && link.parentNode === cell) { //li>a
a = link;
}
}
var handle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
if (handle) {
toggleEvents(cell);
event.stopPropagation();
}
if (!isDisabled) {
if (handle) {
if (timer) {
timer.cancel();
}
timer = $.later(function() {
toggleActive(true);
}, 100);
} else {
toggleActive(true);
}
}
break;
}
}
}
});
window.addEventListener($.EVENT_MOVE, function(event) {
toggleActive(false);
});
var handleEvent = {
handleEvent: function(event) {
switch (event.type) {
case 'drag':
this.drag(event);
break;
case 'dragend':
this.dragend(event);
break;
case 'flick':
this.flick(event);
break;
case 'swiperight':
this.swiperight(event);
break;
case 'swipeleft':
this.swipeleft(event);
break;
}
},
drag: function(event) {
if (!cell) {
return;
}
if (!isMoved) { //init
sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
sliderHandle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
if (sliderHandle) {
sliderActionLeft = cell.querySelector(SELECTOR_SLIDER_LEFT);
sliderActionRight = cell.querySelector(SELECTOR_SLIDER_RIGHT);
if (sliderActionLeft) {
sliderActionLeftWidth = sliderActionLeft.offsetWidth;
buttonsLeft = sliderActionLeft.querySelectorAll(SELECTOR_BUTTON);
}
if (sliderActionRight) {
sliderActionRightWidth = sliderActionRight.offsetWidth;
buttonsRight = sliderActionRight.querySelectorAll(SELECTOR_BUTTON);
}
cell.classList.remove(CLASS_TRANSITIONING);
isOpened = cell.classList.contains(CLASS_SELECTED);
if (isOpened) {
openedActions = cell.querySelector(SELECTOR_SLIDER_LEFT + SELECTOR_SELECTED) ? 'left' : 'right';
}
}
}
var detail = event.detail;
var direction = detail.direction;
var angle = detail.angle;
if (direction === 'left' && (angle > 150 || angle < -150)) {
if (buttonsRight || (buttonsLeft && isOpened)) { //存在右侧按钮或存在左侧按钮且是已打开状态
isMoved = true;
}
} else if (direction === 'right' && (angle > -30 && angle < 30)) {
if (buttonsLeft || (buttonsRight && isOpened)) { //存在左侧按钮或存在右侧按钮且是已打开状态
isMoved = true;
}
}
if (isMoved) {
event.stopPropagation();
event.detail.gesture.preventDefault();
var translate = event.detail.deltaX;
if (isOpened) {
if (openedActions === 'right') {
translate = translate - sliderActionRightWidth;
} else {
translate = translate + sliderActionLeftWidth;
}
}
if ((translate > 0 && !buttonsLeft) || (translate < 0 && !buttonsRight)) {
if (!isOpened) {
return;
}
translate = 0;
}
if (translate < 0) {
sliderDirection = 'toLeft';
} else if (translate > 0) {
sliderDirection = 'toRight';
} else {
if (!sliderDirection) {
sliderDirection = 'toLeft';
}
}
if (!sliderRequestAnimationFrame) {
updateTranslate();
}
translateX = translate;
}
},
flick: function(event) {
if (isMoved) {
event.stopPropagation();
}
},
swipeleft: function(event) {
if (isMoved) {
event.stopPropagation();
}
},
swiperight: function(event) {
if (isMoved) {
event.stopPropagation();
}
},
dragend: function(event) {
if (!isMoved) {
return;
}
event.stopPropagation();
if (sliderRequestAnimationFrame) {
cancelAnimationFrame(sliderRequestAnimationFrame);
sliderRequestAnimationFrame = null;
}
var detail = event.detail;
isMoved = false;
var action = 'close';
var actionsWidth = sliderDirection === 'toLeft' ? sliderActionRightWidth : sliderActionLeftWidth;
var isToggle = detail.swipe || (Math.abs(translateX) > actionsWidth / 2);
if (isToggle) {
if (!isOpened) {
action = 'open';
} else if (detail.direction === 'left' && openedActions === 'right') {
action = 'open';
} else if (detail.direction === 'right' && openedActions === 'left') {
action = 'open';
}
}
cell.classList.add(CLASS_TRANSITIONING);
var buttons;
if (action === 'open') {
var newTranslate = sliderDirection === 'toLeft' ? -actionsWidth : actionsWidth;
setTranslate(sliderHandle, newTranslate);
buttons = sliderDirection === 'toLeft' ? buttonsRight : buttonsLeft;
if (typeof buttons !== 'undefined') {
var button = null;
for (var i = 0; i < buttons.length; i++) {
button = buttons[i];
setTranslate(button, newTranslate);
}
button.parentNode.classList.add(CLASS_SELECTED);
cell.classList.add(CLASS_SELECTED);
if (!isOpened) {
$.trigger(cell, sliderDirection === 'toLeft' ? 'slideleft' : 'slideright');
}
}
} else {
setTranslate(sliderHandle, 0);
sliderActionLeft && sliderActionLeft.classList.remove(CLASS_SELECTED);
sliderActionRight && sliderActionRight.classList.remove(CLASS_SELECTED);
cell.classList.remove(CLASS_SELECTED);
}
var buttonOffset;
if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) {
for (var i = 0, len = buttonsLeft.length; i < len; i++) {
var buttonLeft = buttonsLeft[i];
buttonOffset = buttonLeft._buttonOffset;
if (typeof buttonOffset === 'undefined') {
buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
}
setTranslate(buttonLeft, buttonOffset);
}
}
if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) {
for (var i = 0, len = buttonsRight.length; i < len; i++) {
var buttonRight = buttonsRight[i];
buttonOffset = buttonRight._buttonOffset;
if (typeof buttonOffset === 'undefined') {
buttonRight._buttonOffset = buttonRight.offsetLeft;
}
setTranslate(buttonRight, -buttonOffset);
}
}
}
};
function toggleEvents(element, isRemove) {
var method = !!isRemove ? 'removeEventListener' : 'addEventListener';
element[method]('drag', handleEvent);
element[method]('dragend', handleEvent);
element[method]('swiperight', handleEvent);
element[method]('swipeleft', handleEvent);
element[method]('flick', handleEvent);
};
/**
* 打开滑动菜单
* @param {Object} el
* @param {Object} direction
*/
$.swipeoutOpen = function(el, direction) {
if (!el) return;
var classList = el.classList;
if (classList.contains(CLASS_SELECTED)) return;
if (!direction) {
if (el.querySelector(SELECTOR_SLIDER_RIGHT)) {
direction = 'right';
} else {
direction = 'left';
}
}
var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
if (!swipeoutAction) return;
swipeoutAction.classList.add(CLASS_SELECTED);
classList.add(CLASS_SELECTED);
classList.remove(CLASS_TRANSITIONING);
var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
var swipeoutWidth = swipeoutAction.offsetWidth;
var translate = (direction === 'right') ? -swipeoutWidth : swipeoutWidth;
var length = buttons.length;
var button;
for (var i = 0; i < length; i++) {
button = buttons[i];
if (direction === 'right') {
setTranslate(button, -button.offsetLeft);
} else {
setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
}
}
classList.add(CLASS_TRANSITIONING);
for (var i = 0; i < length; i++) {
setTranslate(buttons[i], translate);
}
setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), translate);
};
/**
* 关闭滑动菜单
* @param {Object} el
*/
$.swipeoutClose = function(el) {
if (!el) return;
var classList = el.classList;
if (!classList.contains(CLASS_SELECTED)) return;
var direction = el.querySelector(SELECTOR_SLIDER_RIGHT + SELECTOR_SELECTED) ? 'right' : 'left';
var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
if (!swipeoutAction) return;
swipeoutAction.classList.remove(CLASS_SELECTED);
classList.remove(CLASS_SELECTED);
classList.add(CLASS_TRANSITIONING);
var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
var swipeoutWidth = swipeoutAction.offsetWidth;
var length = buttons.length;
var button;
setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), 0);
for (var i = 0; i < length; i++) {
button = buttons[i];
if (direction === 'right') {
setTranslate(button, (-button.offsetLeft));
} else {
setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
}
}
};
window.addEventListener($.EVENT_END, function(event) { //使用touchend来取消高亮避免一次点击既不触发tapdoubletaplongtap的事件
if (!cell) {
return;
}
toggleActive(false);
sliderHandle && toggleEvents(cell, true);
});
window.addEventListener($.EVENT_CANCEL, function(event) { //使用touchcancel来取消高亮避免一次点击既不触发tapdoubletaplongtap的事件
if (!cell) {
return;
}
toggleActive(false);
sliderHandle && toggleEvents(cell, true);
});
var radioOrCheckboxClick = function(event) {
var type = event.target && event.target.type || '';
if (type === 'radio' || type === 'checkbox') {
return;
}
var classList = cell.classList;
if (classList.contains($.className('radio'))) {
var input = cell.querySelector('input[type=radio]');
if (input) {
// input.click();
if (!input.disabled && !input.readOnly) {
input.checked = !input.checked;
$.trigger(input, 'change');
}
}
} else if (classList.contains($.className('checkbox'))) {
var input = cell.querySelector('input[type=checkbox]');
if (input) {
// input.click();
if (!input.disabled && !input.readOnly) {
input.checked = !input.checked;
$.trigger(input, 'change');
}
}
}
};
//fixed hashchange(android)
window.addEventListener($.EVENT_CLICK, function(e) {
if (cell && cell.classList.contains($.className('collapse'))) {
e.preventDefault();
}
});
window.addEventListener('doubletap', function(event) {
if (cell) {
radioOrCheckboxClick(event);
}
});
var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/;
window.addEventListener('tap', function(event) {
if (!cell) {
return;
}
var isExpand = false;
var classList = cell.classList;
var ul = cell.parentNode;
if (ul && ul.classList.contains(CLASS_RADIO_VIEW)) {
if (classList.contains(CLASS_SELECTED)) {
return;
}
var selected = ul.querySelector('li' + SELECTOR_SELECTED);
if (selected) {
selected.classList.remove(CLASS_SELECTED);
}
classList.add(CLASS_SELECTED);
$.trigger(cell, 'selected', {
el: cell
});
return;
}
if (classList.contains($.className('collapse')) && !cell.parentNode.classList.contains($.className('unfold'))) {
if (!preventDefaultException.test(event.target.tagName)) {
event.detail.gesture.preventDefault();
}
if (!classList.contains(CLASS_ACTIVE)) { //展开时,需要收缩其他同类
var collapse = cell.parentNode.querySelector($.classSelector('.collapse.active'));
if (collapse) {
collapse.classList.remove(CLASS_ACTIVE);
}
isExpand = true;
}
classList.toggle(CLASS_ACTIVE);
if (isExpand) {
//触发展开事件
$.trigger(cell, 'expand');
//scroll
//暂不滚动
// var offsetTop = $.offset(cell).top;
// var scrollTop = document.body.scrollTop;
// var height = window.innerHeight;
// var offsetHeight = cell.offsetHeight;
// var cellHeight = (offsetTop - scrollTop + offsetHeight);
// if (offsetHeight > height) {
// $.scrollTo(offsetTop, 300);
// } else if (cellHeight > height) {
// $.scrollTo(cellHeight - height + scrollTop, 300);
// }
}
} else {
radioOrCheckboxClick(event);
}
});
})(mui, window, document);