jsdom是一個地道由 javascript 完成的一系列 web範例,迥殊是 WHATWG 組織制訂的DOM和 HTML 範例,用於在 nodejs 中運用。大體上來講,該項目的目的是模仿充足的Web瀏覽器子集,以便用於測試和發掘實在天下的Web應用順序。
最新版本的 jsdom 運轉環境須要 node.js v6或許更高的版本。(jsdom v10以下版本在 nodejs v4以下依然可用,然則我們已不支撐保護了)
v10版本的 jsdom 具有全新的 API(以下所述).舊的 API 如今依然支撐;細緻的參照文檔
基本用法
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
為了運用 jsdom,重要用到jsdom主模塊的一個定名導出的 jsdom
組織函數。往組織器通報一個字符串,將會取得一個 jsdom 組織實例對象,這個對象有很多有用的屬性,迥殊是 window
對象:
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`);
console.log(dom.window.document.querySelector("p").textContent); // "Hello world"
(請注意,jsdom會像瀏覽器一樣剖析您通報的HTML,包括隱含的<html>
,<head>
和<body>
標記)
天生的對象是JSDOM類的一個實例,个中包括 window
對象在內的很多有用的屬性和要領。一般來講,它能夠用來從“外部”對jsdom舉行操縱,而這些操縱關於一般DOM API來講是不能夠的。關於不須要任何功用的簡樸場景,我們引薦運用類似的編碼情勢
const { window } = new JSDOM(`...`);
// or even
const { document } = (new JSDOM(`...`)).window;
下面是關於JSDOM類所能做的一切的完整文檔,在“JSDOM對象API”部份。
定製 jsdom
JSDOM組織函數接收第二個參數,能夠用以下體式格局定製您的jsdom。
簡樸選項
const dom = new JSDOM(``, {
url: "https://example.org/",
referrer: "https://example.com/",
contentType: "text/html",
userAgent: "Mellblomenator/9000",
includeNodeLocations: true
});
-
url
設置的值能夠經由過程window.location
,document.URL
和document.documentURI
來返回,並會影響文檔中相干URL的剖析以及獵取子資本時運用的同源限定和referrer。默許值為"about:blank"
。 -
referrer
僅僅影響document.referrer
的值。默許沒有援用(即為空字符串)。 -
contentType
影響document.contentType
的值,是依據HTML剖析文檔照樣 XML來剖析。它的值如果不是text/html
或XML mime type
值的話將會拋出異常。默許值為"text/html"
。 -
userAgent
影響navigator.userAgent
的值以及要求子資本時發送的User-Agent
頭。默許值為Mozilla / 5.0($ {process.platform})AppleWebKit / 537.36(KHTML,如Gecko)jsdom / $ {jsdomVersion}
。 - includeNodeLocations 保存由HTML剖析器天生的位置信息,許可您運用
nodeLocation()
要領(以下所述)檢索它。
它還能確保在<script>
元素內運轉的代碼的異常客棧跟蹤中報告的行號是準確的。
默許值為false
以供應最好機能,而且不能與XML內容範例一同運用,因為我們的XML剖析器不支撐位置信息。
請注意,url
和referrer
在運用之前已被範例化了,比方
如果你傳入"https:example.com"
,jsdom會自動範例化詮釋為"https://example.com/"
。
如果你通報了一個不可剖析的URL,該挪用將拋出毛病。
(URL依據URL範例舉行剖析和序列化。)
實行劇本
jsdom最壯大的功用是它能夠在jsdom中實行劇本。這些劇本能夠修正頁面的內容並接見jsdom完成的一切Web平台API。
然則,這在處置懲罰不可托內容時也異常風險。
jsdom沙箱並不是十拿九穩的,在DOM的<script>
內部運轉的代碼如果充足深切,就能夠接見Node.js環境,從而接見您的盤算機。
因而,默許狀況下,實行嵌入在HTML中的劇本的功用是禁用的:
const dom = new JSDOM(`<body>
<script>document.body.appendChild(document.createElement("hr"));</script>
</body>`);
// 劇本默許將不能實行:
dom.window.document.body.children.length === 1;
要在頁面內啟用劇本,能夠運用runScripts:"dangerously"
選項:
const dom = new JSDOM(`<body>
<script>document.body.appendChild(document.createElement("hr"));</script>
</body>`, { runScripts: "dangerously" });
// 劇本將實行並修正 DOM:
dom.window.document.body.children.length === 2;
我們再次強調只要在供應給jsdom的代碼是你已曉得是平安的代碼時方可運用它。如果您運轉了恣意用戶供應的或Internet上的不可托的Node.js代碼,能夠會危及您的盤算機。
如果你想經由過程<script src="">
來實行外部劇本,你須要確保已加載了它們。為此,請增加選項resources:"usable"
以下所述。
請注意,除非runScripts
設置為"dangerously"
,不然事宜處置懲罰順序屬性(如<div onclick =“”>
)也將不起作用。(然則,事宜處置懲罰函數屬性,比方div.onclick = ...
,將疏忽runScripts
參數 而且會起作用)
如果您只是試圖從“外部”實行劇本,而不是經由過程<script>
元素(和內聯事宜處置懲罰順序)從內部運轉“,則能夠運用runScripts: "outside-only"
選項,該選項會啟用window.eval
:
const window = (new JSDOM(``, { runScripts: "outside-only" })).window;
window.eval(`document.body.innerHTML = "<p>Hello, world!</p>";`);
window.document.body.children.length === 1;
因為機能緣由,默許狀況下會封閉此功用,但能夠平安啟用。
請注意,我們強烈發起不要試圖經由過程將jsdom和Node全局環境夾雜在一同(比方,經由過程實行global.window = dom.window)來“實行劇本”,然後在Node全局環境中實行劇本或測試代碼。相反,您應當像看待瀏覽器一樣看待jsdom,並運用window.eval
或runScripts: "dangerously"
來運轉須要接見jsdom環境內的DOM的一切劇本和測試。比方,這能夠須要建立一個browserify包作為<script>
元素實行 – 就像在瀏覽器中一樣。
末了,關於高等用例,您能夠運用dom.runVMScript(劇本)要領,以下所述。
偽裝成一個視覺瀏覽器
jsdom沒有襯着可視內容的才,而且默許狀況下會像無頭瀏覽器一樣事情。它經由過程API(如document.hidden)向網頁供應提醒,表明其內容不可見。
當pretendToBeVisual
選項設置為true時,jsdom會偽裝它正在顯現並顯現內容。它是如許做的:
- 變動
document.hidden
以返回false而不是true - 變動
document.visibilityState
以返回“visible”而不是“prerender” - 啟用
window.requestAnimationFrame()
和window.cancelAnimationFrame()
要領,不然不存在
const window = (new JSDOM(``, { pretendToBeVisual: true })).window;
window.requestAnimationFrame(timestamp => {
console.log(timestamp > 0);
});
請注意,jsdom依然不做任何規劃或襯着,因而這實際上只是偽裝為可視化,而不是完成真正的可視化Web瀏覽器將完成的部份。
加載子資本
默許狀況下,jsdom不會加載任何子資本,如劇本,款式表,圖象或iframe。如果您願望jsdom加載這些資本,則能夠通報resources: "usable"
選項,該選項將加載一切可用資本。資本列表以下:
- frame 和 iframe,經由過程
<frame>
和<iframe>
完成 - 款式,經由過程
<link rel="stylesheet">
- 劇本,經由過程
<script>
,然則前提是runScripts: "dangerously"
設置了 - 圖片,經由過程
<img>
,然則前提是canvas
(或許canvas-prebuilt
) npm 包已裝置
將來,我們設計經由過程此選項供應更多的資本加載定製,但如今只供應的兩種情勢:'default'
和 'usable'
。
假造掌握台
像網頁瀏覽器一樣,jsdom也具有“掌握台”的觀點。經由過程在文檔內實行的劇本以及來自jsdom自身完成的信息和紀錄會從頁面直接發送過來。我們將用戶可掌握的掌握台稱為“假造掌握台”,以便將其與Node.js console API和頁面內部的window.console API辨別開來。
默許狀況下,JSDOM組織函數將返回一個具有假造掌握台的實例,該假造掌握台將其一切輸出轉發到Node.js掌握台。為了建立本身的假造掌握台並將其通報給jsdom,能夠經由過程實行下面代碼來掩蓋此默許值
const virtualConsole = new jsdom.VirtualConsole();
const dom = new JSDOM(``, { virtualConsole });
如許的代碼將建立一個沒有任何行動的假造掌握台。您能夠為一切能夠的掌握台要領增加事宜偵聽器來為其供應行動:
virtualConsole.on("error", () => { ... });
virtualConsole.on("warn", () => { ... });
virtualConsole.on("info", () => { ... });
virtualConsole.on("dir", () => { ... });
// ... etc. See https://console.spec.whatwg.org/#logging
(請注意,最幸虧挪用 new JSDOM()
之前設置這些事宜偵聽器,因為在剖析時期能夠會發作毛病或掌握台挪用劇本毛病。)
如果你只是想將假造掌握台輸出重定向到另一個掌握台,比方默許的Node.js,你能夠如許做
virtualConsole.sendTo(console);
另有一個迥殊的事宜,"jsdomError"
,它的觸發將經由過程毛病對象來紀錄jsdom自身的毛病。這與毛病音訊在Web瀏覽器掌握台中的顯現體式格局類似,縱然它們不是由console.error輸出的。到現在為止,毛病會依據下面的體式格局輸出:
- 加載或剖析子資本時失足(劇本,款式表,frames和iframe)
- 不是由
window onerror
事宜處置懲罰順序處置懲罰的劇本實行毛病,它將會返回true或挪用event.preventDefault() - 因為挪用jsdom沒有完成的要領而致使的毛病,比方window.alert,兼容性的 web 瀏覽器都完成了這些要領
如果您運用sendTo(c)
將毛病發送給c,則默許狀況下,它將運用來自"jsdomError"
事宜的信息挪用console.error。如果您願望對峙事宜與要領挪用的嚴厲的一對一映照,而且能夠本身處置懲罰"jsdomError"
,那末您能夠實行
virtualConsole.sendTo(c, { omitJSDOMErrors: true });
Cookie jars(存儲Cookie的容器)
像網頁瀏覽器一樣,jsdom也具有cookie jar的觀點,存儲HTTP cookie 。在文檔的同一個域上一個URL,而且沒有標記為HTTP only
的cookies,能夠經由過程document.cookie
API來接見。另外,Cookie jar中的一切cookie都邑影響子資本的http加載。
默許狀況下,JSDOM組織函數將返回一個帶有空cookie的實例。要建立本身的cookie jar並將其通報給jsdom,能夠經由過程以下代碼來掩蓋默許值
const cookieJar = new jsdom.CookieJar(store, options);
const dom = new JSDOM(``, { cookieJar });
如果您想要在多個jsdoms中同享同一個cookie jar,或許提早運用特定的值來添補cookie jar,這將異常有用。
Cookie jar包由tough-cookie包供應的。jsdom.CookieJar
組織函數是tough-cookie cookie jar
的子類,而且默許設置了looseMode:true
選項,因為它更相符瀏覽器的行動體式格局。如果您想本身運用tough-cookie
的要領和類,則能夠運用jsdom.toughCookie
模塊導出來接見運用jsdom打包的tough-cookie
模塊實例。
在剖析之前舉行干涉干與
jsdom許可您在很早的時刻參与建立jsdom:建立Window和Document對象以後,但在剖析任何HTML並運用節點添補文檔之前:
const dom = new JSDOM(`<p>Hello</p>`, {
beforeParse(window) {
window.document.childNodes.length === 0;
window.someCoolAPI = () => { /* ... */ };
}
});
如果您願望以某種體式格局修正環境,這迥殊有用,比方增加jsdom不支撐的Web API的添補順序。
JSDOM object API
一旦你構建了一個JSDOM對象,它將具有以下有用的功用:
Properties
window
屬性: window
對象的key 從Window
對象檢索而來virtualConsole
和cookieJar
:能夠傳入或許運用默許值
經由過程serialize()
序列化document
const dom = new JSDOM(`<!DOCTYPE html>hello`);
dom.serialize() === "<!DOCTYPE html><html><head></head><body>hello</body></html>";
// Contrast with:
dom.window.document.documentElement.outerHTML === "<html><head></head><body>hello</body></html>";
經由過程nodeLocation(node)
獵取 dom 節點的源位置信息
nodeLocation()
要領將查找DOM節點在源文檔中的位置,並返回節點的parse5位置信息:
const dom = new JSDOM(
`<p>Hello
<img src="foo.jpg">
</p>`,
{ includeNodeLocations: true }
);
const document = dom.window.document;
const bodyEl = document.body; // implicitly created
const pEl = document.querySelector("p");
const textNode = pEl.firstChild;
const imgEl = document.querySelector("img");
console.log(dom.nodeLocation(bodyEl)); // null; it's not in the source
console.log(dom.nodeLocation(pEl)); // { startOffset: 0, endOffset: 39, startTag: ..., endTag: ... }
console.log(dom.nodeLocation(textNode)); // { startOffset: 3, endOffset: 13 }
console.log(dom.nodeLocation(imgEl)); // { startOffset: 13, endOffset: 32 }
請注意,只要您設置了includeNodeLocations
選項才運用此功用;因為機能緣由,節點位置默許為封閉。
運用runVMScript(script)
運轉vm建立的劇本
Node.js的內置vm模塊許可您建立Script
實例,這些劇本實例能夠提早編譯,然後在給定的“VM高低文”上運轉屢次。在這個場景背地,jsdom Window
是一個肯定的VM高低文。要接見此功用,請運用runVMScript()
要領:
const { Script } = require("vm");
const dom = new JSDOM(``, { runScripts: "outside-only" });
const s = new Script(`
if (!this.ran) {
this.ran = 0;
}
++this.ran;
`);
dom.runVMScript(s);
dom.runVMScript(s);
dom.runVMScript(s);
dom.window.ran === 3;
這是高等功用,除非您有迥殊的需求,不然我們發起對峙運用一般的DOM API(如window.eval()或document.createElement(“script”))。
經由過程reconfigure(settings)
重新設置jsdom
window.top
屬性在範例中被標記為Unforgeable,這意味着它是一個不可設置的私有屬性,因而在jsdom內運轉的一般代碼是不能掩蓋或遮擋它的,縱然運用Object.defineProperty
。
一樣,現在在jsdom中是不能夠處置懲罰navigation
相干信息的(比方設置window.location.href ="https://example.com/"
);如許做會致使假造掌握台發出"jsdomError"
,申明此功用未完成,而且沒有任何變化,也將不會有新的Window
或Document
對象,而且現有window.location
對象仍對峙當前一切雷同的屬性值。
然則,如果您從 jsdom 窗口以外舉行演示,比方在一些建立jsdoms的測試框架中,能夠運用迥殊的reconfigure()
要領掩蓋个中的一個或兩個:
const dom = new JSDOM();
dom.window.top === dom.window;
dom.window.location.href === "about:blank";
dom.reconfigure({ windowTop: myFakeTopForTesting, url: "https://example.com/" });
dom.window.top === myFakeTopForTesting;
dom.window.location.href === "https://example.com/";
請注意,變動jsdom的URL將影響一切返回當前 document URL的API,比方window.location
,document.URL
`和document.documentURI,以及文檔中相對URL的剖析以及同源搜檢和提取子資本時運用的援用。然則,它不會實行導航到該URL的內容;DOM的內容將對峙穩定,而且不會建立
Window,
Document`等新的實例。
方便的 APIs
fromURL()
除了JSDOM組織函數自身以外,jsdom還供應了一個返回 Promise
的工場要領,用於經由過程URL構建一個jsdom實例
JSDOM.fromURL("https://example.com/", options).then(dom => {
console.log(dom.serialize());
});
如果URL有用且要求勝利,則onFullfilled
回調實行並返回JSDOM實例。任何URL重定向都將遵照其終究目的地。
fromURL()
供應的參數選項與供應給JSDOM組織函數的選項類似,但具有以下分外的限定和效果:
-
url
和contentType
參數不能被供應 -
referrer
選項用作初始要求的HTTP Referer要求頭 -
userAgent
選項用作任何要求的HTTP User-Agent要求頭 - 天生的jsdom的
url
和contentType
和referrer
是 由 http response來決議 - 任何經由過程HTTP Set-Cookie相應頭設置的cookie都存儲在jsdom的cookie jar中。一樣,已供應的cookie jar中的任何cookie都邑作為HTTP Cookie要求標頭髮送。
初始的要求並不能無窮定製到像request npm 包一樣的水平;fromURL()
旨在為大多數狀況供應方便的API。如果您須要更好地掌握初始要求,您應當本身實行它,然後手動運用JSDOM組織函數。
fromFile()
與fromURL()
類似,jsdom還供應了一個fromFile()
工場要領,用於從文件名構建jsdom
JSDOM.fromFile("stuff.html", options).then(dom => {
console.log(dom.serialize());
});
如果能夠翻開給定的文件,則onFullfilled
回調實行並返回JSDOM實例。和Node.js API一樣,文件名是相干於當前事情目次的。
fromFile()
供應的選項與供應給JSDOM組織函數的選項類似,但具有以下分外的默許值:
-
url
選項將默許為給定文件名相對應的文件URL,而不是"about:blank"
- 如果給定的文件名是以
.xhtml
或許.xml
為後綴的話,contentType
選項默許為"application/xhtml+xml"
;反之為"text/html"
。
fragment()
關於最簡樸的狀況,你能夠不須要一個完整的JSDOM實例及其一切相干的功用。您以至能夠不須要Window
或Document
!相反,你只須要剖析一些HTML片斷,並取得一個你能夠操縱的DOM
對象。為此,我們供應了fragment()
,它能夠從給定的字符串中建立一個DocumentFragment
:
const frag = JSDOM.fragment(`<p>Hello</p><p><strong>Hi!</strong>`);
frag.childNodes.length === 2;
frag.querySelector("strong").textContent = "Why hello there!";
// etc.
frag
是DocumentFragment
的實例對象,其內容是經由過程供應的字符串剖析建立的。剖析是經由過程運用<template>
元素完成的,因而您能夠在个中包括任何元素(包括具有新鮮剖析劃定規矩的元素,如<td>
)。
fragment()
工場函數的一切挪用效果的DocumentFragments
實例都邑同享雷同的Document
和Window
。這允很屢次挪用fragment()
而沒有分外的開支。但這也意味着對fragment()
的挪用不能用任何選項自定義。
請注意,對DocumentFragments
的序列化並不像運用JSDOM對象那樣輕易。如果你須要序列化你的DOM
,你應當直接運用JSDOM組織函數。但關於包括單個元素的片斷的迥殊狀況,經由過程通例要領就很輕易做到。
const frag = JSDOM.fragment(`<p>Hello</p>`);
console.log(frag.firstChild.outerHTML); // logs "<p>Hello</p>"
其他值得注意的功用
支撐 Canvas
jsdom支撐運用canvas或canvas-prebuilt包來擴大任何運用canvas API的<canvas>
元素。為了做到這一點,您須要將canvas
作為依靠項加入到您的項目中,和 jsdom
包並列。如果jsdom能夠找到canvas
包,它將運用它,然則如果它不存在,那末<canvas>
元素的行動就像<div>
一樣。
編碼嗅探
除了供應一個字符串外,JSDOM組織函數還支撐Node.js Buffer
或範例JavaScript二進制數據範例(如ArrayBuffer,Uint8Array,DataView等)的情勢供應二進制數據。當完成后,jsdom將從供應的字節舉行嗅探編碼
,就像瀏覽器掃描<meta charset>
標籤一樣。
這類編碼嗅探也適用於JSDOM.fromFile()
和JSDOM.fromURL()
。在後一種狀況下,就像在瀏覽器中一樣,任何與response相應一同發送的Content-Type
頭信息優先級更高。
請注意,在很多狀況下,供應字節這類體式格局能夠比供應字符串更好。比方,如果您試圖運用Node.js的buffer.toString('utf-8')
API,則Node.js將不會去除任何前導BOM。如果您將此字符串供應給jsdom,它會逐字詮釋,從而使BOM對峙穩定。但jsdom的二進制數據解碼代碼將剝離前導的BOM,就像瀏覽器一樣;在這類狀況下,直接供應buffer
將會取得想要的效果。
封閉一個jsdom
jsdom中定義的定時器(經由過程window.setTimeout
或window.setInterval
設置)將在window高低文中實行代碼。因為歷程在不活潑的狀況下沒法實行將來的定時器代碼,所以卓着的jsdom定時器將對峙您的Node.js歷程處於運動狀況。一樣,對象不活潑的狀況下也沒有方法在對象的高低文中實行代碼,卓着的jsdom定時器將阻撓渣滓接納調理它們的window。
如果你想確保封閉jsdom窗口,運用window.close()
,它將停止一切正在運轉的定時器(而且還會刪除 window
和document
上的任何事宜監聽器)。
在Web瀏覽器中運轉jsdom
運用browserify模塊,jsdom某些方面也支撐在Web瀏覽器中運轉。也就是說,在Web瀏覽器中,您能夠運用被browserify
模塊編譯過的jsdom去建立完整自力的一般JavaScript對象集,其表面和行動與瀏覽器的現有DOM對象異常類似,但完整自力於它們,也就是”假造DOM”!
jsdom的重要目的對象依然是Node.js,因而我們運用僅存在於最新Node.js版本(即Node.js v6 +)中的言語特徵功用。因而,在舊版瀏覽器能夠沒法一般事情。(縱然編譯也不會有多大協助:我們設計在jsdom v10.x的全部過程當中普遍運用Proxy
。)
值得注意的是,jsdom在web worker
中能很好的運轉。項目的開發者@lawnsea使這一功用點成為能夠,他宣布了一篇關於他的項目的論文,該論文就運用了這類才。
在Web瀏覽器中運轉jsdom時,並不是一切的事情都圓滿。有些狀況下,這是因為基本的前提限定(比方沒有文件體系接見),但有些狀況下也是因為我們沒有花充足的時候去舉行恰當的小調解。迎接人人來提BUG。
運用Chrome Devtools調試DOM
從Node.js v6最先,您能夠運用Chrome Devtools來調試順序。請參閱官方文檔相識怎樣運用。
默許狀況下,jsdom元素在掌握台中被花樣化為一般的舊JS對象。為了便於調試,能夠運用jsdom-devtools-formatter,它能夠讓你像真正的DOM元素一樣調試它們。
注意事項
異步劇本加載
運用jsdom時,開發者在加載異步劇本時常常碰到貧苦。很多頁面異步加載劇本,但沒法區分劇本什麼時刻完成,因而沒法曉得什麼時候是運轉代碼並搜檢天生的DOM構造的好時機。這是一個基本的限定;我們沒法展望網頁上的哪些劇本會做什麼,因而沒法告訴您劇本什麼時候加載終了。
這個題目能夠經由過程幾種要領來處理。如果您能掌握頁面邏輯,最好的要領是運用劇本加載器供應的機制來檢測什麼時候加載完成。比方,如果您運用像RequireJS如許的模塊加載器,代碼能夠以下所示:
// On the Node.js side:
const window = (new JSDOM(...)).window;
window.onModulesLoaded = () => {
console.log("ready to roll!");
};
<!-- Inside the HTML you supply to jsdom -->
<script>
requirejs(["entry-module"], () => {
window.onModulesLoaded();
});
</script>
如果您不能掌握該頁面,則能夠嘗試其他處理要領,比方輪詢搜檢特定元素是不是存在。有關更多細緻信息,請檢察#640中的議論,迥殊是@ matthewkastor的深入看法。
同享的組織函數和原型
現在,關於大多數Web平台API,jsdom在多個看似自力的jsdoms之間同享雷同的類定義。這將意味着,能夠會湧現以下狀況
const dom1 = new JSDOM();
const dom2 = new JSDOM();
dom1.window.Element.prototype.expando = "blah";
console.log(dom2.window.document.createElement("frameset").expando); // logs "blah"
這重如果出於機能和內存的緣由:如果在Web平台上每次建立jsdom時,建立一切類的零丁副本,開支將會相稱高貴。
只管如此,我們依然有興緻在有一天供應一個選項設置來建立一個“自力”的jsdom,但要捐軀一些機能。
新API中缺失的功用
與v9.x之前的舊版jsdom API比擬,新API明顯缺乏對資本加載的邃密掌握。先前版本的jsdom許可您設置request時運用的選項(既能夠用於初始要求,也能夠用於舊版本的JSDOM.fromURL()
和子資本要求)。他們還許可您掌握要求哪些子資本並將其應用於主文檔,以便您能夠下載款式表,但不下載劇本文件。末了,他們供應了一個可定製的資本加載器,能夠阻攔任何傳出的要求並用完整合成的response 相應來完畢。
以上這些功用還沒有在新的jsdom API中完成,只管我們也願望儘快將它們增加返來,但不幸的是,這須要相稱大的幕後事情去實行。
同時,請隨時運用舊的jsdom API來接見此功用。它一向處於支撐和保護中,但它不會取得新功用。舊的文檔位於lib/old-api.md
中。
未完成的Web平台部份
現在jsdom中有很多缺失的API,只管我們也想要在jsdom中增加新的功用並對峙最新的Web範例。請隨時為缺失的任何內容提交issue,但我們是一個很小而且勞碌的團隊,因而人人一同來提交 pull request能夠會更好。
除了我們還沒有具有的功用以外,另有兩個重要功用現在超出了jsdom的局限。這些是:
- Navigation:在點擊鏈接或賦值location.href或類似操縱時能夠變動全局對象和一切其他的對象。
- Layout:盤算CSS元素的視覺規劃的才,這會影響諸如
getBoundingClientRects()
或許諸如offsetTop
之類的屬性
現在,jsdom對某些功用的某些方面具有假造行動,比方操縱navigation
時向假造掌握台發送“未完成的”"jsdomError"
,或許為很多與規劃相干的屬性返回0。您一般能夠在代碼中處理這些限定,比方經由過程在爬網過程當中為每一個頁面建立新的JSDOM實例,或運用Object.defineProperty
變動種種與規劃相干的getter
和要領的返回值
請注意,雷同領域中的其他東西(如PhantomJS)確切支撐這些功用。在wiki上,我們有關於jsdom vs. PhantomJS的更完整的比較引見。
獵取協助
如果您須要jsdom的協助,請隨時運用以下任何體式格局:
迥殊聲明
以上文檔翻譯自開源項目 jsdom,若有翻譯毛病,迎接斧正。