注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

学会珍惜

You've been saying for the longest time

 
 
 

日志

 
 

规避document.write()方法的几种方案  

2013-02-26 13:31:28|  分类: 前端开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

写在前面

其实,很多时候我们可以规避document.write()方法:

  • 重写document.write()方法
  • 通过当前执行的script肯定是当前已加载的所有script中的最后一个可以获取到执行脚本的位置,再选用appendChild、insertBefore或者自己实现的insertAfter方法
  • ……


——听歌 


2013年2月26日


转自:携程UED

原文标题:ControlJS part 3: overriding document.write

原文:http://www.stevesouders.com/blog/2010/12/15/controljs-part-3/

关于ControlJs一共有三篇文章,这是第二部分。ControlJS是让脚本加载更快的一个模块(a javascript module for making scripts load faster). 三篇文章的结构分别为:

1. async loading [中文翻译:http://ued.ctrip.com/blog/?p=2964]
2. delayed execution
 [中文翻译:http://ued.ctrip.com/blog/?p=3017]

3. overriding document.write [中文翻译:http://ued.ctrip.com/blog/?p=3111]

ControlJS的目标是让开发者更好的控制脚本的加载。其中的关键是意识到”loading”有两个步骤:下载[download](获取内容)和执行[execution](包括解析).在ControlJS part 1(中文翻译:http://ued.ctrip.com/blog/?p=2964)中,我主要阐述了如何用ControlJS来异步加载脚本。在ControlJS part 2 (中文翻译:http://ued.ctrip.com/blog/?p=3017)中,我们展示了通过延缓脚本的执行使页面更快速的加载,尤其是Ajax的网络应用,下载了大量的脚本,而这些脚本不需要立刻使用到的。在本篇中,我们将讨论一下在脚本异步加载时,document.write引发的问题。

我很欣赏ControlJS,但是我不得不承认,目前为止我还没有找到很完美的解决document.write的问题。不过,我将描述一下在document.write这个问题上我做出的尝试,然后给出两种替代方案,可以解决异步加载时document.write引发的问题。

Async and document.write

ControlJS是异步加载脚本的。默认情况下,这些一步脚本会在window的onload事件之后再执行。如果这些异步脚本中有一个调用了document.write,那么页面就会被清空。因为在页面load之后再调用document.write会自动调用document.open事件(automatically calls document.open).任何write的内容都会替代目前页面中的内容,这当然不是我们期待的结果。

我希望ControlJS可以正常运行页面的所有脚本。广告的脚本基本都使用了document.write,但是我也发现,很多开发员也使用了document.write.我不希望这些脚本因为使用了ControlJS,不经意间就使页面乱掉了。

这个问题对我而言会相对简单一些,因为ControlJS在每一个内联和外链的脚本执行时都是有顺序的。我的解决方案是重写document.write,然后每次都捕获到每一个脚本的输出。如果当前脚本没有document.write的输出,那么就顺延到下一个脚本。如果有输出,那么我会创建一个元素(目前是SPAN), 插入到目前这个脚本的前面,将这个SPAN的innerHTML设置为document.write的输出。

这个方案相当不错。我把CNN.com的源代码拷贝到本地,然后转换成ControlJS的方案。页面中有两个document.write(包含广告), 这两个都能运行正常。但是仍然有一些问题。其中一个就是将输出写到SPAN中会丢失一些行为,例如hover的方法。不过,最大的问题是,浏览器会忽略用innerHTML写入的script脚本,而广告主要的方法之一就是插入scripts脚本。我有一个补丁的方法就是解析输出中的script标签,然后创建一个SCRIPT的dom节点。这样运行正常了,但是并不是非常的强壮。

ControlJS虽然对于document.write没有很优美的解决方案,但是它仍然很有价值。你并不需要将页面中每一个脚本都转成ControlJS的方式.如果你知道页面中有控件或者广告是使用document.write,那么你可以按照正常的方式加载他们。或者你们可以使用ControlJS来测试一下,是否可以正常运行。

Real solutions for async document.write

在结束关于ControlJS的系列文章之前,我需要提到两个解决异步加载时document.write的替代方案: Aptimize 和  GhostWriter.

Aptimize出售网站加速器,更新HTML的标记来提高网站性能。在11月,他们发布了可以使脚本异步加载的方案(包括广告)。这是我迄今为止了解到的第一个提供此特征的产品。我和Aptimize的En和Derek吃过午餐,了解到他们更详细的解决方案,那听上去很不错。

另一个解决方案是来自 Digital Fulcrum的GhostWriter。Will联系到我,我们有过一次电话会议,也有一些邮件的沟通,是关于他利用HTML的解析来解决document.write的问题。你可以免费尝试一下这个方案[ry the code ]

Wrapping it up

ControlJS有很多特点,有一些是其他脚本加载模块所没有的:

  • 异步加载脚本
  • 能够同时处理内联和外链脚本
  • 在页面渲染结束之后再执行脚本
  • 允许脚本下载但暂时先不执行
  • 结合了HTML标记的属性修改-不需要修改代码
  • 能够解决一些document.write引发的问题
  • control.js本身是异步加载的

ControlJS是一个开源的。我希望其中的一些特点可以利用在其他的脚本加载器中。当然,它也仍然有一些功能需要完善(异步样式文件,更好的document.write的解决方案),并且ControlJS并没有经过大量的测试。如果你要增加功能或者修复bug,请看一下 ControlJS project on Google Code , 或者通过 ControlJS discussion list 来联系我们。

  评论这张
 
阅读(448)| 评论(0)
推荐

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017