上篇文章主要讲了如何编写kettle的第一个作业,相信大家已经掌握;本篇文章主要介绍一些kettle如何去获取数据,获取数据无非是从接口获取或是从本地文件获取;本章主要讲解如何从接口中获取数据,比如调用一个rest接口,获取返回结果。后续还会讲解如何从一个websocket接口获取数据,这就涉及到插件的开发,将会在以后的高级篇教程中进行讲解;
最终展示结果如下,日志中输出的result字段,便是get请求的返回值;
第一步:按照上图方式,将“获取变量”节点、“HTTP Client”节点和“写日志”节点,拖动到工作区,并通过连接箭头将它们串起来;
第二步:双击打开“HTTP Clinet”节点,进行配置:只需在url处配置(http://www.weather.com.cn/data/sk/101010100.html)
第三步:配置“获取变量”节点和“日志节点”:“获取变量”节点无须配置;“写日志”节点配置如下:
备注:“获取变量”节点虽然没有做任何配置;但此节点在后续的教程中,会逐渐深入,比如:构建基于kettle的数据集成平台,就会经常使用此节点;
最终展示结果如下图:大家会奇怪,为什么会出现405呢?下面进行解释。
第一步:按照上图方式,将“获取变量”节点、“增加常量”节点、“HTTP POST”节点和“写日志”节点,拖动到工作区,并通过连接箭头将它们串起来;
第二步:双击打开“增加常量””节点配置如下:
第三步:双击打开“HTTP POST”节点配置如下:
General页签配置
?Fields页签配置
第四步:“写日志”节点配置同之前的配置类似,这里不做赘述。
第五步:为什么会出现405
说明:之所以会返回405的状态(405是http的一个状态码,可自行百度),因为get请求和post请求使用的是同一个url,这个url地址只支持get请求,所以在使用post请求的时候就会报405的状态码。
下面展示一个正常的请求:
“HTTP Post”节点如下:url中的地址:是我本地写的一个服务支持application/json的post请求;
本篇文章主要介绍了get请求节点与post请求节点,通过这两个几点便可以获取互联网中支持rest请求中的数据(实际工作中,接口之间的调用一般都是rest接口);当然这里介绍的只是最简单的使用,大家可以自行扩展。下篇文章将介绍如何从本地文件获取数据,如何从数据库获取数据;在此之后,进行数据迁移场景的开发,完成一个真实的业务场景;
.查询节点
1.根据节点的层级查询节点
1.childNodes
元素节点,文本节点,
2.children
元素节点
3.parentNode
获取父节点
4.nextSibling
获取下一个兄弟节点
有可能是文本节点
5.nextElementSibling
获取下一个兄弟元素节点
6.previousSibling
获取上一个兄弟节点
有可能是文本节点
7.previousElementSibling
获取上一个兄弟元素节点
2.通过标签名查询节点 - 返回数组
document|elem.getElementsByTagName("标签名");
document:整个文档内查找
elem:某个元素内查找
3.通过元素的name属性值查询节点
document.getElementsByName("name属性值");
返回值:包含指定name属性值的元素的数组
<input type="radio" checked >
4.通过元素的class值查询节点
document|elem.getElementsByClassName("class");
返回:返回包含指定class属性值的所有元素
2.增加节点
1.创建元素节点
语法:
var elem=document.createElement("元素名");
ex:
var div=document.createElement("div");
div.setAttribute("id","container");
div.innerHTML="动态创建的文本";
2.增加节点到网页上
1.document.body.appendChild(elem);
向body中追加elem的新元素
2.parentNode.appendChild(elem);
向parentNode内部追加elem新元素
3.parentNode.insertBefore(newElem,oldElem)
将newElem元素插入到parentNode中oldElem元素之前
3.删除节点
在DOM中,删除节点的行为只能由父元素发起
parentNode.removeChild(elem);
删除 parentNode 中的 elem 元素
4.事件
1.什么是事件
通常都是由用户的行为来激发的操作
2.触发事件的行为
所有的事件在绑定时,必须加 on
1.鼠标事件
1.click 事件
当鼠标单击元素时触发该事件
2.mouseover 事件
当鼠标移入进元素时的事件
3.mouseout 事件
当鼠标移出元素时的事件
4.mousemove 事件
当鼠标在元素内移动时的事件
2.键盘事件
1.keydown 事件
当键位按下时所激发的事件
2.keypress 事件
当键位按下时所激发的事件
3.keyup 事件
当键位抬起时所激发的事件
3.状态改变事件
1.load 事件
当元素加载完成时所触发的事件(body)
2.change 事件
当选项发生改变时所触发的事件(select)
3.focus 事件
当元素获取焦点时所触发的事件(文本框类)
4.blur 事件
当元素失去焦点时所触发的事件(文本框类)
5.submit 事件
当表单被提交时所触发的事件(表单)
3.绑定的方式
1.在元素中绑定事件
<元素 on事件名=""></元素>
2.在js中动态的为元素绑定事件
语法:
DOM对象.on事件名=function(){
}
ex:
var main=document.getElementById("main");
main.onclick=function(){
}
注意:在JS动态绑定事件中,允许使用 this 来表示触发当前事件的DOM元素
4.事件行为
1.状态改变事件
1.load 事件
通常为 body 绑定 load 事件,目的是为了在所有内容都加载完成之后再实现一些初始化的操作
1. <body onload="函数()">
2.JS中动态绑定
window.onload=function(){
网页加载完成后,要执行的操作
}
2.submit 事件
只有表单被提交时才会被触发
注意:该事件需要一个boolean返回值来通知表单是否要继续被提交.如果返回true,则可以提交表单.否则,阻止表单提交
JS中动态绑定:
表单对象.onsubmit=function(){
return true/false;
}
1.创建一个网页,包含多个单选按钮(name相同)
2.创建一个普通按钮
3.单击普通按钮的时候
验证多个单选按钮中必须有一个被选中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <p> <input type="radio" name="gender">男 <input type="radio" name="gender">女 </p> <button onclick="checkRadio()">验证</button> <p> <input type="checkbox" id="chkAll" onclick="checkAll()">全选 <input type="checkbox" name="hobby">吃 <input type="checkbox" name="hobby">喝 <input type="checkbox" name="hobby">玩 <input type="checkbox" name="hobby">乐 </p> <script src="common.js"></script> <script> function checkAll(){ //先获取 chkAll 的选中状态 var isChk=$("chkAll").checked; //获取所有的 hobby 并循环,将所有的hobby的checked更改为isChk var all=document.getElementsByName("hobby"); for(var i=0;i<all.length;i++){ all[i].checked=isChk; } } function checkRadio(){ //得到页面中name=gender的所有的元素 var arr=document.getElementsByName("gender"); //声明变量用于记录 radio 的选中状态 var isChecked=false; for(var i=0;i<arr.length;i++){ if(arr[i].checked){ isChecked=true; break; } } if(isChecked){ alert('通过'); }else{ alert('请选中一项'); } } </script> </body> </html>
点击按钮时
1.先获取三个文本框的值
2.创建两个按钮 - 删除按钮 , 修改按钮
3.先创建四个td
将三个文本框的值追加到前三个td
将两个按钮追加到第四个td中
4.创建一个tr
将四个td追加到tr中
5.将 tr 追加到 table 中
内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。
Document 接口描述了任何类型的文档的通用属性与方法,根据不同的文档类型(例如HTML、XML)提供了不同的API,比如,使用 "text/html" 作为内容类型的HTML文档,实现了 HTMLDocument,而XML文档则实现了XMLDocument,HTMLDocument和XMLDocument接口都是继承自Document接口;
Javascript通过Document类型表示文档;在浏览器中,document对象是Document的一个实例,更具体一点,是HTMLDocument的一个实例,其表示整个HTML页面;并且document对象也是window对象的一个属性,可以将其作为全局对象来访问;因此document对象,既属于BOM又属于DOM的对象;
Document节点的特征:
其子节点可能是一个DocumentType(最多一个)、Element(最多一个,即html)、ProcessingInstruction或Comment;
console.log(document); // 在FF控制台可以看出是属于HTMLDocument类型
console.log(document.nodeType); // 0
console.log(document.nodeName); // #document
console.log(document.nodeValue); // null
console.log(document.parentNode); // null
console.log(document.childNodes.length); // 2
文档的子节点:
DOM标准规定Document节点的子节点可以是DocumentType、Element、ProcessingInstruction或Comment;
<!-- 这是一个comment -->
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<script>
console.log(document.childNodes); // 使用FF查看 NodeList(3)
</script>
</body>
</html>
documentElement属性:
返回文档直接子节点,始终指向HTML页面中的<html>元素,也就是文档的根元素,并且它一定是文档的根元素;
// 注意:在HTML中的第二行有可能是注释
console.log(document.childNodes[2]); // <html>
console.log(document.documentElement); // <html>
console.log(document.lastChild); // <html>
借助这个只读属性,能方便地获取到任意文档的根元素;
body属性:
作为HTMLDocument的实例,document对象还有一个body属性,直接指向<body>;
console.log(document.body);
对于一个拥有<frameset>元素的文档来说,返回的是最外层的<frameset>元素;
另外,该属性是可写的,且为该属性赋的值必须是一个<body>元素;
// 如果HTML结构为body id="oldBody",则:
console.log(document.body.id); // oldBody
var newBody=document.createElement("body");
newBody.id="newBody";
document.body=newBody;
console.log(document.body.id); // newBody
head属性:
指向<head>元素,这个Document对象扩展的一个属性,类型为HTMLHeadElement;
如果有多个<head>元素,则返回第一个;
document.head 是个只读属性,为该属性赋值只会静默失败,如果在严格模式中,则会抛出TypeError异常;
需要注意的是,如果文档源代码中未显式的包含<head>和<body>元素,浏览器将隐式的创建它们;
doctype属性:
该属性是DocumentType 类型,表示了一个包含文档类型的节点对象,指向<!DOCTYPE>标签;
文档当中最多只有一个DocumentType元素;
console.log(document.doctype); // <!DOCTYPE html>
console.log(document.doctype.nextSibling); // <html>
console.log(document.childNodes[0]); // <!DOCTYPE html>
如果存在文档声明,则将其作为document的第一个子节点,解析DOCUMENTTYPE_NODE类型,如果没有声明,则为null;
注:DocumentType对象不能动态创建,它是只读的;
查找元素(选取文档元素):
在DOM中,取得特定的某个或某组元素,并执行一些操作,这是最重要的应用了;
为了获取文档中的这些元素Element对象,DOM定义了许多方式,如:用指定的id属性、name属性、标签名、CSS类或CSS选择器;
取得元素的操作可以使用document对象的几个方法来完成;Document类型为此提供了两个方法;
getElementById()方法:
该方法接收一个参数,即要获取的元素的ID;如果找到就返回这个元素,类型是HTMLElement,如果不存在,则返回null;该参数ID是区分大小写的;
如果页面中多个元素的ID值相同,只返回文档中第一次出现的元素;
var mydiv=document.getElementById("mydiv");
console.log(mydiv);
可以封装一个通过ID查找多个元素的函数,如:
/**
* 函数接受任意多的字符串参数
* 返回一个对象
* 如果一个id对应的元素未定义,则抛出错误
*/
function getElements(/*ids...*/){
var elements={}; // 一个空map映射对象
for(var i=0; i<arguments.length; i++){
var id=arguments[i];
var elt=document.getElementById(id);
if(elt==null)
throw new Error("No element with id:" + id);
elements[id]=elt;
}
return elements;
}
console.log(getElements("mydiv","mylist"));
console.log(getElements("mydiv","mylist")["mydiv"]);
getElementById方法不会搜索不在文档中的元素;当创建一个元素,并且分配ID后,必须要使用appendChild、insertBefore等方法把元素插入到文档中,之后才能使用getElementById()方法获取到;
var elt=document.createElement("div");
elt.id="myelt";
document.body.appendChild(elt); // myelt,添加到文档对后,才能被获取到到
var el=document.getElementById("myelt");
console.log(el); // null
getElementsByName()方法:
返回给定name 属性的所有元素NodeList集合对象;
var mytexts=document.getElementsByName("mytext");
console.log(mytexts); // dom2.html:17 NodeList(2) [p, div]
该方法定义在HTMLDocument类中,而不在Document类中,所以它只针对HTML文档可用,也就是只有HTMLDocument类型才有的方法,在XML文档中不可用;
<fieldset>
<legend>选择你最喜欢的城市</legend>
<ul>
<li><input type="radio" value="北京" name="city" id="beijing" />
<label for="beijing">北京</label></li>
<li><input type="radio" value="南京" name="city" id="nanjing" />
<label for="nanjing">南京</label></li>
<li><input type="radio" value="蚌埠" name="city" id="bengbu" />
<label for="bengbu">蚌埠</label></li>
</ul>
</fieldset>
<script>
var citys=document.getElementsByName("city");
console.log(citys);
</script>
该方法返回的是NodeList对象,在NodeList中返回的元素按照在文档中的顺序排序的,所以可以使用方括号语法来取得每个元素;
console.log(document.getElementsByName("city")[0]);
但IE与Edge返回的是HTMLCollection;但namedItem()方法是属于HTMLCollection类型的,所以,非IE调用namedItem()方法会抛出异常;并且在IE中namedItem()只会返回第一项,因为每一项的name特性都是相同的;
console.log(citys.namedItem("city"));
为某些HTML元素设置name属性,将自动在windows对象中创建对应的属性,对Document对象也是类似的;比如,为<form>、<img>、<iframe>、<applet>、<embed>或<object>元素设置name属性,即在Document对象中创建以此name属性值为名字的属性;
<form name="myform"></form>
<script>
console.log(document.myform);
</script>
即使如此,建议不要用这种方式来获取元素,最好还是显式的使用getElementsByName()方法;
getElementsByTagName()方法:
该方法是通过标签名来获取元素,其接收一个参数,即要取得元素的标签名;返回拥有零个或多个元素的HTMLCollection集合对象,其是动态集合,与NodeList非常类似;;
var spans=document.getElementsByTagName("span");
console.log(spans); // HTMLCollection
其拥有length属性,可以通过方括号或者item()方法来访问HTMLCollection对象中的项;还拥有一个namedItem()方法,该方法可以通过元素的name属性取得集合中的项,但可以简写为使用方括号访问;即如果是数值,则调用item(),如果是字符串索引,就调用namedItem();
var divs=document.getElementsByTagName("div");
console.log(divs);
console.log(divs[0]);
console.log(divs.item(1));
console.log(divs.namedItem("innerDiv"));
console.log(divs["innerDiv"]);
console.log(images[0].src);
images.item(1).src="images/3.jpg";
如果传入“*”,则取得页面中所有元素;(在JS和CSS中,*就是匹配所有的通配符);
var nodes=document.getElementsByTagName("*");
console.log(nodes);
会打印出页面中所有的元素,按照它们出现的顺序(没有层次之分);
在HTML中,该方法参数不需要区分大小写,而在XML中,区分大小写;
Element类也定义了getElementsByTagName()方法,其原理和Document一样,但是它只选取调用该方法的元素的后代元素;
var mydiv=document.getElementById("mydiv");
// 也可以通过getElementsByTagName来获取
// var mydiv=document.getElementsByTagName("div")[0];
var spans=mydiv.getElementsByTagName("span");
console.log(spans);
文档信息:
作为HTMLDocument的一个实例,document对象还有一些标准的Document对象所没有的属性;这些属性提供了document对象所表现的网页的一些信息;
从BOM角度来看document对象是window对象的属性,由一系列集合构成,这些集合可以访问文档的各个部分,并提供页面自身的信息,可以认为document即为加载的html文档;
document.title:包含着<title>元素中的文本,通过它,可以获取或修改当前页面的标题;
var originalTitle=document.title;
console.log(originalTitle);
document.title="zeronetwork title";
// 标题跑马灯效果
var str="北京零点网络科技有限公司-";
document.title=str;
function titleMove(){
str=str.substring(1,str.length) + str.substring(0,1);
document.title=str;
}
setInterval("titleMove()",1000);
lastModified:返回文档被最后修改的日期和时间;
cookie:允许Javascript读写的HTTP cookie的特殊属性;
location:与window对象的location属性引用同一个Location对象;
URL:包含页面完整的URL;一般情况下,该属性的值与location.href 属性相同;但不包含Location对象的动态变化,即在 URL 重定向发生的时候,这个URL属性保存了文档的实际URL,不会发生变化,而 location.href会发生变化;location.href 是可写的,document.URL是只读的;
console.log(document.URL);
console.log(location.href);
document.URL="demo.html"; // 无效
console.log(document.URL);
// location.href="demo1.html"; // 跳转
referrer:来源页面的URL(链接到当前页面的那个页面),如果没有来源,referrer为空字符串;该属性是只读的;
console.log(document.referrer);
这个属性在分析网站SEO数据时特别有用;
var referrer=document.referrer;
var origin=location.origin;
console.log(referrer);
console.log(origin);
if(referrer){
if(referrer.indexOf(origin)==0){
document.write("站内浏览");
}else{
document.write("从外链:" + referrer + "进入");
}
}else{
document.write("直接打开");
}
查找搜索关键词:
var ref=document.referrer;
console.log(ref);
if(ref.indexOf("http://127.0.0.1:5500/search.html?")==0){
var args=ref.substring(ref.indexOf("?") + 1).split("&");
for(var i=0; i<args.length; i++){
if(args[i].substring(0,2)=="q="){
document.write("<h2>搜索的是:</h2>");
keys=args[i].substring(2).split("+");
for(var k in keys){
document.write(decodeURIComponent(keys[k]) + "<br>");
}
break;
}
}
}
domain属性:获取或设置当前文档的域名;
该属性允许当Web页面之间交互时,相同域名下互相信任的Web服务器之间协作放宽同源策略安全限制,其是可读的,但有安全限制,即不能为domain赋任意值;
不能将该属性设置为URL中不包含的域;
// FF提示“The operation is insecure.”,Chrome提示不是127.0.0.1的子域名
// document.domain="www.zeronetwork.cn"; // 异常
console.log(document.domain);
document对象的集合:
除了属性和方法,document对象还有一些特殊的集合;这些集合都是HTMLCollection对象,为访问文档的常用部分提供了快捷方式,包括:
document.anchors:包含文档中所有带name特性的<a>元素;这个属性已经从Web标准中删除了,但浏览器还支持,所以尽量不要再使用;
<!-- link.html页面 -->
<h1>零点程序员</h1>
<h2><a name="one">Web前端开发</a></h2>
<div style="height: 1000px;background-color: purple;">DIV</div>
<h2><a name="two">后端开发</a></h2>
<div style="height: 1000px;background-color: green;">DIV</div>
<h2><a name="three">苹果开发</a></h2>
<div style="height: 1000px;background-color: blue;">DIV</div>
<!-- 主页面 -->
<p>
<input type="button" value="Web前端开发" onclick="jump('one')" />
<input type="button" value="后端开发" onclick="jump('two')" />
<input type="button" value="苹果开发" onclick="jump('three')" />
</p>
<script>
var win=window.open("link.html","newWin","width=250,height=150");
function jump(name) {
console.log(name);
if(win.document.anchors[name]){
win.location.hash=name;
win.focus();
}else{
alert("锚不存在")
}
}
</script>
document.links:包含文档中所有带href特性的<a>元素或<area>元素;
var mydiv=document.getElementById("mydiv");
var links=document.links;
for(var i=0,len=links.length; i<len; i++){
var aNode=document.createElement("a");
aNode.href=links[i].href;
var href=document.createTextNode(links[i].innerText);
aNode.appendChild(href);
mydiv.appendChild(aNode);
}
打开外链进行提醒:
var links=document.links;
for(var i=0,len=links.length; i<len; i++){
var link=links[i];
link.addEventListener("click",function(e){
e.preventDefault();
if(e.target.host !==location.host)
jump(e.target.innerText, e.target.href);
else
location.href=e.target.href;
},false);
}
function jump(title,href){
var div=document.createElement("div");
div.id="jumpDiv";
document.body.appendChild(div);
var str=document.createTextNode("你要访问的:" + href + "不属于本网站,你要继续访问吗?");
div.appendChild(str);
var aGo=document.createElement("a");
aGo.href=href;
aGo.target="_blank";
aGo.appendChild(document.createTextNode("继续"));
div.appendChild(aGo);
var aBack=document.createElement("a");
aBack.href="Javascript:void(0);";
aBack.appendChild(document.createTextNode("关闭"));
aBack.onclick=closeJumpDiv;
div.appendChild(aBack);
}
function closeJumpDiv(){
var jumpDiv=document.getElementById("jumpDiv");
if(jumpDiv)
jumpDiv.parentNode.removeChild(jumpDiv);
}
document.applets:包含文档中所有的<applet>元素;
document.forms:包含文档中所有的<form>元素,与document.getElementsByTagName(“form”)得到的结果是相同的;
<form name="myform">
<!-- id也可为以-->
<input type="text" id="username" />
</form>
<form name="yourform"></form>
<script>
console.log(document.forms); // HtmlCollection
console.log(document.forms.myform);
console.log(document.forms[0]);
console.log(document.forms["myform"]);
console.log(document.forms.myform.username);
</script>
document.embeds:包含文档中所有的<embeds>元素;
document.plugins:包含文档中所有的插件;注意和navigator.plugins的区别;
console.log(document.plugins); // HTMLCollection
console.log(navigator.plugins); // pluginArray
document.images:包含文档中所有的<img>元素实时集合,集合中的每个元素代表了一个image元素的HTMLImageElement,与document.getElementsByTagName(“img”)得到的结果是相同的;
document.scripts:返回一个HTMLCollection对象,包含了当前文档中所有<script>元素的集合;
document.all:只读属性,返回一个HTMLAllCollection,包含了页面上的所有元素;已从Web标准中删除,但是浏览器都支持,但建议不要使用;与document.getElementsByTagName(“*”)得到的结果基本相同的;
console.log(document.all); // HTMLAllCollection
console.log(document.getElementsByTagName("*")); // HTMLCollection
console.log(document.all[9]);
document.all[9].innerHTML="零点程序员";
// id或name为"mydiv"的元素,但是有区别的,为name的元素只是插入text
document.all["mydiv"].innerHTML="<h2>零点程序员</h2>";
以上这些集合始终都可以通过HTMLDocument对象访问到,而且,它们都是动态的;但现在已经被 document.getElementsByTagName()所取代,部分已经废弃不应该再使用,但是仍然常常被使用,因为他们使用起来很方便;
文档写入:
document对象,可以将文本字符串写入文档流中;
write()与writeln()方法:
这两个都接受一个字符串参数,即要写入到输出流中的文本;write()会原样写入,writeln()则会在字符串的末尾添加一个换行符(\n);
这两个方法会将其字符串参数连接起来,然后将结果字符串插入到文档中调用它们的脚本元素的位置;
document.write("<h1>" + document.title + "</h1>");
document.write("<strong>" + (new Date()).toString() + "</strong>");
不光输出内容,还会解析为DOM元素;
参数可以是多种形式,如:
// 部分替换为writeln()方法
var username="wangwei";
document.write("我的名字:" + username + "<br/>");
document.write("sum:" + (5 + 4));
document.write("<ul>");
document.write("<li>HTML</li>","<li>CSS</li>","<li>Javasc </li>");
document.write("</ul>")
var arr=["<p>zeronetwork</p>","<p>wangwei</p>","<p>web</p>"];
document.write(arr.join(""));
function func(){
return "func";
}
document.write(func + "<br>");
document.write(function(){
return "Happy";
}());
只有在解析文档时才能使用write()方法输出HTML到当前文本,如果把write()方法放到一个函数内或者在文档加载结束后再调用document.write(),那么输出的内容将会重写整个页面;如:
window.onload=function(){
document.write("零点程序员");
}
这里有个问题,理论上来说,重写了整个页面后,原页面中的所有变量和值都应该被清除,但事实却不是这样的,IE是这样的行为,但其他浏览器会保留原内容中的变量和值;
var num=10;
function fun(){
document.write("fun");
}
var mydiv=document.getElementById("mydiv");
window.onload=function(){
document.write("重写了整个页面");
console.log(num);
fun();
document.body.appendChild(mydiv);
}
正因为它们不兼容,所以不要在新文档流中调用原内容中的变量和值;
open()与close()方法:
可以使用write()方法在其他的窗口或框架页中来创建整个全新文档,但一般会配合close和open方法一起使用;
open()和close()分别用于打开和关闭网页的输出流;如果是在页面加载期间使用write()或writeln()方法,则不需要用到这两个方法,因为文档此时是打开状态;向一个已经加载完成的文档写入数据时,会自动调用 document.open,并且会擦除该文档的所有内容,因为已经加载完成的文档,它的文档流已经关闭,就是已经自动调用了document.close();
可以多次调用write()来逐步建立新文档的内容;传递给write的内容可能缓存起来,所以一旦完成了数据写入,建议调用 document.close()来结束该写序列,以告诉HTML解析器,文档已经达到了文件的末尾,写入的数据会被解析到文档结构模型(DOM)里,此时应该结束解析并显示新文档;
btn.onclick=function(){
document.open(); // 可以省略
document.write("重写了整个页面");
document.close();
}
此时,如果在close()方法后,再调用write()方法就会重写整个新窗口的内容,如:
// 在onclick事件处理函数中继续添加
document.write("文档又被重写了");
注意:无法关闭系统创建的文档流,如果,我们在全局环境中直接执行close()方法,会发现没有效果,原因就是无法关闭系统创建的文档流,我们只能关闭自己打开的文档流;
在新窗口也是同样的道理;
var oNewWin=window.open("about:blank","newwindow","width=400,width=200");
oNewWin.document.open();
oNewWin.document.write("<h1>新窗</h1>");
oNewWin.document.write("<div>这是一个新窗口</div>");
oNewWin.document.close();
在使用write()方法时,最好一次性写入;
<input type="button" id="btn" value="写入">
<script>
var newWin=null;
function makeNewWin(){
newWin=window.open("about:blank","newWin","width=400,height=300");
}
var btn=document.getElementById("btn");
btn.onclick=function(){
// 如果newWin不存在或已关闭,再次打开
if(!newWin || newWin.closed)
makeNewWin();
newWin.focus();
var title="零点程序员";
var newStr="<!DOCTYPE html>";
newStr +="<html><head>";
newStr +="<title>" + title + "</title></head>";
newStr +="<body>";
newStr +="<h1>零点程序员</h1>";
newStr +="<div>这是内容</div>";
// 把body拆分成</b和ody>,否则会抛出异常
newStr +="</b" + "ody></html>";
newWin.document.write(newStr);
newWin.document.close();
}
</script>
document.open()另类的用法:
2个参数的open()方法,语法为document.open(type, replace),如:
document.open("text/html","replace");
type指定了所需写入的数据的MIME类型,默认值为”text/html”,replace(如有设置,值为一个字符串“replace”)指定了新文档从父文档继承历史条目;
使用open()方法,在IE中会产生历史条目,其他浏览器不会产生,因此这种用法只会在IE中有效果;而如果指定了replace参数,IE就不会产生历史条目,也就是父文档的记录被覆盖了;
这种形式现在已经弃用;
3个参数的open()方法,是Window.open()的一个别名;
var doc=document.open("https://www.zeronetwork.cn/","","width=400;");// 打开新窗口
console.log(doc); // Window
doc.document.write("<h1>零点程序员</h1>"); // 重写
doc.document.close();
// doc.close(); // 会关闭窗口
动态加载外部资源:
使用write()和writeln()两个方法,还可以动态加载外部资源,如Javascript文件等,但要注意,不能直接包含字符串“</script>”,因为会导致代码不能正确的解析;
document.write("<script type=\"text/javascript\" src=\"file.js\">" + "<\/script>");
// 或者
document.write("<script type=\"text/javascript\" src=\"file.js\">" + "</scr" + "ipt>");
这种方法经常在广告和统计功能的第三方中使用;
为什么不直接使用<script>标签,而直接使用动态载入呢?原因有两个:
一是脚本的URL不能写死,比如要动态添加一些参数,用户设备的分辨率啊,当前页面 URL 啊,防止缓存的时间戳之类的,这些参数只能先用 JS 获取到,再比如国内常见的网站统计代码:
<script>
var cnzz_protocol=(("https:"==document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cspan id='cnzz_stat_icon_1279580898'%3E%3C/span%3E%3Cscript src='" +
cnzz_protocol + "s9.cnzz.com/stat.php%3Fid%3D1279580898' type='text/javascript'%3E%3C/script%3E"));
</script>
它之所以使用write()方法,而不使用<script>元素,就是为了先用 JS 判断出该用http还是https 协议;
另外,有可能需要在脚本里加载另外一个脚本文件或嵌入的JS内容有可能会修改页面内容,而这些操作只需要第三方自己维护,不需要自己的网站去维护;
在实际开发中,write()并不常用,innerHTML属性和其他DOM技术提供了更好的方法来为文档增内容;比如,可以利用innerHTML来输出内容:
var mydiv=document.getElementById("mydiv");
mydiv.innerHTML="<h1>零点程序员</h1><p>开设了Web前端课程</p>";
// 重写body内所有内容
document.body.innerHTML="<h1>零点程序员</h1><p>开设了Web前端课程</p>";
包装一个对象,类似于write()和close()方法:
// 为设置元素的innerHTML定义简单的"流式"API
function ElementStream(elt){
if(typeof elt==="string")
elt=document.getElementById("elt");
this.elt=elt;
this.buffer="";
}
// 连接所有的参数,添加到缓存中
ElementStream.prototype.write=function(){
this.buffer +=Array.prototype.join.call(arguments, "");
};
// 类似write(),只是多增加了换行符
ElementStream.prototype.writeln=function(){
this.buffer +=Array.prototype.join.call(arguments, "") + "\n";
};
// 从缓存设置元素的内容,然后清空缓存
ElementStream.prototype.close=function(){
this.elt.innerHTML=this.buffer;
this.buffer="";
}
var mydiv=document.getElementById("mydiv");
var elt=new ElementStream(mydiv);
elt.write("<h1>零点程序员</h1>");
elt.writeln("<p>王唯</p>");
elt.close();
Web前端开发之Javascript-零点程序员-王唯
*请认真填写需求信息,我们会在24小时内与您取得联系。