يمكن لـ jsdom تشغيل نصوص مضمنة داخل علامة <head>
للمستند ، ولكن كيف تجعلها تشغل البرامج النصية المرتبطة في رأس المستند عبر <script src="">
؟
للخيارات التي أستخدمها:
{
url: url,
resources: 'usable',
runScripts: 'dangerously',
}
// index.js
const request = require('request')
const jsdom = require('jsdom')
const {JSDOM} = jsdom
const url = 'http://localhost:8000'
request(url, (error, response, body) => {
const options = {
url: url,
resources: 'usable',
runScripts: 'dangerously',
}
const dom = new JSDOM(body, options)
console.log(dom.window.document.body.children.length) // Expecting to see `1`
console.log(dom.window.document.body.innerHTML) // Expecting to see `<h1>Hello world</h1>`
})
// external.js
document.addEventListener('DOMContentLoaded', () => {
document.write('<h1>Hello world!</h1>')
})
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSDOM test</title>
<script src="external.js"></script>
</head>
<body>
</body>
</html>
أكمل مثال العمل الأدنى: https://github.com/cg433n/jsdom-test
المشكلة هنا هي أن DOMContentLoaded
حدث غير متزامن. أنت تقوم بتسجيل الدخول قبل أن تتاح له فرصة حدوث ذلك. أنت بحاجة إلى الانتظار حتى إطلاق النار ؛ عندها فقط سيحدث document.write()
.
ربما يجب أن يعمل شيء مثل هذا:
const dom = new JSDOM(body, options)
dom.window.document.addEventListener('DOMContentLoaded', () => {
// We need to delay one extra turn because we are the first DOMContentLoaded listener,
// but we want to execute this code only after the second DOMContentLoaded listener
// (added by external.js) fires.
setImmediate(() => {
console.log(dom.window.document.body.children.length) // Expecting to see `1`
console.log(dom.window.document.body.innerHTML) // Expecting to see `<h1>Hello world</h1>`
});
});
فهمت! أنتم يا رفاق رائعون - استمروا في العمل الجيد!
ملاحظة: سمتان من العرض التوضيحي أعلاه محفوفة بالمخاطر.
request
مستهلك. النتائج npm install request
في:setImmediate
محفوفًا بالمخاطر على المدى الطويل .بدلاً من ذلك ، أوصي باستخدام fs
لقراءة وتحميل أكواد js من الملفات ، راجع Stackoverflow بناءً على نهجEricRicketts ' FS.read()
في # 3023 و Domenic addEventListener()
في # 1914. يتضمن عرض العمل الذي أقترحه ما يلي:
fs.readFileSync
لتحميل js الخارجية إلى html كسلاسلمن المحتمل أن يمنعك هذا من إجراء مكالمات xhr / API وبالتالي يحل المشكلة جزئيًا فقط.
لم أستطع معرفة طريقة عمل عنوان url.
من الناحية المثالية ، سيكون موضع ترحيب حد أدنى محدث من JSDOM تحميل ملفات external.js عبر عرض عمل url . :قلب:
التعليق الأكثر فائدة
المشكلة هنا هي أن
DOMContentLoaded
حدث غير متزامن. أنت تقوم بتسجيل الدخول قبل أن تتاح له فرصة حدوث ذلك. أنت بحاجة إلى الانتظار حتى إطلاق النار ؛ عندها فقط سيحدثdocument.write()
.ربما يجب أن يعمل شيء مثل هذا: