不为成仙,只为在这红尘中等你回来。

您现在的位置是:网站首页>>Javascript

window.onload 和 window.onscroll 冲突问题

2020年4月3日 15:53 | 分类:Javascript | 标签: Javascript

问题描述

同一个页面,我们可能会使用到多个 window.onload/window.onscroll 事件,分别在不同的代码块来执行不同的操作或监听滚动条,但直接使用会导致只有一个 window.onload/window.onscroll 事件能正常运行,而我们是需要他们同时运行,互不影响。

分析

因为前者被后者覆盖了,故此只有一个能正常运行。

window.onload 冲突

原先我们分别在 window.onload 中编写各自的代码块,结果就是后面覆盖前面的。如下:

window.onload = function () {
    alert('运行函数1')
    // 代码一...
}

window.onload = function () {
    alert('运行函数2')
    // 代码二...
}

因此我们可以将它们合并到一个 window.onload 中,各自封装一个函数处理自己的业务逻辑,如下所示:

window.onload = function () {
    alert("加载完成");
    fun1(); // 函数一
    fun2(); // 函数二
}

function fun1() {
    alert('运行函数1')
}

function fun2() {
    alert('运行函数2')
}

window.onscroll 冲突

解决了 window.onload 冲突后,我们又遇到了另一个问题,那就是 window.onscroll 冲突,同样的只有一个能够监听到窗口的滚动。因为在函数一、函数二中还有其他代码,不单单是监听滚动的代码,所以合并到一起不太可行。所以我们需要通过 addEventListener 解决了这种共存问题。

定义和用法

addEventListener() 方法用于向指定元素添加事件句柄。 提示: 使用 removeEventListener() 方法来移除 addEventListener() 方法添加的事件句柄。

语法

element.addEventListener(event, function, useCapture)

参数值

方法

function addEvent(obj, type, fn) {
    if (obj.attachEvent) {
        obj.attachEvent('on' + type, function () {
            fn.call(obj);
        })
    } else {
        obj.addEventListener(type, fn, false);
    }
}

addEvent(window, 'scroll', function () {
    alert('first method')
});
addEvent(window, 'scroll', function () {
    alert('second method')
});

完整代码

<html>
<head>
    <script type="text/javascript">
        window.onload = function () {
            alert("加载完成");
            fun1(); // 函数一
            fun2(); // 函数二
        }


        function fun1() {
            alert('运行函数1')
            // 代码块一...
            addEvent('scroll', function () {
                console.log('第一次调用')
            });
            // 代码块二...
        }


        function fun2() {
            alert('运行函数2')
            // 代码块三...
            addEvent('scroll', function () {
                console.log('第二次调用')
            });
            // 代码块四...
        }


        function addEvent(type, toDo) {
            if (window.attachEvent) { // 针对不同浏览器的判断
                window.attachEvent('on' + type, function () {
                    toDo.call(window)
                })
            } else {
                window.addEventListener(type, toDo, false)
            }
        }
    </script>
</head>
<body>
<span id="top"></span>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
<p>博客地址www.iamnancy.top</p>
</body>
</html>

效果展示

其他方法

方法一

先判断之前有没有加载过监听事件

缺点:只能监听两个滚动条事件

// 第一次监听滚动条事件
window.οnscrοll = function () {
    console.log('首次监听滚动条事件')
}
// 获取滚动事件的对象
var method = window.onscroll
// 如果滚动事件已存在过
if (typeof method == 'function') {
    window.onscroll = function () {
        method.call(this)
        console.log('第二次监听滚动条事件 ')
    }
}

方法二

页面需要加载 jQuery

$(document).ready(function () {
    $(window).scroll(function () {
        console.log('第一次调用')
    })
    $(window).scroll(function () {
        console.log('第二次调用')
    })
})

参考

多个window.onscroll同时存在的解决方案