gpt4 book ai didi

javascript - 在初始页面加载后,是否可以通过某种方式将浏览器触发到 DOM 的 'rescue'?

转载 作者:可可西里 更新时间:2023-11-01 13:46:14 24 4
gpt4 key购买 nike

我最近意识到,虽然浏览器会在 DOM 的初始构造期间尝试从无效或损坏的 HTML 中“拯救”它,但在初始构造之后它似乎并不遵守有效的 HTML 规则.

举个例子:

button {
display: block;
}

img,
td > img {
border: 3px solid limegreen;
}

tr>img {
border-color: red;
}

table {
table-layout: fixed;
border-collapse: collapse;
}

td {
padding: 1em;
text-align: center;
vertical-align: middle;
border: 1px solid #000;
}
<table>
<tr>
<td>cell 1</td>
<!-- this was deliberately inserted into a bad
place (I already know it's wrong) -->
<img src="/image/92t7rs.png" />
<td>cell 2</td>
<td><img src="/image/92t7rs.png" /></td>
</tr>
</table>

JS Fiddle demo

在我当前使用的浏览器 Chrome 56、Opera 43、Edge 38、Firefox Developer Edition 53 和 Internet Explorer 11 中,我按预期看到以下内容,<img> 已从 <table> 元素中删除,因为它对 <img> 无效<table> 中的元素只能是 <th><td> 元素的子元素:

这符合预期,而且我直到最近才假设,这将是一致的行为,可以防止我们有意或无意地滥用 JavaScript 来创建无效的 DOM。

为了证明 JavaScript 显然愿意创建无效的 DOM,我们有以下内容,在页面加载时,第一个 <img><table> 中删除(如上和预期);尽管单击 <button> 将插入一个 <img> 元素作为所选 <td> 元素的下一个兄弟元素:

//
//
let image = document.createElement('img');
image.src = '/image/92t7rs.png'
document.querySelector('button').addEventListener('click', function() {
let cell = document.querySelector('td:first-child');
cell.parentNode.insertBefore(image.cloneNode(), cell.nextSibling);
});
button {
display: block;
}

img,
td > img {
border: 3px solid limegreen;
}

tr > img {
border-color: red;
}

table {
table-layout: fixed;
border-collapse: collapse;
}

td {
padding: 1em;
text-align: center;
vertical-align: middle;
border: 1px solid #000;
}
<button>add image inside a &lt;tr&gt; element (<strong>bad!</strong>)</button>
<table>
<tr>
<td>cell 1</td>
<img src="/image/92t7rs.png" />
<td>cell 2</td>
<td><img src="/image/92t7rs.png" /></td>
</tr>
</table>

JS Fiddle demo

点击 <button> ,再次在我当前所有的浏览器上(如上所述),给出以下内容:

如前所述,以上肯定是无效的 HTML,因为 <img><tr> 的直接后代,由 tr > img 的 CSS 规则选择以应用红色边框。

所以:是否有一种非破坏性(不破坏绑定(bind)的事件处理程序)方式,我们可以通过这种方式强制浏览器重复在页面加载时实现的任何“救援”方式,将插入的 <img> 移动到一个适当的“有效”地方?

最后,我更愿意将任何解决方案(如果可能的话)发布在 native DOM API 中,而不是 JavaScript 库中。一定要发布一个答案,显示使用库可能会容易得多,但只有以及 native DOM API 解决方案。

此外,作为进一步的补充,我不想模仿原生 DOM 的“拯救”——似乎有太多的边缘案例无法适应这种方法——但是只需触发“救援”。

最佳答案

重写 innerHTML 类模仿页面加载。通过重置 innerHTML,您可以强制浏览器执行与加载特定元素时相同的工作。

在函数 fix 中,我们获取了元素的 innerHTML 并将其放回原处,浏览器将自动修复它会在加载时修复的错误。

//
//
let image = document.createElement('img');
image.src = '/image/92t7rs.png'
document.querySelector('button').addEventListener('click', function() {
let cell = document.querySelector('td:first-child');
cell.parentNode.insertBefore(image.cloneNode(), cell.nextSibling);
});

function fix(selector) {
var elem = document.querySelector(selector);
elem.innerHTML = elem.innerHTML;
}
button {
display: block;
}

img,
td > img {
border: 3px solid limegreen;
}

tr > img {
border-color: red;
}

table {
table-layout: fixed;
border-collapse: collapse;
}

td {
padding: 1em;
text-align: center;
vertical-align: middle;
border: 1px solid #000;
}
<button>add image inside a &lt;tr&gt; element (<strong>bad!</strong>)</button>
<button onclick="fix('table')">Fix it Felix!</button>
<table>
<tr>
<td>cell 1</td>
<img src="/image/92t7rs.png" />
<td>cell 2</td>
<td><img src="/image/92t7rs.png" /></td>
</tr>
</table>

关于javascript - 在初始页面加载后,是否可以通过某种方式将浏览器触发到 DOM 的 'rescue'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42537317/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com