123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- /**
- * 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来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
- if (!cell) {
- return;
- }
- toggleActive(false);
- sliderHandle && toggleEvents(cell, true);
- });
- window.addEventListener($.EVENT_CANCEL, function(event) { //使用touchcancel来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
- 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);
|