Или есть способ обеспечить выполнение кода сценария содержимого после загрузки DOM, но до запуска сценариев страницы?
Проблема в том, что сценарии страницы могут выполняться до DOM полностью загружен. Например, ниже:
<div id="foo"></div>
<script>
foo.textContent = 'foo';
</script>
<div id="bar"></div>
скрипт будет запускаться до создания элемента bar
(до загрузки DOM).
Возможно найти все элементы с идентификаторами в настоящее время в DOM с [id]
, и можно переназначить эти свойства в окне, просто переназначив свойство - или, если вы хотите запустить код при получении элемента, вы можете использовать Object.defineProperty
для превратить его в добытчик. Вы должны быть в состоянии найти идентификаторы и переназначить их до загрузки сценариев, что может быть выполнено с помощью поддерева MutationObserver - непосредственно перед вставкой <script>
, итерации по [id]
s в DOM и переназначения их:
console.log('(empty JS block inserted by Stack Snippet editor)');
<script>
new MutationObserver((mutations) => {
// Check to see if a script was inserted
if (mutations.every(
mutation => [...mutation.addedNodes].every(
addedNode => addedNode.tagName !== 'SCRIPT'
)
)) {
// No scripts inserted
return;
}
console.log('id reassignment running');
for (const elm of document.querySelectorAll('[id]')) {
Object.defineProperty(window, elm.id, {
get() {
console.log('Custom code running');
return elm;
},
configurable: true
});
}
})
.observe(document.body, { childList: true, subtree: true });
</script>
<div id="foo"></div>
<script>
console.log('Lower script about to reference foo');
foo.textContent = 'foo';
console.log('Lower script has finished referencing foo');
</script>
<div id="bar"></div>
Может быть полезна некоторая полировка, но это общая идея.