`
yiminghe
  • 浏览: 1434086 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

页面加载判断与 load 研究

阅读更多

判断页面加载完毕进行相关操作是经常碰到的问题 ,不能仅仅满足于 window.onload 或 <body onload="">。

 

<html>
	<head>
<title>页面加载问题-onload-by yiminghe</title>
<script>
function ready() {
    alert(document.getElementById('i_test').value);
}

var addE = function() {
    if (window.addEventListener) {
        return function(el, eventName, fn, capture) {
            el.addEventListener(eventName, fn, (capture));
        };
    } else if (window.attachEvent) {
        return function(el, eventName, fn, capture) {
            el.attachEvent("on" + eventName, fn);
        };
    } else {
        return function() {
            };
    }
} ();


/*

 标准DOM2事件添加,ie,ff兼容 ,等页面image、flash、iframe等都载入完才运行   ,
 在如下的 html中 若不能上126 则 等很长时间才有弹出框呢。  
 等同于  window.onload=ready;
 */

/*
	addE(window,'load',function() {
	ready();
	});
	*/
	
/*
ff 都不行,可见 body 没有 onload 事件
ie 报错,还没有 document.body 形成

*/
/*
addE(document.body,'load',function() {
	ready();
	});
	*/


/**
	  最快的方法,我们不必等待页面image、flash、iframe等都载入完(若要获取图片属性则不要用),只要htmlDOM形成就可以了,
	  
	  而这个各个浏览器有不同实现,ff 遵循了标准,而ie则没有遵循标准
	  
	  在下面的例子中 ,即使上不了 126 ,也会很快提示页面载入完成
	**/

function DOMOk(readyOk) {

    /* for Mozilla */
    if (document.addEventListener) {
        document.addEventListener("DOMContentLoaded", readyOk, false);
    }

    /* for Internet Explorer */
    if (window.attachEvent) {
        document.write("<s" + 'cript id="ie-deferred-loader" defer="defer" src="/' + '/:"></s' + "cript>");
        var defer = document.getElementById("ie-deferred-loader");
        defer.onreadystatechange = function() {
            if (this.readyState == "complete") {
                readyOk();
            }
        };
    }
}
DOMOk(ready);
</script>
</head>
<body> 
	<!--
	
	//ie ff 兼容,非常老式,在dom2标准出现之前就有了
	onload="ready()"
	
	--> 
<input id="i_test" value="1" />
<img src='http://mimg.126.com/logo/126logo_tsp.gif' />
</body>
<script>
/*
只有 ie 可以 ,可能为了兼容标准以前的ie版本,且不能放在 head 中 ,document.body尚不存在
*/
//	document.body.onload=ready;

/*
ie,ff 都不行,可见 body 没有 onload 事件
*/
/*
addE(document.body,'load',function() {
	ready();
	});
*/
</script>
</html>

 

这个问题这么复杂,那么 javascript 库肯定会考虑 ,看看 extjs 的实现吧,Ext.onReady 就不解释了,原理和上相同。需要注意的是 defer 属性并不能通过动态添加脚本标签设置,而只能在页面初始阶段通过 document.write 设置!

 

 

这里使用了 script 的 defer 属性,但是这种方法有个问题,当页面包含iframe时,必须得等该页面的 iframe 载入完毕后才会触发 defer 的脚本执行。所以更好的方法是 doScroll hack :

 

function IEContentLoaded (w, fn) {
	var d = w.document, done = false,
	// only fire once
	init = function () {
		if (!done) {
			done = true;
			fn();
		}
	};
	// polling for no errors
	(function () {
		try {
			// throws errors until after ondocumentready
			d.documentElement.doScroll('left');
		} catch (e) {
			setTimeout(arguments.callee, 50);
			return;
		}
		// no errors, fire
		init();
	})();
	// trying to always fire before onload
	d.onreadystatechange = function() {
		if (d.readyState == 'complete') {
			d.onreadystatechange = null;
			init();
		}
	};
}
 

不过这种解法仍然有问题,当页面处于 iframe 中时,doScroll 实际上不会抛错   :

 

顶层:

 

<script>
	try{
	document.documentElement.doScroll("left");
	alert(2);
}catch(e){
	alert(3);
}
</script>
<iframe src='http://yiminghe.xx.com/t/inner.html'/>
 

iframe :

 

<script>
	alert(window.top==window);
	//alert(window.frameElement);
	document.documentElement.doScroll("left");
	alert(1);
</script>
<img src='sleep.jsp'/>
 

 

所以只能在页面在顶层时使用:

// polling for no errors

	if(window==window.top)(function () {
		try {
			// throws errors until after ondocumentready
			d.documentElement.doScroll('left');
		} catch (e) {
			setTimeout(arguments.callee, 50);
			return;
		}
		// no errors, fire
		init();
	})();
 

最不好也可以用 onreadystatechange ,其complete 仍然会比window load 快,但是依然在 img load 后出发 (dean's test )。

 

另一点是关于使用 window.top == window 还是使用 window.frameElement 来判断是否是顶层窗口,如果使用 window.frameElement 的话还得注意 try catch 否则如果iframe和主页面不同域会报错,所以一般还是用 window.top==window好一点?


update : 2010-12-26

 

还是使用 window.frameElement 好,否则 ie6 下会有问题,iframe中页面如果在设置 domain 前访问了 top ,则即使 iframe 的 domain 和 外层页面一致也无法访问 window.frameElement了 :jquery ticket 4787

 

PS:ie9 quirks 模式并不能模拟 ie6 这种bug,quirks 应该是 5.5

 

结果图:

 

 

 

 

 

 

 

 

 

  • 大小: 25.2 KB
  • 大小: 42 KB
分享到:
评论

相关推荐

    JS判断图片是否加载完成方法汇总(最新版)

    下面小编给大家整理了几种关于JS判断图片是否加载完成方法汇总,一起看看吧。 一、load事件 [removed] $('img').onload = function() { //code } [removed] 优点:简单易用,不影响HTML代码。 缺点:只能指定一...

    Gif-Load-ReTry-Refresh-支持gif图片的Load反馈框架,只需一张gif图,一行代码解决初次加载,重试加载,刷新加载,与生命周期绑定,LeakCanary检测无内存泄漏.zip

    }配置属性方法参数作用setGifR.drawable.*加载页面的Gif图setBackgroundColorR.color.*加载页面整体背景颜色setBtnNormalColorR.color.*加载页面按钮未按下时的颜色setBtnPressedColorR.color.*加载页面按钮按下时的...

    前端图片懒加载(lazyload)的实现方法(提高用户体验)

    图片懒加载又称图片延时加载、惰性加载,即在用户需要使用图片的时候加载,这样可以减少请求,节省带宽,提高页面加载速度,相对的,也能减少服务器压力。 惰性加载是程序人性化的一种体现,提高用户体验,防止一次...

    LazyLoad 延迟加载(按需加载)

    2:解决方案 用客户端语言来判断用户当前的可视范围,只加载用户可视范围的内容。最主要的是图片。因为文字信息,相对较小,其他多媒体内容相对占用服务器流量更多。 3:演示例子(最后提供)4:解析 首先我们要分析...

    js或者jquery判断图片是否加载完成实现代码

    网页中有时候需要获得图片的宽度和高度,来定义某些大小,可是这个是需要从服务端请求图片,下载到本地才能够得到的,有些js或者jquery代码在还没有加载完图片时就执行了。怎么办呢?jquery提供一个方法: 代码如下:...

    JS实现非首屏图片延迟加载的示例

    减少资源加载可以明显的优化页面加载的速度,所以可以减少页面载入时立即下载的图片的数量,以提高页面加载速度,其他的图片在需要的时候再进行加载。 思路 想要实现以上的目标,有几个地方需要思考。 1、如何判断...

    JS图片懒加载技术实现过程解析

    懒加载(LazyLoad)是前端优化的一种有效方式,极大的提升用户体验,图片一直是页面加载的流浪大户,现在一张图片几兆已经是很正常的事,远远大于代码的大小。 原理:页面加载后只让文档可视区内的图片显示,其它不...

    ASP.NET的网页代码模型及生命周期

    代码隐藏页模型与单文件页模型不同的是,代码隐藏页模型将事物处理代码都存放在cs文件中,当ASP.NET网页运行的时候,ASP.NET类生成时会先处理cs文件中的代码,再处理.aspx页面中的代码。这种过程被成为代码分离。 ...

    js检测iframe是否加载完成的方法

    iframe个人感觉最独特的应用之一就是配合P3P协议可以实现跨域写入cookie(好象除此之外,还没找到更有效的办法),但是有时候我们不知道这个iframe页面是否执行完毕,有没有办法判断iframe里的页面是否load完成了呢?...

    使用js判断TextBox控件值改变然后出发事件

    代码如下:[removed] var firsty;...//判断改变了没有 function onloadload()//给全局变量赋最初值 在页面onload事件中调用&lt;body onload=”onloadload()”&gt; { firsty = document.getElementByI

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    (3)针对页面自适应问题,本文结合渐进增强以及拥抱流式布局的思想,同时研究利用了移动设备的视口特性,实现跨分辨率、跨设备的页面自适应。 (4)针对系统的功能实现问题,通过结合利用原生态框架与HTML5的跨平台...

    asp.net下的异步加载

    3:后台Load事件必须判断是否为Post请求   后台代码如下: 测试结果如下:   第二种:类似于.net MVC直接请求方法。 1:后台代码中,引入using System.Web.Services; 2:方法必须是静态修饰,且方法上面打上特性 ...

    Google Android SDK开发范例大全(PDF高清完整版3)(4-3)

    8.4 设计前往打开网页功能——Intent与Uri.parse 8.5 将网络图像网址放入Gallery中显示——URL.URLConnection.BaseAdapter 8.6 即时访问网络图文件展示——HttpURLConnection 8.7 手机气象局,实时卫星云图——...

    Google Android SDK开发范例大全(PDF完整版4)(4-4)

    8.4 设计前往打开网页功能——Intent与Uri.parse 8.5 将网络图像网址放入Gallery中显示——URL.URLConnection.BaseAdapter 8.6 即时访问网络图文件展示——HttpURLConnection 8.7 手机气象局,实时卫星云图——...

    firefox下jquery iframe刷新页面提示会导致重复之前动作

    }) 框架打开后设置地址到一个空页面就可以避免这个提示但有个问题 就是设置src后会触发load事件,会导致循环加载所以需要设置一个参数 等触发完正常事件后 做一个标记load完后判断一下 代码如下:$(“iframe[name=hi]...

    Google Android SDK开发范例大全(PDF高清完整版1)(4-1)

    8.4 设计前往打开网页功能——Intent与Uri.parse 8.5 将网络图像网址放入Gallery中显示——URL.URLConnection.BaseAdapter 8.6 即时访问网络图文件展示——HttpURLConnection 8.7 手机气象局,实时卫星云图——...

    vue-lazy-container:检测页面中元素的可见性

    Vue懒惰的容器 English |介绍vue惰性容器,通过检测页面中元素的可见性,决定是否加载资源并进行渲染。为什么当页面内容超过一个屏幕时,我们通常只希望加载和呈现当前屏幕的数据。随着页面的滚动,加载并呈现以下...

    web-demo:分享一些实用的小案例

    lazyLoad 简单的实现图片懒加载 2021-04-17 懒加载原理: 判断当前图片是否在浏览器的可视区域范围内 如果 浏览器可视区域的高度 + 滚动条滚动的距离 &gt;= 该图片到页面最顶部的距离 那么就加载图片 先给img标签的src...

    Google Android SDK开发范例大全的目录

    8.4 设计前往打开网页功能——Intent与Uri.parse 8.5 将网络图像网址放入Gallery中显示——URL.URLConnection.BaseAdapter 8.6 即时访问网络图文件展示——HttpURLConnection 8.7 手机气象局,实时卫星云图——...

Global site tag (gtag.js) - Google Analytics