问题1:bindToWrapper主要作用是什么?
解答:move事件一般都是绑定在document上面的而不是wrapper元素上,这时候当你在wrapper外移动游标/手指,这个scroller元素也会一直滚动。但是如果你可以把事件绑定在wrapper上,这时候只要指针离开了wrapper那么scroller就会停止!
_initEvents: function (remove) { var eventType = remove ? utils.removeEvent : utils.addEvent, target = this.options.bindToWrapper ? this.wrapper : window; eventType(window, 'orientationchange', this); eventType(window, 'resize', this); if ( this.options.click ) { eventType(this.wrapper, 'click', this, true); } //disableMouse= utils.hasPointer || utils.hasTouch //也就是说没有pointer事件和touch事件的时候我们就会绑定mouse事件,如mousedown等 if ( !this.options.disableMouse ) { eventType(this.wrapper, 'mousedown', this); eventType(target, 'mousemove', this); eventType(target, 'mousecancel', this); eventType(target, 'mouseup', this); } //disablePointer : !utils.hasPointer //如果有pointer事件,同时pointer事件没有被阻止,那么我们添加pointer事件 if ( utils.hasPointer && !this.options.disablePointer ) { eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); eventType(target, utils.prefixPointerEvent('pointermove'), this); eventType(target, utils.prefixPointerEvent('pointercancel'), this); eventType(target, utils.prefixPointerEvent('pointerup'), this); } //如果有touch同时touch没有被阻止那么添加touch事件 //hasTouch: 'ontouchstart' in window if ( utils.hasTouch && !this.options.disableTouch ) { eventType(this.wrapper, 'touchstart', this); eventType(target, 'touchmove', this); eventType(target, 'touchcancel', this); eventType(target, 'touchend', this); } //为scroller添加transitionend事件监听滚动是否结束 eventType(this.scroller, 'transitionend', this); eventType(this.scroller, 'webkitTransitionEnd', this); eventType(this.scroller, 'oTransitionEnd', this); eventType(this.scroller, 'MSTransitionEnd', this); }
注意:从上面的代码中可以看到,其中mousedown,pointerdown,touchstart都是绑定在wrapper上,其他都是绑定在wrapper或者window上,主要看使用者是否指定了bindToWrapper属性,如果指定了那么mousemove/mousecancel/mouseup等其他事件都是绑定在wrapper元素上,这时候当你移动到wrapperw外面的时候就不会响应事件了!
接下来我们分析一下hasTouch,disablePointer,disableTouch等内容:
判断是否有pointer事件:
hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed
我们判断是否有touch事件|:
hasTouch: 'ontouchstart' in window我们再来看看disableTouch,disablePointer等方法
disablePointer : !utils.hasPointer,//是否禁止pointer事件 disableTouch : utils.hasPointer || !utils.hasTouch,//是否禁止touch。如果有Pointer事件或者没有Touch事件可以取消Touch事件 disableMouse : utils.hasPointer || utils.hasTouch,//是否禁止Mouse。如果有指针事件或者Touch事件可以取消Mouse事件
注意:如果没有PointerEvent那么应该禁止pointer event;如果有PointerEvent那么禁止Touch,如果没有Touch也禁止Touch;如果有Pointer或者有Touch那么应该禁止Mouse事件。默认情况下,iScroll会监听所有的指针事件同时会处理第一个触发的同类事件(功能检测)。功能检测虽然看起来很浪费资源,而且很不可靠,但是监听所有的事件是最安全的方式来判断浏览器/设备兼容性。如果你有设备检测的内部机制或者你预先知道你的脚本的执行环境,那么你可以禁止掉一系列的事件(mouse,pointer,touch)事件!
总结:上面的initEvent就是根据设备类型为我们的wrapper元素绑定相应的touch/mouse/pointer事件,同时transitionEnd事件用于判断当元素滚动结束后应该执行的回调