如果 focus 事件能被触发的话,那肯定能重新定位光标到正确的位置呀。
咱们看下面这段:
//iOS4下的 select 元素不能禁用默认事件(要确保它能被穿透),否则不会打开select目录 //有时候 iOS6/7 下(VoiceOver开启的情况下)也会如此 if (!deviceIsIOS || targetTagName !== 'select' ) { this.targetElement = null; event.preventDefault(); }
通过 preventDefault 的阻挡,textarea 自然再也无法拥抱其 focus 宝宝了~
于是乎,我们在这里做个改动就能修复这个问题:
var _isTextInput = function(){ return targetTagName === 'textarea' || (targetTagName === 'input' && targetElement.type === 'text'); }; if ((!deviceIsIOS || targetTagName !== 'select') && !_isTextInput()) { this.targetElement = null; event.preventDefault(); }
或者:
if (!deviceIsIOS4 || targetTagName !== 'select') { this.targetElement = null; //给textarea加上“needsclick”的class if((!/\bneedsclick\b/).test(targetElement.className)){ event.preventDefault(); } }
这里要吐槽下的是,Fastclick 把 this.needsClick 放到了 ontouchEnd 末尾去执行,才导致前面说的加上了“needsclick”类名也无效的问题。
虽然问题原因找到也解决了,但咱们还是继续看剩下的部分吧。
4. onMouse 和 onClick
//用于决定是否允许穿透事件(触发layer的click默认事件) FastClick.prototype.onMouse = function(event) { // touch事件一直没触发 if (!this.targetElement) { return true; } if (event.forwardedTouchEvent) { //触发的click事件是合成的 return true; } // 编程派生的事件所对应元素事件可以被允许 // 确保其没执行过 preventDefault 方法(event.cancelable 不为 true)即可 if (!event.cancelable) { return true; } // 需要做预防穿透处理的元素,或者做了快速(200ms)双击的情况 if (!this.needsClick(this.targetElement) || this.cancelNextClick) { //停止当前默认事件和冒泡 if (event.stopImmediatePropagation) { event.stopImmediatePropagation(); } else { // 不支持 stopImmediatePropagation 的设备(比如Android 2)做标记, // 确保该事件回调不会执行(见126行) event.propagationStopped = true; } // 取消事件和冒泡 event.stopPropagation(); event.preventDefault(); return false; } //允许穿透 return true; }; //click事件常规都是touch事件衍生来的,也排在touch后面触发。 //对于那些我们在touch事件过程没有禁用掉默认事件的event来说,我们还需要在click的捕获阶段进一步 //做判断决定是否要禁掉点击事件(防穿透) FastClick.prototype.onClick = function(event) { var permitted; // 如果还有 trackingClick 存在,可能是某些UI事件阻塞了touchEnd 的执行 if (this.trackingClick) { this.targetElement = null; this.trackingClick = false; return true; } // 依旧是对 iOS 怪异行为的处理 —— 如果用户点击了iOS模拟器里某个表单中的一个submit元素 // 或者点击了弹出来的键盘里的“Go”按钮,会触发一个“伪”click事件(target是一个submit-type的input元素) if (event.target.type === 'submit' && event.detail === 0) { return true; } permitted = this.onMouse(event); if (!permitted) { //如果点击是被允许的,将this.targetElement置空可以确保onMouse事件里不会阻止默认事件 this.targetElement = null; } //没有多大意义 return permitted; }; //销毁Fastclick所注册的监听事件。是给外部实例去调用的 FastClick.prototype.destroy = function() { var layer = this.layer; if (deviceIsAndroid) { layer.removeEventListener('mouseover', this.onMouse, true); layer.removeEventListener('mousedown', this.onMouse, true); layer.removeEventListener('mouseup', this.onMouse, true); } layer.removeEventListener('click', this.onClick, true); layer.removeEventListener('touchstart', this.onTouchStart, false); layer.removeEventListener('touchmove', this.onTouchMove, false); layer.removeEventListener('touchend', this.onTouchEnd, false); layer.removeEventListener('touchcancel', this.onTouchCancel, false); };
内容版权声明:除非注明,否则皆为本站原创文章。