javascript - innerHTML 仅在 Chrome 中编码

标签 javascript html css svg

好的,所以我使用外部 svg 文件显示一些 svg,其中我有一些样式如下:

    <style type="text/css">
<![CDATA[
    .st1 {fill:#ffffff;stroke:#808080;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.5;stroke-width:0.75}
    .st2 {fill:#444444;font-family:Calibri;font-size:0.833336em;font-weight:bold}
    .st3 {fill:#f8eccc;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
    .st4 {fill:#444444;font-family:Calibri;font-size:0.75em;font-weight:bold}
]]>
</style>

我想像这样使用 javascript 添加一些样式:

    console.log("style innerHTML before :\n" + document.querySelector(elementOrSelector).contentDocument.querySelector("style").innerHTML);
    var styleContent = document.querySelector(elementOrSelector).contentDocument.querySelector("style").innerHTML;
    styleContent = styleContent.slice(0, styleContent.lastIndexOf("}") + 1) + "\n\t\trect:hover {fill:#698B89}\n\t]]>\n";
    document.querySelector(elementOrSelector).contentDocument.querySelector("style").innerHTML = styleContent;
    console.log("style innerHTML after :\n" + document.querySelector(elementOrSelector).contentDocument.querySelector("style").innerHTML);

它在 Firefox 中工作正常,我的控制台显示修改后的内部 HTML:

<![CDATA[
.st1 {fill:#ffffff;stroke:#808080;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.5;stroke-width:0.75}
.st2 {fill:#444444;font-family:Calibri;font-size:0.833336em;font-weight:bold}
.st3 {fill:#f8eccc;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
.st4 {fill:#444444;font-family:Calibri;font-size:0.75em;font-weight:bold}
rect:hover {fill:#698B89}
]]>

但在 Chrome 中它严重失败,控制台显示:

&lt;![CDATA[
.st1 {fill:#ffffff;stroke:#808080;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.5;stroke-width:0.75}
.st2 {fill:#444444;font-family:Calibri;font-size:0.833336em;font-weight:bold}
.st3 {fill:#f8eccc;stroke:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:0.75}
.st4 {fill:#444444;font-family:Calibri;font-size:0.75em;font-weight:bold}
rect:hover {fill:#698B89}
]]&gt;

所以我的<>设置不正确,我有 &lt;&gt;实体代替,这仅在 Chrome 中。

最佳答案

您的问题是由于使用方法 Element.innerHTML() 处理 DOM 节点时不同浏览器之间的差异引起的.这在检查 <style> 时变得很明显在任何操作发生之前的节点。该节点在所有浏览器中包含三个子节点:[text, cdata-section, text] .其中类型为 text 的两个节点只包含 cdata-section 周围的任何空格.

使用方法Element.innerHTML()将通过用更新的 <style> 替换它来在 FF 和 IE 中保留此 DOM 结构具有相同 DOM 子树结构的元素。然而,Chrome 将解析更新后的 styleContent字符串作为字符数据,只创建一个 text 类型的节点.自 <style>元素只允许字符数据内容 Chrome 似乎也转义了其中包含的任何标记。因此,您的 style之后将仅包含 Chrome 中的一个文本节点,这对进一步处理没有用。

我已经设置了一个 Plunk展示更强大的解决方案:

// Get style node.
var style = document.querySelector("object").contentDocument.querySelector("style");

// Extract CDATA-Section from style's childNodes.
var cdata = getCDATA(style.childNodes);

// Manipulate CDATA content.
var styleContent = cdata.textContent;
styleContent += "\n\t\tpath:hover {fill:#698B89;}";

// Update CDATA-section node.
cdata.textContent = styleContent;

function getCDATA(nodelist) {
    for (var i=0; i < nodelist.length; i++) {
        var node = nodelist.item(i);
        if (node.nodeType == Element.CDATA_SECTION_NODE) {
            return node;
        }
    }
}

这样做,您将获得对 cdata-section 类型节点的引用使您能够轻松操纵其 textContent .因为您没有使用 Element.innerHTML() 强制浏览器重建其 DOM 树的一部分。 <style> 的结构DOM 子树将在浏览器中保持不变,从而提供一致的结果。

关于javascript - innerHTML 仅在 Chrome 中编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30057394/

相关文章:

javascript - jQuery - 恢复删除的选择选项

javascript - HTML5 事件源 API 和 node.js |如何将流发送到正确的客户端?

javascript - 嵌套排序动态项目不折叠

html - 如何在 UIWebView 中显示 HTML 代码?

css - 如何为 IE 用户提供来自不同服务器的字体?

javascript - 如何使用异步 Node 库传递请求 header ?

html - CSS - nth-child() 例子

html - 在 html 源代码中使用外部字体

css - 在没有媒体查询的情况下,在表格行交叉的中心页面上锚定图像

html - 纯CSS响应式文字效果