Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
上篇文章主要講了如何編寫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小時內與您取得聯系。