好的,所以我使用外部 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 中它严重失败,控制台显示:
<![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 中。
最佳答案
您的问题是由于使用方法 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/