YAOHAIXIAO.COM

HTML(5),CSS(3),JavaScript,DOM,Ajax,JSON,Front-end technologies & Yaohaixiao

热门标签:JavaScript Performance 前端开发 前端性能优化 原创

Rss

Home » Frontend » JavaScript » DOM » JavaScript动态创建的Link标签插入到 head 的最前面会怎么样?

JavaScript动态创建的Link标签插入到 head 的最前面会怎么样?

由于本人还是蓝色理想论坛前端的实习版主,所以也把文章《如何用JavaScript动态创建link标签到head里》发到了论坛里(由于我的一个乌龙,1年前测试的时候,发现过IE6直接插入head有问题)有个叫sicoolqs朋友认为我的处理方式(当时还做了浏览器的探测)过于的复杂了,给出了更加简洁的处理方案:

var head = document.getElementsByTagName("head")[0];
var link = document.createElement("link");
link.setAttribute("href","xxx.css");
link.setAttribute("rel","stylesheet");
link.setAttribute("type","text/css");
head.insertBefore(link,head.firstChild);

仔细看看link标签添加的在head里的位置:

head.insertBefore(link,head.firstChild);

从代码我们可以很清楚的看到,这样处理,新创建的link标签被添加为了head的第一节点。这样问题就来了,我们知道,浏览器解析CSS样式的顺序是自上而下解析的,这么处理,如果是动态添加的样式里,没有需要重写之前样式的处理,这个解决方案是没有问题的。

但是,实际的开发过程中,我们往往会遇到需要重写CSS的时候,这个时候这个处理方案就出现问题了。我这里特意做了一个测试页面:http://www.yaohaixiao.com/scripts/linktag.htm,我们看看下面各个不同浏览器的表现吧:

IE6-VIEW

IE6 的效果

IE10-VIEW

IE10 的效果

IE10-DEBUG

IE10 的调试图

FIREFOX-VIEW

Firefox 的效果

FIREFOX-DEBUG

Firefox 的调试图

CHROME-VIEW

Chrome 的效果

CHROME-DEBUG

Chrome 的调试图

这些效果都不是我这个测试页面所期望的结果。我期望的是这样的效果:

right-view

期望的效果图

我动态添加的样式表中,重写了背景的样式。而将动态创建的CSS样式link标签文件插入到head的顶部作为fireChild,浏览器解析CSS就出现的问题,这里也是我之前的方案为什么都是将link标签插入到head做末尾的原因。

当看到sicoolqs的解决方案后,我第一时间就想到了insertAfter方法。insertAfter不是JavaScript 默认的 DOM 处理函数,我们需要自己写一个:

var insertAfter = function (newElement, targetElement){
		var parent = targetElement.parentNode;
		if (parent.lastChild == targetElement) {
			// 如果最后的节点是目标元素,则直接添加。因为默认是最后
			parent.appendChild(newElement);
		}
		else {
			parent.insertBefore(newElement, targetElement.nextSibling);
			//如果不是,则插入在目标元素的下一个兄弟节点 的前面。也就是目标元素的后面
		}

估计你也猜到我要用insertAfter做什么了,我要把动态创建的样式查到head标签的lastChild

function createLink(cssURL,lnkId,charset){
	var head = document.getElementsByTagName("head")[0],
	    link = document.createElement("link"),
		// insertAfter 你完全可以作为一个独立的方式使用,
		// 我这里作为内部函数处理,是为了createLink看上去更美观一些
		insertAfter = function (newElement, targetElement){
		var parent = targetElement.parentNode;
		if (parent.lastChild == targetElement) {
			// 如果最后的节点是目标元素,则直接添加。因为默认是最后
			parent.appendChild(newElement);
		}
		else {
			parent.insertBefore(newElement, targetElement.nextSibling);
			//如果不是,则插入在目标元素的下一个兄弟节点 的前面。也就是目标元素的后面
		}
	};
	
	link.setAttribute("href", cssURL);
	link.setAttribute("id", lnkId || "dynamic-style");
	link.setAttribute("charset", charset || "utf-8");
	link.setAttribute("rel", "stylesheet");
	link.setAttribute("type", "text/css");
	insertAfter(link, head.lastChild);
}

看看测试页面的效果:http://www.yaohaixiao.com/scripts/linktag-after.html

OK,都兼容了,而且也不需要用什么浏览器版本探测脚本了。不过现在看看,也没有必要用insertAfter。好了,回到今天的主题,JavaScript动态创建的Link标签插入到 head 的最前面会怎么样,通过上面的例子我们看到,有些浏览器似乎是在动态添加了样式后,用重新至上而下的把CSS重新渲染了一遍。而IE6则显得

所以,为了安全和稳定,我们动态创建的样式一定要添加到head的最末尾,而不能将其放在head的最前面。

声明:本文采用BY-NC-SA协议进行授权。转载请注明转自:JavaScript动态创建的Link标签插入到 head 的最前面会怎么样?

« »

1 条评论

  • 有兴趣的朋友你也可以测试一下,动态创建的link放到了head最前面在不同浏览器的解析效果。还是很有意思的。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(Spamcheck Enabled)