浅谈FastClick 填坑及源码解析(5)
这段比较长,我们主要看这段:
} else if (this.needsFocus(targetElement)) { //非label则识别是否需要focus的元素
//手势停留在组件元素时长超过100ms,则置空this.targetElement并返回
//(而不是通过调用this.focus来触发其聚焦事件,走的原生的click/focus事件触发流程)
//这也是为何文章开头提到的问题中,稍微久按一点(超过100ms)textarea是可以把光标定位在正确的地方的原因
//另外iOS下有个意料之外的bug——如果被点击的元素所在文档是在iframe中的,手动调用其focus的话,
//会发现你往其中输入的text是看不到的(即使value做了更新),so这里也直接返回
if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {
this.targetElement = null;
return false;
}
this.focus(targetElement);
this.sendClick(targetElement, event); //立即触发其click事件,而无须等待300ms
//iOS4下的 select 元素不能禁用默认事件(要确保它能被穿透),否则不会打开select目录
//有时候 iOS6/7 下(VoiceOver开启的情况下)也会如此
if (!deviceIsIOS || targetTagName !== 'select') {
this.targetElement = null;
event.preventDefault();
}
return false;
}
其中 this.needsFocus 用于判断给定元素是否需要通过合成click事件来模拟聚焦:
//判断给定元素是否需要通过合成click事件来模拟聚焦
FastClick.prototype.needsFocus = function(target) {
switch (target.nodeName.toLowerCase()) {
case 'textarea':
return true;
case 'select':
return !deviceIsAndroid; //iOS下的select得走穿透点击才行
case 'input':
switch (target.type) {
case 'button':
case 'checkbox':
case 'file':
case 'image':
case 'radio':
case 'submit':
return false;
}
return !target.disabled && !target.readOnly;
default:
//带有名为“bneedsfocus”的class则返回true
return (/\bneedsfocus\b/).test(target.className);
}
};
另外这段说明了为何稍微久按一点(超过100ms)textarea ,我们是可以把光标定位在正确的地方(会绕过后面调用 this.focus 的方法):
//手势停留在组件元素时长超过100ms,则置空this.targetElement并返回
//(而不是通过调用this.focus来触发其聚焦事件,走的原生的click/focus事件触发流程)
//这也是为何文章开头提到的问题中,稍微久按一点(超过100ms)textarea是可以把光标定位在正确的地方的原因
//另外iOS下有个意料之外的bug——如果被点击的元素所在文档是在iframe中的,手动调用其focus的话,
//会发现你往其中输入的text是看不到的(即使value做了更新),so这里也直接返回
if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {
this.targetElement = null;
return false;
}
内容版权声明:除非注明,否则皆为本站原创文章。
