zoukankan      html  css  js  c++  java
  • js 事件对象 鼠标滚轮效果演示说明

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
    <html> 
    <head> 
    <title>Mouse Wheel Data</title> 
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 
    <style> 
    .slider 
    { 
    50px; 
    height:180px; 
    background:#eee; 
    padding:10px 0; 
    cursor:n-resize; 
    } 
    .slider-slot 
    { 
    16px; 
    margin:0 auto; 
    height:180px; 
    background:#eee; 
    border:1px solid gray; 
    border-color:#999 white white #999; 
    position:relative; 
    } 
    .slider-trigger 
    { 
    14px; 
    height:18px; 
    font:1px/0 arial; 
    border:1px solid gray; 
    border-color:white #999 #999 white; 
    background:#ccc; 
    position:absolute; 
    } 
    .slider-trigger b 
    { 
    display:block; 
    margin:1px 3px; 
    border-top:1px solid #999; 
    border-bottom:1px solid white; 
    } 
    </style> 
    </head> 
    <body> 
    <h2>文本框增加/减少值</h2> 
    <div><input type="text" id="txt" value="1440" /><span id="warn">文本框获得焦点后滚动鼠标滚轮</span></div> 
    <h2>鼠标滚动缩放图片</h2> 
    <div><img src="/uploads/allimg/2010/20100707/20100707233307495.jpg" id="img" width="300" style="cursor:-moz-zoom-in" title="鼠标滚动 缩放大小" / alt="" /></div> 
    <h2>鼠标滚动控制滑块移动</h2> 
    <div class="slider" id="slider"> 
    <div class="slider-slot"> 
    <div class="slider-trigger" id="sliderTrigger"> 
    <strong></strong> 
    <strong></strong> 
    <strong></strong> 
    <strong></strong> 
    <strong></strong> 
    </div> 
    </div> 
    </div> 
    </body> 
    <script> 
    var $ = function(i) 
    { 
    return document.getElementById( i ); 
    } 
    //取得滚动值 
    function getWheelValue( e ) 
    { 
    e = e||event; 
    return ( e.wheelDelta ? e.wheelDelta/120 : -( e.detail%3 == 0 ? e.detail/3 : e.detail ) ) ; 
    } 
    function stopEvent(e) 
    { 
    e = e||event; 
    if( e.preventDefault )e.preventDefault(); 
    e.returnValue = false; 
    } 
    //绑定事件,这里对mousewheel做了判断,注册时统一使用mousewheel 
    function addEvent( obj,type,fn ) 
    { 
    var isFirefox = typeof document.body.style.MozUserSelect != 'undefined'; 
    if( obj.addEventListener ) 
    obj.addEventListener( isFirefox ? 'DOMMouseScroll' : type,fn,false ); 
    else 
    obj.attachEvent( 'on'+type,fn ); 
    return fn; 
    } 
    //移除事件,这里对mousewheel做了兼容,移除时统一使用mousewheel 
    function delEvent( obj,type,fn ) 
    { 
    var isFirefox = typeof document.body.style.MozUserSelect != 'undefined'; 
    if( obj.removeEventListener ) 
    obj.removeEventListener( isFirefox ? 'DOMMouseScroll' : type,fn,false ); 
    else 
    obj.detachEvent( 'on'+type,fn ); 
    } 
    /*限制范围函数, 
    参数是三个数字,如果num 大于 max, 则返回max, 如果小于min,则返回min,如果在max和min之间,则返回num 
    */ 
    function range( num, max,min ) 
    { 
    return Math.min( max, Math.max( num,min ) ); 
    } 
    /* ------------ */ 
    /* <h2>文本框增加/减少值</h2> */ 
    $( 'txt' ).onfocus = function() 
    { 
    //保存txt自己的引用 
    var me = this, 
    //onfocus之后注册滚轮事件 
    handler = addEvent( me,'mousewheel',function(e) 
    { 
    stopEvent( e ); 
    var delta = getWheelValue(e); 
    /* 
    +me.value 将me.value转换成数字, 
    然后使用isNaN检查转换后的数字是否为NaN 
    如果是,重新赋值me.value=0; 
    */ 
    if( isNaN( +me.value ) ) me.value = 0; 
    //递增(或递减) 
    me.value = +me.value + delta; 
    //选中me里的文字 
    me.select(); 
    }); 
    //失去焦点时,把mousewheel事件移除,重置window.onblur和handler引用为null 
    this.onblur = function() 
    { 
    //移除掉mousewheel事件 
    delEvent( me,'mousewheel',handler ); 
    window.onblur = handler = null; 
    } 
    //为了防止浏览器失焦后,文本框重复触发focus,在onblur时,让文本框同时失焦 
    window.onblur = function() 
    { 
    me.blur(); 
    //把自己清理掉 
    this.onblur = null; 
    } 
    } 
    /* <h2>鼠标滚动缩放图片</h2> */ 
    addEvent( $('img'),'mousewheel',function(e) 
    { 
    stopEvent( e ); 
    var delta = getWheelValue(e); 
    //每次递增(或递减)10px,使用了范围限制,保证图片不会过大过小 
    var img = $('img'); //没有修复ie的this指向,所以这里只好重新获取img 
    img.style.width = range( img.offsetWidth + ( delta * 10 ),550,100) + 'px'; 
    return false; 
    }); 
    /* <h2>鼠标滚动控制滑块移动</h2> */ 
    addEvent( $('slider'), 'mousewheel',function(e) 
    { 
    stopEvent( e ); 
    var delta = getWheelValue(e), 
    tar = $('sliderTrigger'); 
    //杯具的反转,因为tar.offsetTop 越大,滑块就越往下,所以delta又需要反转回来,向上是负的,向下是正的,所以乘以-1 
    tar.style.top = range( tar.offsetTop + ( -1 * delta * 10 ),160,0 ) + 'px'; 
    }); 
    </script></html> 
    

     先来看看各个浏览器的兼容情况

    IE 6,7,8
    注册事件使用 onmousewheel
    取得滚动的值使用 event.wheelDelta
    滚动步长 120
    向下是负值,向上是正值
    当鼠标在一个同一个坐标,并且滚轮不间断滚动时,wheelDelta会按步长递增
    (比如 -240 -360 )


    Firefox 3.5
    注册事件有两个MozMousePixelScroll,DOMMouseScroll,但是它们不能使用element.onDOMMouseScroll方式注册,必须使用addEventLinstener来监听事件
    Firefox没有event.wheelDelta,它使用event.detail 来获取滚动的信息(Firefox这点做的很奇怪)
    event.detail 本身是用来记录一个事件在原地(鼠标坐标不发生变化的情况下)执行了多少次的信息
    而在DOMMouseScroll事件发生的时候,它的值通常是 3 和 -3
    但是它的取值和IE正好相反, 向上是负,向下是正( 这个问题在代码中需要做统一 )
    为什么说它的值通常是 3和-3呢,因为当你按住ctrl ,alt, shift 之后,再滑动鼠标滚轮,detail 的值就会成为 1和-1
    而按住别的键,则正值有时还会变成6
    总之在我看来是有点乱糟糟,


    MozMousePixelScroll 据Mozilla说,是几乎跟DOMMouseScroll一样的事件,只不过更精确(到像素)
    但是这个事件的detail值返回的非常奇怪,默认是51和-51,按住ctrl ,alt, shift 变成了 +- 17. @_@,所以它被华丽的无视了,我们不打算使用它


    Chrome 和IE保持一致,但是它考虑到了横向鼠标滚轮设备的情况,所以增加了两个鼠标来分别获取值

    事件 onmousewheel
    wheelDelta {number}
    wheelDeltaX {number}
    wheelDeltaY {number}

    这次 Opera 又是集大成者,既有detail 取值也一样是3,-3,又有wheelDelta,不过表现上倒是很一致
    事件 onmousewheel
    detail = {number}
    wheelDelta = {number}



    本来我们应该从Firefox支持的event.detail或者IE等支持的event.wheelDelta的取值中,选择一个,然后把另一个通过计算做成统一的,
    但是实际上我们只能通过这些值知道 是向上滚 还是向下滚,
    所以为了方便,我们两个都不取,通过计算把他们统一成 +1 和 -1.(这样做也是为了实际应用中的运算方便);

    对于IE,Chrome来说,直接除以120就可以搞定

    Opera 同时支持wheelDelta和detail ,但是detail没有wheelDelta同一位置递增的能力,所以
    我们首先优先判断wheelDelta是否存在,如果存在,就使用wheelDelta,如果不存在再使用detail

    由于firefox的键盘干扰,我们还需要对detail做一些过滤
    首先用这个值跟3做取模运算 value % 3
    说它是3的倍数,那么返回值是0,我们就用value除以3后返回( 保证返回的值是+1 -1 )
    如果返回值不是0,那说明这个值不是1就是-1,那就直接返回这个值

    最后,由于Firefox返回值的规则是向上是负 向下是正,与平时的习惯不同,我们要将正负反转过来,方法也很简单,计算结果前面加一个负号就可以搞定
    话说回来,对滚轮事件的支持情况firefox真是有点闷.

    好了,分析了一大堆,其实代码就几句:

    复制代码 代码如下:

    function getWheelValue( e )
    {
    e = e||event;
    return ( e.wheelDelta ? e.wheelDelta/120 : -( e.detail%3 == 0 ? e.detail : e.detail/3 ) );
    }


    最后说说未来的滚轮事件和API
    在DOM3 Event 中
    滚轮事件变得更为复杂(也支持更多的东西)
    注册的事件并没有变,依然叫mousewheel
    专门增加了两枚滚轮事件对象
    MouseWheelEvent
    WheelEvents
    而且支持了x,y,z三个轴向的滚轮值( 真复杂>_< )

  • 相关阅读:
    程序员常见的坏习惯,你躺枪了吗?
    程序员常见的坏习惯,你躺枪了吗?
    程序员常见的坏习惯,你躺枪了吗?
    ACM2037
    [Golang]字符串拼接方式的性能分析
    如果一个类同时继承的两个类都定义了某一个函数会怎样呢 | Code4Fun
    Python学习笔记(四)函数式编程
    MySql之增删改查 · YbWork's Studio
    季銮西的博客
    ActiveMQ学习总结(一)
  • 原文地址:https://www.cnblogs.com/xiaomier/p/3101628.html
Copyright © 2011-2022 走看看