Jquery学习笔记(3):iScroll问题总结

18 篇文章 0 订阅

   一、iScroll框架在部分手机和pad上无法滑动或点击的解决方案

1、问题描述

    上述手机出现无法滑动或者无法触发点击事件的情况


2、问题分析

    1onBeforeScrollStart方法

       onBeforeScrollStart: function (e) { e.preventDefault(); }

       此方法是在_start里进行了调用,目的是为了阻止浏览器默认动作的执行,防止在

          滑动的过程中进行干扰,同时也就阻止了滑动区域里元素的事件的触发,这种处

          理方式也直接导致了必须要在_end方法中再次触发元素的点击事件

    2、_end方法

       if (target.tagName != 'SELECT' && target.tagName != 'INPUT' 

             && target.tagName != 'TEXTAREA') {

           ev = document.createEvent('MouseEvents');

           ev.initMouseEvent('click', true, true, 

                             e.view, 1,point.screenX, 

                             point.screenY, point.clientX,

                             point.clientY,e.ctrlKey, 

                             e.altKey, e.shiftKey,

                             e.metaKey,0, null);

            ev._fake = true;

            target.dispatchEvent(ev);

        }

        这个处理方式就是顺承了上面所提到的阻止了浏览器默认行为后,对滑动区域

            除SELECTINPUTTEXTAREA的元素触发click事件,已完成对click绑定事件的调用

    【具体分析】

         由于onBeforeScrollStart是在_start方法中进行的调用,e.preventDefault();阻止了元

         素的默认行为,从而导致了元素绑定事件的失效,必须在_end操作结束后进行

             绑定事件的模拟调用,原始的iScroll源代码中在_end中最后创建了click事件的

             模拟,但是这里必须要清楚的一个原理就是,click其实是要依赖于其他事件的:

         1)   普通pc网页中,click需要依赖于mousedownmouseup相继触发

         2)   移动webkit中,click则需要依赖于touchstarttouchend

            (实际mousedown,mouseup在移动webkit上也存在)相继触发

  “相继触发”的意思就是中间不会夹杂有其他的事件类型,这也就很容易理解

     iScroll_end中对模拟事件调用的条件了,必须要判断that.moved才能直接触

    发模拟事件。iScroll中与_start_move_end相关的三个事件类型是按照如

   下的规则来设置的:

        START_EV = hasTouch ? 'touchstart' : 'mousedown'

        MOVE_EV = hasTouch ? 'touchmove' : 'mousemove'

        END_EV = hasTouch ? 'touchend' : 'mouseup'   

    【注意事项】

          经测试,三星部分手机里默认浏览器里会默认所有元素都有一个默认的click

          事件测试结果显示鼠标事件中默认事件包含mouseup,mousedown,click,

                    dblclick在移动webkit上不支持,为系统放大功能),e.preventDefault时会阻止

          掉默认click事件的执行,必须要人为的在_end结束之后模拟click事件的调用,

               而其他正常手机即使调用了e.preventDefault也不会阻止click事件的触发,因为

               这些手机的默认浏览器上的元素的click事件的cancelable属性不为true,不可

               以被preventDefault取消掉,会正常执行,而如果在_end中模拟了click事件则

               将会导致click的重复调用(在toggle状态的事件上非常明显),因此折中

               的方式参见下面的解决方案。


3、解决方案

       1. 去除onBeforeScrollStart里的阻止默认行为

      onBeforeScrollStart: function (e) { //e.preventDefault(); }

       2. onBeforeScrollMove设置为

           function (e) {e.preventDefault();}

         以保证手机上的正常滑动免受浏览器默认行为影响(如下滑时会有窗口的scroll事件),

         当然如果这里不添加的话也可以在documentEND_EV中阻止浏览器默认行为

      3.  _end 中将模拟事件名更改为END_EV或者直接去掉模拟事件的功能(注释掉如下部分):

//					that.doubleTapTimer = setTimeout(function () {
//						that.doubleTapTimer = null;
//
//						// Find the last touched element
//						target = point.target;
//						while (target.nodeType != 1) target = target.parentNode;
//
//						if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {
//							ev = doc.createEvent('MouseEvents');
//							ev.initMouseEvent('click', true, true, e.view, 1,
//								point.screenX, point.screenY, point.clientX, point.clientY,
//								e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
//								0, null);
//							ev._fake = true;
//							target.dispatchEvent(ev);
//						}
//					}, that.options.zoom ? 250 : 0);

二、 鼠标滚轮滚动太慢


iscroll支持在pc端浏览器中使用鼠标滚轮控制区域滚动,但操作起来很不灵敏。这是由于iscroll对鼠标滚轮事件做了拦截,然后缩小了滚轮的滚动距离,详见iscroll4.js源代码608-609行:

wheelDeltaX = e.wheelDeltaX / 12;//控制X轴鼠标滚轮速度
wheelDeltaY = e.wheelDeltaY / 12;//控制Y轴鼠标滚轮速度
    iscroll将每次的滚轮距离缩小为系统默认距离的12分之一,难怪滚起来很慢,感觉不灵敏。只需要将12改成1,滚轮的滚动速度就恢复正常了。你也可以根据实际需要设置成其他值。

    iscroll5 1046行

  if ( 'deltaX' in e ) {
   wheelDeltaX = -e.deltaX*20;
   wheelDeltaY = -e.deltaY*20;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值