document.write:

JavaScript中对document.open所开启的文档流(document stream操作的API方法,它能够直接在文档流中写入字符串,一旦文档流已经关闭,那document.write就会重新利用document.open打开新的文档流并写入,此时原来的文档流会被清空,已渲染好的页面就会被清除,浏览器将重新构建DOM并渲染新的页面。

一.写入文本(页面加载中可以写入,而不会出现重写页面问题)

利用document.write来写入脚本,先考虑如下代码:

 <!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<h1>Head</h1>
<script>
document.write('<p>hello document</p>');
</script>
<h2>Tail</h2>
</body>
</html>

这段在h1h2之间内嵌一个脚本,使用document.write来写入一个p标签。刷新页面,可以看到最终的结果是:

Head

hello document

Tail

即要文本在脚本执行的位置被插入。这是因为,浏览器就解析HTML构建DOM的时候,如果遇到script就会暂停下来,解析script中的代码并执行,然后再继续解析剩余HTML。(阻塞进行的)此时再去浏览器中检测DOM的结构,会发现scripth2之间多了一个p,浏览器在解析完h1之后,碰到script并执行之,此时document.write将一段HTML代码写入到文档流中,script执行完毕后,浏览器会解析文档流中的字符串,对新添加的p标签进行解析。如果将渲染好的页面保存下来,不同的浏览器会有不同的结果。如Chrome和Firefox的做保存下来的页面文件中,script后面会增加p标签,而IE中则是维持原状。(这里指的是原有的HTML结构,不同浏览器将页面保存会作不同的处理,有些会增加一些不影响原有结构的标签或注释。这意味着,如果浏览器重新加载Chrome或Firefox中保存下来的页面文件,就会多出一个p标签。

二.写入脚本(注意加转义符号)

既然document.write可以写入p并被浏览器解析,那么自然地也可以写入script标签。

<script>
document.write('<script>alert("oops!!!")</script>');
</script>

将代码作出上面的改动,意图在利用document.write在页面中插入一段脚本。这段代码的本意是弹出一个窗口,阻塞浏览器对HTML的解析。浏览器下刷新页面,发现并不管用,取而代之的是显示出一个没有意料到的页面。

 Head

 ');
Tail

去检查DOM树,就会发现,这段脚本被拦腰截断了!浏览器将它解析成以下代码:

 <script>
document.write('<script>alert("oops!!!")
</script>
');

插入文本中的</script>被当成了第一个script的闭合标签,因此这个段代码成了非法代码,因为document.write的调用书写不正确,缺少右边的括号)。此时,你可以在console中看到相关的错误信息。(控制台)解决这个问题,我们可以对插入文本中闭合的的标签进行轻微修改,对最后一个>进行转义,变成\>。此时再刷新一下页面,就可以看到预想中的结果。即页面中仅显示h1,弹窗阻塞了浏览器对HTML的解析,关闭弹窗后,浏览器继续对HTML的解析并完成对页面的渲染。再去看看DOM的结构,会发现在原有的script元素后面又多了一个新的<script>元素,其中所执行的代码就是我们的alert("opps!!!")

弊端

从某个角度说,document.write的实际功能确实很强,能够直接修改文档流,但它有很多弊端:

在非loading阶段调用document.write会清除已加载的页面;

document.write不能够在XHTML中使用;

嵌入script中的document.write不能给任意节点添加子节点,因为它是随着DOM的构建执行的;

利用document.write写入HTML字符串流并不是一个好方法,它有违DOM操作的概念;

利用document.write添加script加载外部脚本时,浏览器的HTML解析会被script的加载所阻塞;

document.getElementById:

document.getElementById(" ") 得到的是一个对象,用 alert 显示得到的是“ object ”,而不是具体的值,它有 value 和 length 等属性,加上 .value 得到的才是具体的值!

document 对象

属性: title ; bgColor ; url; ( 使用: document.title)

方法:

focus:使得元素得到焦点并执行由 onfocus 事件指定的代码。

getElementById:获取对 ID 标签属性为指定值的第一个对象的引用。

getElementsByName:根据 NAME 标签属性的值获取对象的集合。

getElementsByTagName:获取基于指定元素名称的对象集合。

document.write vs document.getElementById的更多相关文章

  1. document.getElementsByName和document.getElementById用法

    本文的问题在国外的一个网站得到了答案http://stackoverflow.com/questions/11235409/no-getelementbyid-for-body document.bo ...

  2. 各浏览器对使用 document.id 和 document.name 获取对象的支持存在差异

    标准参考 无. 问题描述 各浏览器使用 document.id 和 document.name 方法获取对象引用的支持存在差异. 造成的影响 某些浏览器中通过 document.id 和 docume ...

  3. 【转】document.documentElement和document.body的区别

    转自:http://www.cnblogs.com/ckmouse/archive/2012/01/30/2332070.html 网页中获取滚动条卷去部分的高度,可以通过 document.body ...

  4. document.documentElement和document.body的区别

    网页中获取滚动条卷去部分的高度,可以通过 document.body.scrollTop 来获取,比如使div跟着滚动条滚动: <div id="div" style=&qu ...

  5. document.body、document.documentElement和window获取视窗大小的区别

    来源:http://www.ido321.com/906.html 在w3school关于window对象的介绍中,介绍了获取浏览器窗口大小的三种方法(浏览器的视口,不包括工具栏和滚动条). 对于In ...

  6. 用document.onreadystatechange和document.readyState确保文档加载完毕才获取DOM

    document.onreadystatechange = function(){ //document.readyState有“interactive”和“complate”两个值 if(docum ...

  7. HTML5中类jQuery选择器querySelector的高级使用 document.querySelectorAll.bind(document);

    基本用法 querySelector 该方法返回满足条件的单个元素.按照深度优先和先序遍历的原则使用参数提供的CSS选择器在DOM进行查找,返回第一个满足条件的元素. ----> querySe ...

  8. 点击图片或者鼠标放上hover .图片变大. 1)可以使用css中的transition, transform 2) 预先设置一个 弹出div. 3)弹出层 alert ; 4) 浏览器的宽度document.documentElement.clientWidth || document.body.clientWidth

    变大: 方法一: 利用css属性. 鼠标放上 hover放大几倍. .kecheng_02_cell_content img { /*width: 100px; height: 133px;*/ wi ...

  9. document.body、document.documentElement和window获取视窗大小的差别

    来源:http://www.ido321.com/906.html 在w3school关于window对象的介绍中,介绍了获取浏览器窗体大小的三种方法(浏览器的视口,不包含工具栏和滚动栏). 对于In ...

  10. document.documentElement和document.body 与document.compatMode的关系

    首先我们看看document.compatMode(兼容模式): document.compatMode它有两种可能的返回值:BackCompat和CSS1Compat, document.compa ...

随机推荐

  1. Visual Studio 2012 编译错误【error C4996: 'scanf': This function or variable may be unsafe. 】的解决方案(转载)

    转载:http://www.th7.cn/Program/c/201303/127343.shtml 原因是Visual C++ 2012 使用了更加安全的 run-time library rout ...

  2. Spark On YARN 分布式集群安装

    一.导读 最近开始学习大数据分析,说到大数据分析,就必须提到Hadoop与Spark.要研究大数据分析,就必须安装这两个软件,特此记录一下安装过程.Hadoop使用V2版本,Hadoop有单机.伪分布 ...

  3. React 回忆录(二)为什么使用 React?

    Hi 各位,欢迎来到 React 回忆录!

  4. Python3基础 delattr 删除对象的属性

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  5. word2vec 中的数学原理详解(一)目录和前言【转】

    本文转载自:https://blog.csdn.net/itplus/article/details/37969519 word2vec 是 Google 于 2013 年开源推出的一个用于获取 wo ...

  6. Sass常用写法

    Sass使用变量,变量以$开头 $bgcolor:#f40; background-color:$bgcolor; 如果变量需要嵌套在字符串当中,就需要写在#{}之中 $direction:left; ...

  7. 【Django】【五】开发Web接口

    [HTTP协议与JSON] 1. HTTP协议 特点如下: (1)支持客户/服务器模式. 简单快速:客户向服务器请求服务时,只需传送请求方法和路径.请求方法常用的有GET.POST.每种方法规定了客户 ...

  8. Linux——软件包简单学习笔记

    Linux中的是那种软件包:  (这里学习是基于redHat的Cent-OS) 1: 二进制软件包管理(RPM.YUM) 2:源代码包安装 3: 脚本安装(Shell或Java脚本) 一: 二进制软件 ...

  9. MongoDB(课时6 关系查询)

    支持关系查询操作:大于($gt),小于($lt),大于等于($gte),小于等于($lte),不等于($ne ),等于(key:value 或 $eq).想让这些操作正常使用,需要准备一个数据集合. ...

  10. Hibernate HQL查询 插入 更新(update)实例

    1.实体查询:有关实体查询技术,其实我们在先前已经有多次涉及,比如下面的例子:String hql=”from User user ”;List list=session.CreateQuery(hq ...