jsdom 中文文檔(純翻譯)

jsdom是一個地道由 javascript 完成的一系列 web範例,迥殊是 WHATWG 組織制訂的DOMHTML 範例,用於在 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.locationdocument.URLdocument.documentURI來返回,並會影響文檔中相干URL的剖析以及獵取子資本時運用的同源限定和referrer。默許值為"about:blank"
  • referrer 僅僅影響document.referrer的值。默許沒有援用(即為空字符串)。
  • contentType 影響document.contentType的值,是依據HTML剖析文檔照樣 XML來剖析。它的值如果不是text/htmlXML 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剖析器不支撐位置信息。

請注意urlreferrer在運用之前已被範例化了,比方
如果你傳入"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.evalrunScripts: "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 對象檢索而來
virtualConsolecookieJar:能夠傳入或許運用默許值

經由過程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",申明此功用未完成,而且沒有任何變化,也將不會有新的WindowDocument對象,而且現有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.locationdocument.URL`和document.documentURI,以及文檔中相對URL的剖析以及同源搜檢和提取子資本時運用的援用。然則,它不會實行導航到該URL的內容;DOM的內容將對峙穩定,而且不會建立WindowDocument`等新的實例。

方便的 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組織函數的選項類似,但具有以下分外的限定和效果:

  • urlcontentType 參數不能被供應
  • referrer 選項用作初始要求的HTTP Referer要求頭
  • userAgent 選項用作任何要求的HTTP User-Agent要求頭
  • 天生的jsdom的urlcontentTypereferrer是 由 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實例及其一切相干的功用。您以至能夠不須要WindowDocument!相反,你只須要剖析一些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.

fragDocumentFragment的實例對象,其內容是經由過程供應的字符串剖析建立的。剖析是經由過程運用<template>元素完成的,因而您能夠在个中包括任何元素(包括具有新鮮剖析劃定規矩的元素,如<td>)。

fragment()工場函數的一切挪用效果的DocumentFragments實例都邑同享雷同的DocumentWindow。這允很屢次挪用fragment()而沒有分外的開支。但這也意味着對fragment()的挪用不能用任何選項自定義。

請注意,對DocumentFragments的序列化並不像運用JSDOM對象那樣輕易。如果你須要序列化你的DOM,你應當直接運用JSDOM組織函數。但關於包括單個元素的片斷的迥殊狀況,經由過程通例要領就很輕易做到。

const frag = JSDOM.fragment(`<p>Hello</p>`);
console.log(frag.firstChild.outerHTML); // logs "<p>Hello</p>"

其他值得注意的功用

支撐 Canvas

jsdom支撐運用canvascanvas-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.setTimeoutwindow.setInterval設置)將在window高低文中實行代碼。因為歷程在不活潑的狀況下沒法實行將來的定時器代碼,所以卓着的jsdom定時器將對峙您的Node.js歷程處於運動狀況。一樣,對象不活潑的狀況下也沒有方法在對象的高低文中實行代碼,卓着的jsdom定時器將阻撓渣滓接納調理它們的window。

如果你想確保封閉jsdom窗口,運用window.close(),它將停止一切正在運轉的定時器(而且還會刪除 windowdocument上的任何事宜監聽器)。

在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的協助,請隨時運用以下任何體式格局:

  • 郵件組(題目最好以”how do i”的情勢)
  • 報iusse(最好用BUG 報告)
  • IRC頻道:#jsdom on freenode

迥殊聲明

以上文檔翻譯自開源項目 jsdom,若有翻譯毛病,迎接斧正。

jsdom 原文鏈接

jsdom 項目鏈接

jsdom 中文翻譯wiki鏈接

原文博客地址

    原文作者:frontmoment
    原文地址: https://segmentfault.com/a/1190000014844043
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞