anima-yocto-touch
Advanced tools
Comparing version 1.0.10 to 2.0.0
@@ -5,2 +5,8 @@ # History | ||
## 2.0.0 | ||
`new` tnpm 改造 | ||
`update` 升级anima-yocto-core依赖到`2.0.0` | ||
`update` 升级anima-yocto-event依赖到`2.0.1` | ||
## 1.0.10 | ||
@@ -7,0 +13,0 @@ |
@@ -1,2 +0,2 @@ | ||
var $ = Yocto = require('anima-yocto-core'); | ||
var $ = require('anima-yocto-core'); | ||
@@ -3,0 +3,0 @@ require('anima-yocto-event'); |
{ | ||
"name": "anima-yocto-touch", | ||
"version": "1.0.10", | ||
"version": "2.0.0", | ||
"description": "the touch from yocto", | ||
"keywords": [], | ||
"homepage": "", | ||
"author": "", | ||
"keywords": [ | ||
"anima", | ||
"anima-yocto", | ||
"anima-yocto-touch" | ||
], | ||
"homepage": "http://gitlab.alibaba-inc.com/animajs/yocto-touch", | ||
"author": "wanyan.wz@taobao.com", | ||
"maintainers": [ | ||
"wanyan.wz@taobao.com" | ||
], | ||
"repository": { | ||
@@ -13,27 +20,30 @@ "type": "git", | ||
"bugs": { | ||
"url": "" | ||
"url": "http://gitlab.alibaba-inc.com/animajs/yocto-touch/issues" | ||
}, | ||
"licenses": "MIT", | ||
"spm": { | ||
"engines": { | ||
"seajs": "2.2.1" | ||
}, | ||
"tests": "tests/*.js" | ||
"main": "./lib/index", | ||
"entry": { | ||
"index": "./index.js" | ||
}, | ||
"main": "index.js", | ||
"dependencies": { | ||
"anima-yocto-core": "1.1.1", | ||
"anima-yocto-event": "1.0.3" | ||
"anima-yocto-core": "2.0.0", | ||
"anima-yocto-event": "2.0.1" | ||
}, | ||
"devDependencies": { | ||
"spm-expect.js": "0.3.1", | ||
"spm-webpack": "~1.0.0" | ||
"atool-build": "0.6.x", | ||
"atool-doc": "^0.1.0", | ||
"atool-test": "^0.4.4", | ||
"dora": "0.3.x", | ||
"gh-pages": "^0.11.0" | ||
}, | ||
"scripts": { | ||
"build": "spm-webpack -c" | ||
"build": "atool-build", | ||
"test": "atool-test", | ||
"doc": "atool-doc", | ||
"doc-build": "atool-doc --build", | ||
"gh-pages": "atool-doc --build && gh-pages -d __site" | ||
}, | ||
"engines": { | ||
"node": ">=4.0.0" | ||
}, | ||
"publishConfig": {} | ||
} | ||
} | ||
} |
@@ -1,5 +0,15 @@ | ||
# anima-yocto-touch [![spm version](http://spmjs.io/badge/anima-yocto-touch)](http://spmjs.io/package/anima-yocto-touch) | ||
# anima-yocto-touch [![npm](https://img.shields.io/npm/v/anima-yocto-touch.svg?style=flat-square)](https://www.npmjs.com/package/anima-yocto-touch) [![npm](https://img.shields.io/npm/dm/anima-yocto-touch.svg?style=flat-square)](https://www.npmjs.com/package/anima-yocto-touch) | ||
--- | ||
An awesome npm package! | ||
--- | ||
## Install | ||
``` | ||
$ npm install anima-yocto-touch --save | ||
``` | ||
## Yocto-touch | ||
@@ -6,0 +16,0 @@ |
@@ -1,79 +0,66 @@ | ||
var $ = Yocto = require('anima-yocto-core'); | ||
'use strict'; | ||
var $ = require('anima-yocto-core'); | ||
require('anima-yocto-event'); | ||
Gesture = { | ||
init: function(name){ | ||
var self = this, | ||
gesture = self[name]; | ||
var Gesture = { | ||
init: function (name) { | ||
var self = this, | ||
gesture = self[name]; | ||
var bindEvent = function(element){ | ||
var $el = $(element); | ||
function move(event) { | ||
gesture.handler.touchmove(event); | ||
} | ||
if(!$el.data(name)){ //防止同一重复绑定函数 | ||
function end(event) { | ||
gesture.handler.touchend(event); | ||
document.removeEventListener("touchmove", move, false); | ||
document.removeEventListener("touchend", end, false); | ||
document.removeEventListener("touchcancel", cancel, false); | ||
} | ||
$el | ||
.data(name, 1) | ||
.forEach(function(el){ | ||
el.addEventListener("touchstart", function(event){ | ||
gesture.handler.touchstart(event); | ||
function cancel(event) { | ||
gesture.handler.touchcancel(event); | ||
document.removeEventListener("touchmove", move, false); | ||
document.removeEventListener("touchend", end, false); | ||
document.removeEventListener("touchcancel", cancel, false); | ||
} | ||
document.addEventListener("touchmove", move, false); | ||
var bindEvent = function (element) { | ||
var $el = $(element); | ||
document.addEventListener("touchend", end, false); | ||
if (!$el.data(name)) { //防止同一重复绑定函数 | ||
document.addEventListener("touchcancel", cancel, false); | ||
$el | ||
.data(name, 1) | ||
.forEach(function (el) { | ||
el.addEventListener("touchstart", function (event) { | ||
gesture.handler.touchstart(event); | ||
// event.preventDefault(); | ||
}, false); | ||
}); | ||
document.addEventListener("touchmove", move, false); | ||
function move(event){ | ||
document.addEventListener("touchend", end, false); | ||
gesture.handler.touchmove(event); | ||
document.addEventListener("touchcancel", cancel, false); | ||
// event.preventDefault(); | ||
} | ||
// event.preventDefault(); | ||
}, false); | ||
}); | ||
} | ||
}; | ||
function end(event){ | ||
gesture.events.forEach(function (eventName) { | ||
self.list[eventName] = bindEvent; | ||
gesture.handler.touchend(event); | ||
$.fn[eventName] = function (callback) { | ||
return this.on(eventName, callback); | ||
}; | ||
}); | ||
}, | ||
list: {} | ||
}; | ||
document.removeEventListener("touchmove", move, false); | ||
document.removeEventListener("touchend", end, false); | ||
document.removeEventListener("touchcancel", cancel, false); | ||
// event.preventDefault(); | ||
} | ||
function cancel(event){ | ||
gesture.handler.touchcancel(event); | ||
document.removeEventListener("touchmove", move, false); | ||
document.removeEventListener("touchend", end, false); | ||
document.removeEventListener("touchcancel", cancel, false); | ||
// event.preventDefault(); | ||
} | ||
} | ||
}; | ||
gesture.events.forEach(function(eventName){ | ||
self.list[eventName] = bindEvent; | ||
$.fn[eventName] = function(callback) { | ||
return this.on(eventName, callback); | ||
}; | ||
}); | ||
}, | ||
list: {} | ||
}; | ||
$.gestures = Gesture; | ||
module.exports = $; |
468
src/tap.js
@@ -1,3 +0,5 @@ | ||
var $ = Yocto = require('anima-yocto-core'); | ||
'use strict'; | ||
var $ = require('anima-yocto-core'); | ||
require('anima-yocto-event'); | ||
@@ -10,284 +12,284 @@ | ||
var deviceIsAndroid = navigator.userAgent.toLowerCase().indexOf('android') > 0, | ||
deviceIsIOS = /ip(ad|hone|od)/.test(navigator.userAgent.toLowerCase()); | ||
deviceIsIOS = /ip(ad|hone|od)/.test(navigator.userAgent.toLowerCase()); | ||
var yoctoTouch = { | ||
trackingClick: false, | ||
trackingClickStart: 0, | ||
targetElement: null, | ||
touchStartX: 0, | ||
touchStartY: 0, | ||
touchBoundary: 10, | ||
tapDelay: 200, | ||
sendClick: function(targetElement, event){ | ||
// 在click之前触发tap事件 | ||
var tap = $.Event('tap', {animaTap: true}) | ||
$(targetElement).trigger(tap); | ||
trackingClick: false, | ||
trackingClickStart: 0, | ||
targetElement: null, | ||
touchStartX: 0, | ||
touchStartY: 0, | ||
touchBoundary: 10, | ||
tapDelay: 200, | ||
sendClick: function (targetElement, event) { | ||
// 在click之前触发tap事件 | ||
var tap = $.Event('tap', {animaTap: true}) | ||
$(targetElement).trigger(tap); | ||
var clickEvent, touch; | ||
var clickEvent, touch; | ||
// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24) | ||
if (document.activeElement && document.activeElement !== targetElement) { | ||
document.activeElement.blur(); | ||
} | ||
// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24) | ||
if (document.activeElement && document.activeElement !== targetElement) { | ||
document.activeElement.blur(); | ||
} | ||
touch = event.changedTouches[0]; | ||
touch = event.changedTouches[0]; | ||
// Synthesise a click event, with an extra attribute so it can be tracked | ||
clickEvent = document.createEvent('MouseEvents'); | ||
clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); | ||
clickEvent.animaClick = true; | ||
targetElement.dispatchEvent(clickEvent); | ||
}, | ||
needClick: function(target){ | ||
switch (target.nodeName.toLowerCase()) { | ||
// Synthesise a click event, with an extra attribute so it can be tracked | ||
clickEvent = document.createEvent('MouseEvents'); | ||
clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); | ||
clickEvent.animaClick = true; | ||
targetElement.dispatchEvent(clickEvent); | ||
}, | ||
needClick: function (target) { | ||
switch (target.nodeName.toLowerCase()) { | ||
// Don't send a synthetic click to disabled inputs (issue #62) | ||
case 'button': | ||
case 'select': | ||
case 'textarea': | ||
if (target.disabled) { | ||
return true; | ||
} | ||
// Don't send a synthetic click to disabled inputs (issue #62) | ||
case 'button': | ||
case 'select': | ||
case 'textarea': | ||
if (target.disabled) { | ||
return true; | ||
} | ||
break; | ||
case 'input': | ||
break; | ||
case 'input': | ||
// File inputs need real clicks on iOS 6 due to a browser bug (issue #68) | ||
if ((deviceIsIOS && target.type === 'file') || target.disabled) { | ||
return true; | ||
} | ||
break; | ||
case 'label': | ||
case 'iframe': | ||
case 'video': | ||
return true; | ||
// File inputs need real clicks on iOS 6 due to a browser bug (issue #68) | ||
if ((deviceIsIOS && target.type === 'file') || target.disabled) { | ||
return true; | ||
} | ||
return false; | ||
}, | ||
focus: function(targetElement){ | ||
var length; | ||
break; | ||
case 'label': | ||
case 'iframe': | ||
case 'video': | ||
return true; | ||
} | ||
// on iOS 7, some input elements (e.g. date datetime) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724. | ||
if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time') { | ||
length = targetElement.value.length; | ||
targetElement.setSelectionRange(length, length); | ||
} else { | ||
targetElement.focus(); | ||
return false; | ||
}, | ||
focus: function (targetElement) { | ||
var length; | ||
// on iOS 7, some input elements (e.g. date datetime) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724. | ||
if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time') { | ||
length = targetElement.value.length; | ||
targetElement.setSelectionRange(length, length); | ||
} else { | ||
targetElement.focus(); | ||
} | ||
}, | ||
needFocus: function (target) { | ||
switch (target.nodeName.toLowerCase()) { | ||
case 'textarea': | ||
case 'select': //实测android下select也需要 | ||
return true; | ||
case 'input': | ||
switch (target.type) { | ||
case 'button': | ||
case 'checkbox': | ||
case 'file': | ||
case 'image': | ||
case 'radio': | ||
case 'submit': | ||
return false; | ||
} | ||
}, | ||
needFocus: function(target){ | ||
switch (target.nodeName.toLowerCase()) { | ||
case 'textarea': | ||
case 'select': //实测android下select也需要 | ||
return true; | ||
case 'input': | ||
switch (target.type) { | ||
case 'button': | ||
case 'checkbox': | ||
case 'file': | ||
case 'image': | ||
case 'radio': | ||
case 'submit': | ||
return false; | ||
} | ||
// No point in attempting to focus disabled inputs | ||
return !target.disabled && !target.readOnly; | ||
default: | ||
return false; | ||
} | ||
}, | ||
updateScrollParent: function(targetElement){ | ||
var scrollParent, parentElement; | ||
// No point in attempting to focus disabled inputs | ||
return !target.disabled && !target.readOnly; | ||
default: | ||
return false; | ||
} | ||
}, | ||
updateScrollParent: function (targetElement) { | ||
var scrollParent, parentElement; | ||
scrollParent = targetElement.yoctoTouchScrollParent; | ||
scrollParent = targetElement.yoctoTouchScrollParent; | ||
// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the | ||
// target element was moved to another parent. | ||
if (!scrollParent || !scrollParent.contains(targetElement)) { | ||
parentElement = targetElement; | ||
do { | ||
if (parentElement.scrollHeight > parentElement.offsetHeight) { | ||
scrollParent = parentElement; | ||
targetElement.yoctoTouchScrollParent = parentElement; | ||
break; | ||
} | ||
parentElement = parentElement.parentElement; | ||
} while (parentElement); | ||
// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the | ||
// target element was moved to another parent. | ||
if (!scrollParent || !scrollParent.contains(targetElement)) { | ||
parentElement = targetElement; | ||
do { | ||
if (parentElement.scrollHeight > parentElement.offsetHeight) { | ||
scrollParent = parentElement; | ||
targetElement.yoctoTouchScrollParent = parentElement; | ||
break; | ||
} | ||
// Always update the scroll top tracker if possible. | ||
if (scrollParent) { | ||
scrollParent.yoctoTouchLastScrollTop = scrollParent.scrollTop; | ||
} | ||
}, | ||
findControl: function(labelElement){ | ||
// Fast path for newer browsers supporting the HTML5 control attribute | ||
if (labelElement.control !== undefined) { | ||
return labelElement.control; | ||
} | ||
parentElement = parentElement.parentElement; | ||
} while (parentElement); | ||
} | ||
// All browsers under test that support touch events also support the HTML5 htmlFor attribute | ||
if (labelElement.htmlFor) { | ||
return document.getElementById(labelElement.htmlFor); | ||
} | ||
// Always update the scroll top tracker if possible. | ||
if (scrollParent) { | ||
scrollParent.yoctoTouchLastScrollTop = scrollParent.scrollTop; | ||
} | ||
}, | ||
findControl: function (labelElement) { | ||
// Fast path for newer browsers supporting the HTML5 control attribute | ||
if (labelElement.control !== undefined) { | ||
return labelElement.control; | ||
} | ||
// If no for attribute exists, attempt to retrieve the first labellable descendant element | ||
// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label | ||
return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea'); | ||
}, | ||
touchHasMoved: function(event){ | ||
var touch = event.changedTouches[0], boundary = yoctoTouch.touchBoundary; | ||
// All browsers under test that support touch events also support the HTML5 htmlFor attribute | ||
if (labelElement.htmlFor) { | ||
return document.getElementById(labelElement.htmlFor); | ||
} | ||
if (Math.abs(touch.pageX - yoctoTouch.touchStartX) > boundary || Math.abs(touch.pageY - yoctoTouch.touchStartY) > boundary) { | ||
return true; | ||
} | ||
// If no for attribute exists, attempt to retrieve the first labellable descendant element | ||
// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label | ||
return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea'); | ||
}, | ||
touchHasMoved: function (event) { | ||
var touch = event.changedTouches[0], boundary = yoctoTouch.touchBoundary; | ||
return false; | ||
}, | ||
fixTarget: function(target){ | ||
if (window.SVGElementInstance && (target instanceof SVGElementInstance)){ | ||
target = target.correspondingUseElement; | ||
} | ||
if (Math.abs(touch.pageX - yoctoTouch.touchStartX) > boundary || Math.abs(touch.pageY - yoctoTouch.touchStartY) > boundary) { | ||
return true; | ||
} | ||
return target; | ||
return false; | ||
}, | ||
fixTarget: function (target) { | ||
if (window.SVGElementInstance && (target instanceof SVGElementInstance)) { | ||
target = target.correspondingUseElement; | ||
} | ||
return target; | ||
} | ||
}; | ||
Gesture.tap = { | ||
events: ['tap', 'click'], | ||
handler: { | ||
touchstart: function(event){ | ||
var targetElement, touch, selection; | ||
events: ['tap', 'click'], | ||
handler: { | ||
touchstart: function (event) { | ||
var targetElement, touch, selection; | ||
// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the yoctoTouch element (issue #111). | ||
if (event.targetTouches.length > 1) { | ||
return true; | ||
} | ||
// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the yoctoTouch element (issue #111). | ||
if (event.targetTouches.length > 1) { | ||
return true; | ||
} | ||
targetElement = yoctoTouch.fixTarget(event.target); | ||
touch = event.targetTouches[0]; | ||
targetElement = yoctoTouch.fixTarget(event.target); | ||
touch = event.targetTouches[0]; | ||
if (deviceIsIOS) { | ||
if (deviceIsIOS) { | ||
// Only trusted events will deselect text on iOS (issue #49) | ||
selection = window.getSelection(); | ||
if (selection.rangeCount && !selection.isCollapsed) { | ||
return true; | ||
} | ||
// Only trusted events will deselect text on iOS (issue #49) | ||
selection = window.getSelection(); | ||
if (selection.rangeCount && !selection.isCollapsed) { | ||
return true; | ||
} | ||
yoctoTouch.updateScrollParent(targetElement); | ||
} | ||
yoctoTouch.updateScrollParent(targetElement); | ||
} | ||
yoctoTouch.trackingClick = true; | ||
yoctoTouch.trackingClickStart = event.timeStamp; | ||
yoctoTouch.targetElement = targetElement; | ||
yoctoTouch.trackingClick = true; | ||
yoctoTouch.trackingClickStart = event.timeStamp; | ||
yoctoTouch.targetElement = targetElement; | ||
// var now = Date.now(), | ||
// delta = now - (yoctoTouch.last || now); | ||
// var now = Date.now(), | ||
// delta = now - (yoctoTouch.last || now); | ||
// if(delta > 0 && delta <= 250){ | ||
// yoctoTouch.isDouleTap = true; | ||
// } | ||
// if(delta > 0 && delta <= 250){ | ||
// yoctoTouch.isDouleTap = true; | ||
// } | ||
// yoctoTouch.last = now; | ||
// yoctoTouch.last = now; | ||
yoctoTouch.touchStartX = touch.pageX; | ||
yoctoTouch.touchStartY = touch.pageY; | ||
yoctoTouch.touchStartX = touch.pageX; | ||
yoctoTouch.touchStartY = touch.pageY; | ||
// Prevent phantom clicks on fast double-tap (issue #36) | ||
if ((event.timeStamp - yoctoTouch.lastClickTime) < yoctoTouch.tapDelay) { | ||
event.preventDefault(); | ||
} | ||
// Prevent phantom clicks on fast double-tap (issue #36) | ||
if ((event.timeStamp - yoctoTouch.lastClickTime) < yoctoTouch.tapDelay) { | ||
event.preventDefault(); | ||
} | ||
return true; | ||
}, | ||
touchmove: function(event){ | ||
if (!yoctoTouch.trackingClick) { | ||
return true; | ||
} | ||
return true; | ||
}, | ||
touchmove: function (event) { | ||
if (!yoctoTouch.trackingClick) { | ||
return true; | ||
} | ||
// If the touch has moved, cancel the click tracking | ||
if (yoctoTouch.targetElement !== yoctoTouch.fixTarget(event.target) || yoctoTouch.touchHasMoved(event)) { | ||
yoctoTouch.trackingClick = false; | ||
yoctoTouch.targetElement = null; | ||
} | ||
// If the touch has moved, cancel the click tracking | ||
if (yoctoTouch.targetElement !== yoctoTouch.fixTarget(event.target) || yoctoTouch.touchHasMoved(event)) { | ||
yoctoTouch.trackingClick = false; | ||
yoctoTouch.targetElement = null; | ||
} | ||
return true; | ||
}, | ||
touchend: function(event){ | ||
var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = yoctoTouch.targetElement; | ||
return true; | ||
}, | ||
touchend: function (event) { | ||
var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = yoctoTouch.targetElement; | ||
if (!yoctoTouch.trackingClick) { | ||
return true; | ||
} | ||
if (!yoctoTouch.trackingClick) { | ||
return true; | ||
} | ||
// Prevent phantom clicks on fast double-tap (issue #36) | ||
if ((event.timeStamp - yoctoTouch.lastClickTime) < yoctoTouch.tapDelay) { | ||
yoctoTouch.cancelNextClick = true; | ||
return true; | ||
} | ||
// Prevent phantom clicks on fast double-tap (issue #36) | ||
if ((event.timeStamp - yoctoTouch.lastClickTime) < yoctoTouch.tapDelay) { | ||
yoctoTouch.cancelNextClick = true; | ||
return true; | ||
} | ||
// Reset to prevent wrong click cancel on input (issue #156). | ||
yoctoTouch.cancelNextClick = false; | ||
// Reset to prevent wrong click cancel on input (issue #156). | ||
yoctoTouch.cancelNextClick = false; | ||
yoctoTouch.lastClickTime = event.timeStamp; | ||
yoctoTouch.lastClickTime = event.timeStamp; | ||
trackingClickStart = yoctoTouch.trackingClickStart; | ||
yoctoTouch.trackingClick = false; | ||
yoctoTouch.trackingClickStart = 0; | ||
trackingClickStart = yoctoTouch.trackingClickStart; | ||
yoctoTouch.trackingClick = false; | ||
yoctoTouch.trackingClickStart = 0; | ||
targetTagName = targetElement.tagName.toLowerCase(); | ||
if (targetTagName === 'label') { | ||
forElement = yoctoTouch.findControl(targetElement); | ||
if (forElement) { | ||
yoctoTouch.focus(targetElement); | ||
if (deviceIsAndroid) { | ||
return false; | ||
} | ||
targetTagName = targetElement.tagName.toLowerCase(); | ||
if (targetTagName === 'label') { | ||
forElement = yoctoTouch.findControl(targetElement); | ||
if (forElement) { | ||
yoctoTouch.focus(targetElement); | ||
if (deviceIsAndroid) { | ||
return false; | ||
} | ||
targetElement = forElement; | ||
} | ||
} else if (yoctoTouch.needFocus(targetElement)) { | ||
targetElement = forElement; | ||
} | ||
} else if (yoctoTouch.needFocus(targetElement)) { | ||
// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through. | ||
// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37). | ||
if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) { | ||
yoctoTouch.targetElement = null; | ||
return false; | ||
} | ||
// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through. | ||
// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37). | ||
if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) { | ||
yoctoTouch.targetElement = null; | ||
return false; | ||
} | ||
yoctoTouch.focus(targetElement); | ||
deviceIsAndroid && yoctoTouch.sendClick(targetElement, event); | ||
yoctoTouch.focus(targetElement); | ||
deviceIsAndroid && yoctoTouch.sendClick(targetElement, event); | ||
return false; | ||
} | ||
return false; | ||
} | ||
if (deviceIsIOS) { | ||
if (deviceIsIOS) { | ||
// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled | ||
// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42). | ||
scrollParent = targetElement.yoctoTouchScrollParent; | ||
if (scrollParent && scrollParent.yoctoTouchLastScrollTop !== scrollParent.scrollTop) { | ||
return true; | ||
} | ||
} | ||
// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled | ||
// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42). | ||
scrollParent = targetElement.yoctoTouchScrollParent; | ||
if (scrollParent && scrollParent.yoctoTouchLastScrollTop !== scrollParent.scrollTop) { | ||
return true; | ||
} | ||
} | ||
// Prevent the actual click from going though - unless the target node is marked as requiring | ||
// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted. | ||
if (!yoctoTouch.needClick(targetElement)) { | ||
event.preventDefault(); | ||
yoctoTouch.sendClick(targetElement, event); | ||
} | ||
// Prevent the actual click from going though - unless the target node is marked as requiring | ||
// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted. | ||
if (!yoctoTouch.needClick(targetElement)) { | ||
event.preventDefault(); | ||
yoctoTouch.sendClick(targetElement, event); | ||
} | ||
return false; | ||
}, | ||
touchcancel: function(event){ | ||
yoctoTouch.trackingClick = false; | ||
yoctoTouch.targetElement = null; | ||
} | ||
return false; | ||
}, | ||
touchcancel: function (event) { | ||
yoctoTouch.trackingClick = false; | ||
yoctoTouch.targetElement = null; | ||
} | ||
} | ||
}; | ||
@@ -300,12 +302,12 @@ | ||
Event.prototype.initEvent = function(){ | ||
var args = Array.prototype.slice.call(arguments); | ||
Event.prototype.initEvent = function () { | ||
var args = Array.prototype.slice.call(arguments); | ||
oldInitEvent.apply(this, args) | ||
oldInitEvent.apply(this, args) | ||
if(args[0] === 'click'){ | ||
this.animaClick = true | ||
} | ||
if (args[0] === 'click') { | ||
this.animaClick = true | ||
} | ||
} | ||
module.exports = $; |
@@ -1,2 +0,1 @@ | ||
var expect = require('spm-expect.js'); | ||
var $ = require('anima-yocto-core'); | ||
@@ -6,60 +5,68 @@ | ||
require('../index') | ||
require('../index'); | ||
$( | ||
'<p>点透测试</p>'+ | ||
'<div style="position: relative;">'+ | ||
'<div id="J_top" style="width:50px; height:50px; background-color: red; position: absolute; z-index: 1;"></div>'+ | ||
'<div id="J_bottom" style="width:100px; height:100px; background-color: blue; position: absolute;"></div>'+ | ||
'</div>'+ | ||
'<br>'+ | ||
'<br>'+ | ||
'<br>'+ | ||
'<br>' | ||
).appendTo('body'); | ||
describe('anima-yocto-touch', function () { | ||
var i = 0; | ||
it('normal usage', function () { | ||
it('normal usage', function () { | ||
expect($.isFunction($)).to.equal(true); | ||
expect($.isPlainObject($.zepto)).to.equal(true); | ||
}); | ||
$('#J_top').on('tap', function(){ | ||
$(this).hide(); | ||
}) | ||
before(function () { | ||
var html = '<ul class="UITestContainer">' + | ||
'<li>' + | ||
'<ul class="UITest">' + | ||
'<li class="UITest"><a href="">测试</a></li>' + | ||
'<li><a href="">测试</a></li>' + | ||
'</ul>' + | ||
'</li>' + | ||
'</ul>'; | ||
$(html).appendTo('body'); | ||
}); | ||
$('#J_bottom').on('tap', function(){ | ||
$(this).html(i++); | ||
}) | ||
it('closest usage', function () { | ||
expect($('li.UITest').closest('.UITest')[0]).to.equal($('li.UITest')[0]); | ||
expect($('li.UITest').closest('li')[0]).to.equal($('li.UITest')[0]); | ||
expect($('li.UITest').closest('ul')[0]).to.equal($('ul.UITest')[0]); | ||
expect($('ul.UITestContainer li li').closest('ul')[0]).to.equal($('ul.UITest')[0]); | ||
}); | ||
$( | ||
'<p>A标签测试</p>'+ | ||
'<div style="position: relative;">'+ | ||
'<p><a href="http://www.taobao.com">未监听click或tap事件</a></p>'+ | ||
'<p><a id="J_href_first" href="http://www.taobao.com">监听了tap事件</a></p>'+ | ||
'<p><a id="J_href_second" href="http://www.taobao.com">监听了click且preventDefault</a></p>'+ | ||
'<p><a id="J_href_third" href="http://www.taobao.com">监听了click未preventDefault</a></p>'+ | ||
'</div>'+ | ||
'<br>'+ | ||
'<br>'+ | ||
'<br>'+ | ||
'<br>' | ||
).appendTo('body'); | ||
after(function () { | ||
$('.UITestContainer').remove(); | ||
}); | ||
$('#J_href_first').on('tap', function(event){ | ||
alert('Tap: 模拟事件没有preventDefault'); | ||
}) | ||
it('$(htmlString) usage', function () { | ||
expect($('<h1 class="helloworld">helloworld</h1>').html()).to.equal('helloworld'); | ||
expect($('<h1 class="helloworld">helloworld</h1>').appendTo('body')[0]).to.equal($('.helloworld')[0]); | ||
$('.helloworld').remove(); | ||
}); | ||
$('#J_href_second').on('click', function(event){ | ||
alert('Click: 执行了preventDefault'); | ||
event.preventDefault(); | ||
}) | ||
before(function () { | ||
var html = '<div class="UITestOffset" style="width:100px;height:100px;position:absolute;left:50px;top:50px;">测试</div>'; | ||
$(html).appendTo('body'); | ||
}); | ||
it('offset useage', function () { | ||
expect($('.UITestOffset').offset().left).to.equal(50); | ||
expect($('.UITestOffset').offset().top).to.equal(50); | ||
expect($('.UITestOffset').offset().width).to.equal(100); | ||
expect($('.UITestOffset').offset().height).to.equal(100); | ||
}); | ||
$('#J_href_third').on('click', function(event){ | ||
alert('Click: 期望正常跳转'); | ||
}) | ||
after(function () { | ||
$('.UITestOffset').remove(); | ||
}); | ||
describe('anima-yocto-touch', function() { | ||
it('normal usage', function() { | ||
it('isArray useage', function () { | ||
expect($.isArray([])).to.equal(true); | ||
expect($.isArray([1, 2, '3'])).to.equal(true); | ||
expect($.isArray({'a': 1})).to.equal(false); | ||
expect($.isArray(function () { | ||
})).to.equal(false); | ||
expect($.isArray('foo')).to.equal(false); | ||
expect($.isArray(true)).to.equal(false); | ||
}); | ||
}); | ||
}); | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
19737
10
376
2
32
5
+ Addedanima-yocto-core@2.0.0(transitive)
+ Addedanima-yocto-event@2.0.1(transitive)
- Removedanima-yocto-core@1.1.1(transitive)
- Removedanima-yocto-event@1.0.3(transitive)
Updatedanima-yocto-core@2.0.0
Updatedanima-yocto-event@2.0.1