原生js的attachEvent和addEventListener解决window.onload在一个页面只能执行一次的问题
1. window.onload和$(document).ready()的区别
一般提到js的window.onload就会联想到jquery的$(document).ready(),下面简述下两者的区别
1)js的window.onload方法是当网页中的所有元素(包括元素的关联文件,如图片)全部加载完毕后执行的,并且一个页面里面window只能绑定一次onload事件,多次绑定则执行最后一次绑定的处理函数。
2)jquery中的$(document).ready()方法是页面DOM加载完毕就执行,此时元素的关联文件(如图片)可能还没加载完,特点是一个页面可以多次调用$(document).ready()方法
下面的输出结果为:window onload3(前面两个onload事件不执行)
<script> window.onload = function() { console.log('window onload 1'); }; window.onload = function() { console.log('window onload 2'); }; window.onload = function() { console.log('window onload 3'); }; </script>
下面的输出结果为:
document ready1
document ready2
document ready3
<script src="jquery-1.7.2.js" type="text/javascript"></script> <script> $(document).ready(function() { console.log('document ready 1'); }); $(document).ready(function() { console.log('document ready 2'); }); $(document).ready(function() { console.log('document ready 3'); }); </script>
2. 用element.attachEvent('onload', handler)替代window.onload
鉴于window.onload在一个页面只能绑定一次,有时为了在页面全部元素加载完毕后执行一些方法,会将这些方法全部写在window.onload函数里面
<script> window.onload = function() { onload1(); onload2(); onload3(); }; function onload1() { console.log('window onload 1'); }
function onload2() { console.log('window onload 2'); }
function onload3() { console.log('window onload 3'); } </script>
这个方法可以解决一部分问题,但是一来代码不是很美观,二来当这个页面引入了一些用到了window.onload方法的插件时,就不能这样使用了,解决方案是使用ele.attachEvent('onload', handler);
attachEvent是为元素添加事件监听器,当触发该事件时调用事件处理函数,原型为:ele.attachEvent('type', handler)。其中ele为添加事件监听器的元素,type为带'on'的事件类型如'onload',handler为事件触发时的处理函数。
这个方法的特点是可以为同一元素多次绑定同一事件。
下面的代码在IE系列的输出结果为:(IE下attachEvent为后绑定先执行)
window onload 3
window onload 2
window onload 1
<script> window.attachEvent('onload', onload1); window.attachEvent('onload', onload2); window.attachEvent('onload', onload3); function onload1() { console.log('window onload 1'); }
function onload2() { console.log('window onload 2'); }
function onload3() { console.log('window onload 3'); } </script>
有一点必须注意的是attachEvent是IE的一个私有属性,现代浏览器必须使用ele.addEventListener('load', handler, false);
addEventListener也是为事件注册监听器,原型为:ele.addEventListener('type', handler, isCapture)。其中ele为添加事件监听器的元素,type为不带'on'的事件类型如'load',handler为事件触发时的处理函数,'isCapture'为是否在事件捕获阶段执行处理函数,一般为false。与attachEvent一样可以为同一元素多次绑定同一事件。
下面的代码在现代浏览器的输出结果为:(现代浏览器下addEventListener为先绑定先执行)
window onload 1
window onload 2
window onload 3
<script> window.addEventListener('load', onload1, false); window.addEventListener('load', onload2, false); window.addEventListener('load', onload3, false); function onload1() { console.log('window onload 1'); } function onload2() { console.log('window onload 2'); } function onload3() { console.log('window onload 3'); } </script>
另外jquery的$(window).load()方法也可以解决window.onload在一个页面调用一次的问题。