javascript的事件加载
通常来说,window.onload就够用了,如果想加载多个事件,我们可以采取以下方式:
window.onload = function (){ func1(); func2(); func3(); //更多加载事件……………… } |
但是如果我们需要页面完全呈现前做一些东西呢,如通过脚本加载其他js文件,或在IE6实现fixed……这些东西就要用到domReady了,domReady好像是jQuery的叫做,一个加载函数。在W3C的草稿中,它其中是一种事件,名为 DOMContentLoaded。DOMContentLoaded事件比onload事件快许多,它是在DOM树建成之时就触发,而onload必须要等待页面所有元素的资源都下载完毕时才触发。在标准游览器中调用这个事件很简单的:
document.addEventListener( 'DOMContentLoaded' , function (){ alert( "DOM树建成了!" ) }, false ); |
IE虽然有这么多私有事件,但却没有一个与它相同的,最接近的是readystatechange,加上其他乱七八糟的东西,我们还是能够模拟DOMContentLoaded的。
有时我们加载事件时,可能不是单是通过一个函数就加载完的。比如我要用window.onload加载一段代码,但我还通过JS文件加载一个开源插件,那个插件当它要处理DOM,还是需要等到DOM树完成之时,因此它可能也要搞一个window.onload块。这时页面拥有两个window.onload代码块,很显然,第二个会覆盖掉第一个。这时,我们就要用到loadEvent这样的多重加载函数了。
var loadEvent = function (fn) { var oldonload = window.onload; if ( typeof window.onload != 'function' ) { window.onload = fn; } else { window.onload = function () { oldonload(); fn(); } } } //*******************用法******************* loadEvent(handler1); loadEvent(handler2); loadEvent(handler3); |
在标准游览器中,因为有addEventListener,很轻松就实现DOMContentLoaded的多重加载,那IE怎么办?唯一的办法是,无论是addEventListener还是attachEvent都执行,把多个要加载的代码整合到一块,一次性执行。因此,我们需要一个数组。
window.DOMLoadEvents = []; var addDOMLoadEvent = function (handler) { window.DOMLoadEvents[window.DOMLoadEvents.length]=handler } addDOMLoadEvent(handler); addDOMLoadEvent(handler); addDOMLoadEvent(handler); //更多加载事件 |
那么怎样执行它们,上面仅仅是添加事件,我们需要另一个函数,专门用来执行它的。
var fireContentLoadedEvent = function () { if (arguments.callee.loaded) return ; //让此函数仅仅执行一次 arguments.callee.loaded = true ; var handlers = window.DOMLoadEvents,length = handlers.length; for ( var i=0; i<length; i++) { var func = handlers[i]; func(); //执行要在domReady运行的代码 } } |
那么我们要在什么时候执行上面的函数呢?我们仅讨论IE的情况。在IE中,任何DOM元素都有一个doScroll 方法,无论它们是否支持滚动条。为了判断DOM树是否建成,我们只看看documentElement是否完整就是,因为,它作为最外层的元素,作为DOM树的根部而存在,如果documentElement完整的话,就可以调用doScroll方法了。当页面一加载JS时,我们就执行此方法,当然要如果documentElement还不完整就会报错,我们在catch块中重新调用它,一直到成功执行,成功执行时就可以调用fireContentLoadedEvent 方法了。
参数 | 描述 |
---|---|
scrollbarDown | Default. Down scroll arrow is at the specified location |
scrollbarHThumb | Horizontal scroll thumb or box is at the specified location |
scrollbarLeft | Left scroll arrow is at the specified location |
scrollbarPageDown | Page-down scroll bar shaft is at the specified location |
scrollbarPageLeft | Page-left scroll bar shaft is at the specified location |
scrollbarPageRight | Page-right scroll bar shaft is at the specified location |
scrollbarPageUp | Page-up scroll bar shaft is at the specified location |
scrollbarRight | Right scroll arrow is at the specified location |
scrollbarUp | Up scroll arrow is at the specified location |
scrollbarVThumb | Vertical scroll thumb or box is at the specified location |
down | Composite reference to scrollbarDown |
left | Composite reference to scrollbarLeft |
pageDown | Composite reference to scrollbarPageDown. |
pageLeft | Composite reference to scrollbarPageLeft. |
pageRight | Composite reference to scrollbarPageRight. |
pageUp | Composite reference to scrollbarPageUp. |
right | Composite reference to scrollbarRight. |
up | Composite reference to scrollbarUp. |
var pollDoScroll = function () { try { document.documentElement.doScroll( 'left' ); } catch (e) { setTimeout(arguments.callee, 10); return ; } fireContentLoadedEvent(); } |
我们要页面加载JS立即执行此函数,是直接pollDoScroll()吗?!不要忘记,它只是应用于IE中,我们还要判定一下浏览器。如果支持addEventListener,也肯定支持DOMContentLoaded了(不考虑旧版本),否则就运行pollDoScroll函数。
if (document.addEventListener) { document.addEventListener( 'DOMContentLoaded' , fireContentLoadedEvent, false ); } else { pollDoScroll(); } |
完整的代码如下:
window.DOMLoadEvents = []; var addDOMLoadEvent = function (handler) { window.DOMLoadEvents[window.DOMLoadEvents.length]=handler } var fireContentLoadedEvent = function () { if (arguments.callee.loaded) return ; //让此函数仅仅执行一次 arguments.callee.loaded = true ; var handlers = window.DOMLoadEvents,length = handlers.length; for ( var i=0; i<length; i++) { var func = handlers[i]; func(); //执行要在domReady运行的代码 } } var pollDoScroll = function () { try { document.documentElement.doScroll( 'left' ); } catch (e) { setTimeout(arguments.callee, 10); return ; } fireContentLoadedEvent(); } if (document.addEventListener) { document.addEventListener( 'DOMContentLoaded' , fireContentLoadedEvent, false ); } else { pollDoScroll(); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)