我们都知道,浏览器的事件一般是从元素的一层一层网上冒泡的(document.addEventListener
方法的第三个参数设置为true
则是冒泡, false
则是捕获),鼠标的滚轮事件也不例外,当某个滚动区域的内容滚动到最底部时,则会往上走,找到最近的父元素,继续滚动。在某些时候这是个很不错的设定,但是当页面的可滚动区域过多的时候,便会造成不好的用户体验。给人以“到处都在动”的感觉,可能你马上会想到event.stopPropagation()
这个方法,但是你可以先试试有用吗。#滑稽#
没错,我也是试了之后发现根本没什么卵用,所以就在网上找 代码如下:(摘自http://blog.csdn.net/jyy_12/article/details/6878049):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| $.fn.extend( { preventScroll: function() { $( this ).each( function() { var _this = this; if ( navigator.userAgent.indexOf( 'Firefox' ) >= 0 ) { _this.addEventListener( 'DOMMouseScroll', function( e ) { _this.scrollTop += e.detail > 0 ? 60 : -60; e.preventDefault(); }, false ); } else { _this.onmousewheel = function( e ) { e = e || window.event; _this.scrollTop += e.wheelDelta > 0 ? -60 : 60; return false; }; } } ) } } ); $( ".box" ).preventScroll();
|
然后问题就这么愉快的解决了!
于是我便开始愉快的开始测试,是的当当前滚动条滚动到滚动到顶部继续滚动的话,不会导致body或者其他父元素的滚动条继续滚动,但是总觉得哪里没对。不信的童鞋可以直接写代码测试一下。
其他浏览器我没有测试过,用chrome的童鞋肯定发现了,惯性呢?滚动的惯性呢?是的因为e.preventDefault()
阻止了它的默认滚动行为,改用this.scrollTop += e.detail > 0 ? 60 : -60
这种编程式的滚动,导致滚动没那么流畅了。肯定有人会说,再继续写代码模拟这个惯性不就好了吗? 确实可以,但不觉得代价太大了点?是的,肯定有其他的解决办法。其实爱思考的人看到这里早已找到了答案,通过e.detail
或者e.wheelDelta
是可以知道鼠标滚轮是在向上还是向下滚动的,向上滚,滚动到顶部,则e.preventDefault(),向下滚,滚动到最下面,也e.preventDefault()
,于是这个题目就这样完美的解决了,滚动的行为依然是浏览器的默认行为,但是它确实不再向上冒泡了,贴上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| $.fn.extend( { preventScroll: function() { return $( this ).each( function() { var _this = this; if ( navigator.userAgent.toLowerCase().indexOf( "firefox" ) > 0 ) { _this.addEventListener( 'DOMMouseScroll', function( e ) { if ( this.scrollTop + this.clientHeight == this.scrollHeight && e.detail > 0 ) { e.preventDefault(); e.returnValue = false; } else if ( this.scrollTop === 0 && e.detail < 0 ) { e.preventDefault(); e.returnValue = false; } }, false ); } else { _this.addEventListener( 'mousewheel', function( e ) { if ( this.scrollTop + this.clientHeight == this.scrollHeight && e.wheelDelta < 0 ) { e.preventDefault(); e.returnValue = false; } else if ( this.scrollTop === 0 && e.wheelDelta > 0 ) { e.preventDefault(); e.returnValue = false; } }, false ); } return this; } ); } } );
|
是的,这个问题就这么完美解决了,可能不是最佳实现,但是确实比上面的代码要更贴近浏览器原来的样子,我们在写代码的时候对于浏览器的默认行为,不管是从代码来说还是用户体验来说,都应该抱着谨慎的态度。