鼠标滚轮事件以及满屏滚动实现

MDN对鼠标的滚轮事件的介绍:
<code>这里写图片描述</code>
这里写图片描述

MDN对鼠标滚轮事件的实现:

/*
* 鼠标滚轮事件
* @return   void
* */
function mouseWeel() {
    var prefix = "", 
        _addEventListener, 
        onwheel, 
        support;

    if (window.addEventListener) {
        _addEventListener = "addEventListener";
    } else {
        _addEventListener = "attachEvent";
        prefix = "on";
    }

    // detect available wheel event
    support = "onwheel" in document.createElement("div") ? "wheel" : (// 各个厂商的高版本浏览器都支持"wheel"
              (document.onmousewheel !== undefined) ? "mousewheel" : // Webkit 和 IE一定支持"mousewheel"
              "DOMMouseScroll"); // 低版本firefox

    function _addWheelListener( elem, eventName, callback, useCapture ) {
        elem[ _addEventListener ]( prefix + eventName, support == "wheel" ? callback : function( originalEvent ) {
            !originalEvent && ( originalEvent = window.event );

            // create a normalized event object
            var event = {
                // keep a ref to the original event object
                originalEvent: originalEvent,
                target: originalEvent.target || originalEvent.srcElement,
                type: "wheel",
                deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1,
                deltaX: 0,
                deltaZ: 0,
                preventDefault: function() {
                    originalEvent.preventDefault ?
                        originalEvent.preventDefault() :
                        originalEvent.returnValue = false;
                }
            };

            // calculate deltaY (and deltaX) according to the event
            if ( support == "mousewheel" ) {
                event.deltaY = - 1/40 * originalEvent.wheelDelta;
                // Webkit also support wheelDeltaX
                originalEvent.wheelDeltaX && ( event.deltaX = - 1/40 * originalEvent.wheelDeltaX );
            } else {
                event.deltaY = originalEvent.detail;
            }

            // it's time to fire the callback
            return callback( event );

        }, useCapture || false );
    }

    return function( elem, callback, useCapture ) {
        _addWheelListener( elem, support, callback, useCapture );

        // handle MozMousePixelScroll in older Firefox
        if( support == "DOMMouseScroll" ) {
            _addWheelListener( elem, "MozMousePixelScroll", callback, useCapture );
        }
    };
}

如果是上下滚动的满屏,则使用deltaY,如果向上则该值为负数,否则为正数。

满屏滚动实现:
1首先HTML创建数个块级元素,推荐使用ul>li(更加具有语义化)。
2使用css将每个表示一屏元素都沾满整屏,然后给切换的屏幕时添加动画。你应该隐藏页面的滚动条,否则话页面滚动的不是一屏,而是多了一段距离。你可以还是用下面的方法隐藏滚动条

body{
    overflow: hidden;
}

3监听鼠标滚轮的事件,如果向下,则滚动到下一屏,否则滚动到上一屏
4如果你给页面添加关于每一屏的导航栏,则需要给导航栏添加点击事件

"use strict";

domLoad('load',function () {
    /**
     * 满屏滚动的类
     * @param   void
     * @rerurn   void
     */
    function MaxScreen () {
        this.el = document.querySelector(".nav .wrapper");
        this.navEls = this.el.querySelectorAll(".item");
        this.pageEl = document.querySelector(".pages-wrapper");
        this.activeIndex = 0;
        this.navClassList = null;
        this.pageClassList = null;
        this.item = null;
    }

    MaxScreen.prototype = {
        constructor: MaxScreen,
        init: function() { //启动函数
            this.setNavsClickEvent();
            this.setMouseWheelEvent();
        },
        setNavsClickEvent: function() { //设置导航的点击事件
            var _self = this;
            // 使用事件委托的方式给导航项的容器添加点击事件
            addEvent(_self.el, 'click', function(event) {
                var item = event.srcElement || event.target,
                    index = parseInt(item.getAttribute("data-index"));

                _self.switchPageAndNavState(index);
            });

        },
        opearaClassName: function(elem, opeara, name){ //操作HTML元素的类名
            if (!checkType.isElement(elem) || !checkType.isString(opeara) || !checkType.isString(name)) {
                return null;
            }
            var classList = elem.classList;
            if (opeara === 'remove') {
                if (classList.contains(name)) {
                    classList.remove(name);
                }
            } else if (opeara === 'add') {
                if (!classList.contains(name)) {
                    classList.add(name);
                }
            }
        },
        switchPageAndNavState: function(index) { //切换页面和导航的状态
            print('switchPageAndNavState', {
                'index': index
            });
            var _self = this,
                len = _self.navEls.length ? _self.navEls.length:0,
                parentEl,
                pageEls;

            if (isNaN(len) || (len < 1)) {
                return ;
            }
            if (isNaN(index) || (index < 0) || (index > (len - 1))) {
                return;
            }
            pageEls = _self.pageEl.querySelectorAll('.page');
            // 删除原来有active类名的导航项
            parentEl = _self.navEls[_self.activeIndex];
            _self.opearaClassName(parentEl, 'remove', 'active');
            // 给现在点击的导航项添加active类名
            parentEl = _self.navEls[index];
            _self.opearaClassName(parentEl, 'add', 'active');
            // 删除原来有active类名的页面容器
            _self.opearaClassName(_self.pageEl, 'remove', 'active' + (_self.activeIndex + 1));
            _self.opearaClassName(pageEls[_self.activeIndex], 'remove', 'active');
            // 给现在点击的导航项对应的页面容器添加active类名
            _self.opearaClassName(_self.pageEl, 'add', 'active' + (index + 1));
            _self.opearaClassName(pageEls[index], 'add', 'active');
            // 保存本次点击的导航项的下标
            _self.activeIndex = index;
        },
        setMouseWheelEvent: function() { //添加鼠标滚轮是事件
            var _self = this,
                len = _self.navEls.length ? _self.navEls.length:0,
                index = 0;

            function wheelEvent(event) {
                var scrollDir = event.deltaY > 0? 1:-1;


                /**
                 * 如果页面向下滚动,滚动下一个页面的状态(index++)
                 * 如果页面向上滚动,滚动上一个页面的状态(index--)
                 */

                if (scrollDir > 0) {
                    index = Math.min(++index, len);
                } else {
                    index = Math.max(--index, 0);
                }

                _self.switchPageAndNavState(index);
                // setPageScoll(0, index * pageHeight);

                print('addWheelListener', {
                    'scrollDir': scrollDir,
                    'index': index
                });
            }
            var _throttle = throttle(wheelEvent);

            // 给页面容器添加鼠标滚动事件
            addWheelListener(_self.pageEl, function(event) {
                _throttle(event);
                // wheelEvent(event);
            }, false);
        },
    };

    var maxScreen = new MaxScreen();
    maxScreen.init();
});

这里有几个要点
1.使用事件委托的方式给导航栏添加监听事件。
2.通过data-*自定义属性标记导航栏各个导航项。
3.使用闭包保存上一次点击的导航项的标识(activeIndex)。
4.使用节流函数减少鼠标滚轮事件的触发。

猜你喜欢

转载自blog.csdn.net/babulongbo/article/details/81222730
今日推荐