From 8c55e280ba2d7bdf8e89b9b8f8006a2fec3d8661 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Mon, 17 Mar 2014 13:47:02 -0500 Subject: [PATCH] fix scrolling through list causes "active" class on items --- config/build.config.js | 1 + js/utils/activator.js | 69 ++++++++++++++++++++++++++++++++++++++++++ js/utils/tap.js | 23 -------------- js/views/listView.js | 38 +---------------------- 4 files changed, 71 insertions(+), 60 deletions(-) create mode 100644 js/utils/activator.js diff --git a/config/build.config.js b/config/build.config.js index 6db81e153f..263e82f336 100644 --- a/config/build.config.js +++ b/config/build.config.js @@ -37,6 +37,7 @@ module.exports = { 'js/utils/platform.js', 'js/utils/poly.js', 'js/utils/tap.js', + 'js/utils/activator.js', 'js/utils/utils.js', 'js/utils/keyboard.js', diff --git a/js/utils/activator.js b/js/utils/activator.js new file mode 100644 index 0000000000..0e4e17e43a --- /dev/null +++ b/js/utils/activator.js @@ -0,0 +1,69 @@ +(function(document, ionic) { + 'use strict'; + + var queueElements = {}; // elements that should get an active state in XX milliseconds + var activeElements = {}; // elements that are currently active + var keyId = 0; // a counter for unique keys for the above ojects + + function onStart(e) { + // when an element is touched/clicked, it climbs up a few + // parents to see if it is an .item or .button element + var x, ele = e.target; + + ionic.requestAnimationFrame(function(){ + for(x=0; x<5; x++) { + if(!ele || ele.tagName === 'LABEL') break; + if( ele.classList.contains('item') || ele.classList.contains('button') ) { + keyId = (keyId > 99 ? 0 : keyId + 1); + + // queue that this element should be set to active + queueElements[keyId] = ele; + setTimeout(activateElements, 32); + } + ele = ele.parentElement; + } + }); + } + + function activateElements() { + // activate all elements in the queue + for(var key in queueElements) { + if(queueElements[key]) { + queueElements[key].classList.add('active'); + activeElements[key] = queueElements[key]; + } + } + queueElements = {}; + } + + function onEnd(e) { + // clear out any active/queued elements after XX milliseconds + setTimeout(clear, 200); + } + + function clear() { + // clear out any active/queued elements immediately + queueElements = {}; + for(var key in activeElements) { + activeElements[key] && activeElements[key].classList.remove('active'); + delete activeElements[key]; + } + } + + // use window.onload because this doesn't need to run immediately + window.addEventListener('load', function(){ + // start an active element + document.body.addEventListener('touchstart', onStart, false); + document.body.addEventListener('mousedown', onStart, false); + + // clear all active elements after XX milliseconds + document.body.addEventListener('touchend', onEnd, false); + document.body.addEventListener('mouseup', onEnd, false); + + // clear all active immediately + document.body.addEventListener('mousemove', clear, false); + document.body.addEventListener('touchmove', clear, false); + document.body.addEventListener('touchcancel', clear, false); + }, false); + +})(document, ionic); diff --git a/js/utils/tap.js b/js/utils/tap.js index 8c2c0d2d2c..2b26d95d75 100644 --- a/js/utils/tap.js +++ b/js/utils/tap.js @@ -175,13 +175,6 @@ var tap = isRecentTap(e); if(tap) delete tapCoordinates[tap.id]; }, REMOVE_PREVENT_DELAY); - - setTimeout(function(){ - for(var hitKey in hitElements) { - hitElements[hitKey] && hitElements[hitKey].classList.remove('active'); - delete hitElements[hitKey]; - } - }, 150); } function stopEvent(e){ @@ -204,20 +197,6 @@ function recordStartCoordinates(e) { startCoordinates = getCoordinates(e); - - var x, ele = e.target; - for(x=0; x<5; x++) { - if(!ele || ele.tagName === 'LABEL') break; - if( ele.classList.contains('item') || ele.classList.contains('button') ) { - hitElements[hitCounts] = ele; - hitCounts = (hitCounts > 24 ? 0 : hitCounts + 1); - ionic.requestAnimationFrame(function(){ - ele.classList.add('active'); - }); - break; - } - ele = ele.parentElement; - } } var tapCoordinates = {}; // used to remember coordinates to ignore if they happen again quickly @@ -225,8 +204,6 @@ var CLICK_PREVENT_DURATION = 1500; // max milliseconds ghostclicks in the same area should be prevented var REMOVE_PREVENT_DELAY = 375; // delay after a touchend/mouseup before removing the ghostclick prevent var HIT_RADIUS = 15; - var hitElements = {}; - var hitCounts = 0; // set global click handler and check if the event should stop or not document.addEventListener('click', preventGhostClick, true); diff --git a/js/views/listView.js b/js/views/listView.js index c7406d926a..eec0750ffd 100644 --- a/js/views/listView.js +++ b/js/views/listView.js @@ -319,10 +319,6 @@ this.onRefreshOpening = opts.onRefreshOpening || function() {}; this.onRefreshHolding = opts.onRefreshHolding || function() {}; - window.ionic.onGesture('touch', function(e) { - _this._handleTouch(e); - }, this.el); - window.ionic.onGesture('release', function(e) { _this._handleEndDrag(e); }, this.el); @@ -466,13 +462,6 @@ return; } - // Cancel touch timeout - clearTimeout(this._touchTimeout); - var items = _this.el.querySelectorAll('.item'); - for(var i = 0, l = items.length; i < l; i++) { - items[i].classList.remove('active'); - } - this._dragOp.end(e, function() { _this._initDrag(); }); @@ -488,13 +477,6 @@ this._didDragUpOrDown = true; } - // If the user has a touch timeout to highlight an element, clear it if we - // get sufficient draggage - if(Math.abs(e.gesture.deltaX) > 10 || Math.abs(e.gesture.deltaY) > 10) { - clearTimeout(this._touchTimeout); - } - - clearTimeout(this._touchTimeout); // If we get a drag event, make sure we aren't in another drag, then check if we should // start one if(!this.isDragging && !this._dragOp) { @@ -509,25 +491,7 @@ e.gesture.srcEvent.preventDefault(); this._dragOp.drag(e); - }, - - /** - * Handle the touch event to show the active state on an item if necessary. - */ - _handleTouch: function(e) { - var _this = this; - - var item = ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_CLASS); - if(!item) { return; } - - this._touchTimeout = setTimeout(function() { - var items = _this.el.querySelectorAll('.item'); - for(var i = 0, l = items.length; i < l; i++) { - items[i].classList.remove('active'); - } - item.classList.add('active'); - }, 250); - }, + } });