Получите innerHTML результата svg-tag в undefined в IE
У меня возникли проблемы с получением html-содержимого svg-тега с помощью javascript в Internet Explorer.
Мой код javascript выглядит следующим образом:
console.log($('.icon')[0].innerHTML);
и мой тег в документе html:
<svg class="icon"><use>testing</use></svg>
Это хорошо работает в Chrome, Firefox и что у нас есть, но в Internet Explorer я остался с ошибкой undefined. Это моя смесь Javascript и jQuery?
Почему я не могу получить содержимое моего svg-тега? Я пробовал разные вещи, и часто я получаю "SCRIPT5007: невозможно установить свойство" innerHTML "из undefined или нулевую ссылку"
Помогите мне:) спасибо в привет!
Ответы
Ответ 1
В конце концов я нашел какое-то решение для этого. Возможно, хакерский путь? Но работает для меня по крайней мере.
Вместо того, чтобы получать исходный innerhtml, который я не могу в IE. Я пытаюсь получить каждый элемент node внутри моего svg-тега, сделав так:
var element = document.getElementsByTagName('svg')[0].childNodes;
for (i = 0; i < element.length; i++) {
if (element[i].nodeName != '#text') {
console.log(element[i]);
}
}
Ответ 2
Как насчет использования XMLSerializer. Получите элемент как-то, а затем сделайте это...
console.log(new XMLSerializer().serializeToString(element));
Ответ 3
В настоящее время Internet Explorer не поддерживает метод innerHTML
в SVG Elements. Тем не менее у нас есть проблема, открытая внутри, чтобы отслеживать наше рассмотрение этой функции. Тем временем я бы рассмотрел альтернативные решения, такие как InnerSVG polyfill, который предположительно работает в Internet Explorer 9 и новее.
Ответ 4
Следующий код предоставит вам содержимое в виде строки из данного SVG.
Он основан на отличном ответе Роберта Лонгсона.
const svgNode = document.getElementsByTagName('svg')[0];
const serializer = new XMLSerializer();
const svgContent = Array.prototype.map.call(
svgNode.childNodes,
(child) => serializer.serializeToString(child)
).join('');
Ответ 5
console.log($('.icon').parent().html());
отлично работает для меня в IE11.
Поставляемая строка начинается с объявления XML
<?xml version="1.0" encoding="iso-8859-1" ?>
который, по-видимому, обрабатывается как родительский элемент svg node.
Ответ 6
(function () {
var svg = document.createElementNS("http://www.w3.org/2000/svg","svg");
if(typeof svg["innerHTML"] !== "undefined") {
return;
}
var node = $('<script type="text/svg_template"></script>');
Object.defineProperty(SVGElement.prototype, 'innerHTML', {
get: function() {
try {
var childNode = this.firstChild;
while (childNode) {
node.append($.clone(childNode));
childNode = childNode.nextSibling;
}
return node.html();
} finally {
node.empty();
}
}
})
})();
set html use:
$(svg).html()
тест на IE11
Ответ 7
В качестве обходного пути вы можете добавить элемент SVG во временный DIV, взять внутренний html этого DIV и удалить тег открытия и закрытия SVG из этой строки.
let parentHtml = $('<div />').append($('svg')).html();
let svgInner = parentHtml.replace(/(<svg)([^<]*|[^>]*)/g, '').replace('</svg>', '');
alert(svgInner);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" height="100" width="100"
style="stroke:#ff0000; fill: #0000ff"/>
</svg>
Ответ 8
Для реальных тегов внутреннего содержимого вы можете использовать следующее:
function innerHTML(anySvgElement) {
var d = document.createElement('div');
d.appendChild(anySvgElement);
// Given all SVG tags contain only letters and no numbers, we can strip out the outer tag (the anySvgElement itself)
return d.innerHTML.replace(/<([a-z]+)[^>]+>(.*)(<\/\1>)/i, '$2')
}
Для текстового только внутреннего содержимого, используйте вместо этого node.textContent
.
Ответ 9
console.log($('.icon')[0].html());
jQuery сглаживает различия между браузерами.
Ответ 10
Почему бы не добавить свой собственный innerHTML в прототип, как показано ниже:
// 针对IE浏览器进行加强
if (_IE >= 9) {
var _innerHTML = {
get: function () {
var frame = document.createElement("div"), i;
for (i = 0; i < this.childNodes.length; i++) {
// 深度克隆,克隆节点以及节点下面的子内容
frame.appendChild(this.childNodes[i].cloneNode(true));
}
return frame.innerHTML;
},
set: function (svgstring) {
var frame = document.createElement("div"), i;
frame.innerHTML = svgstring;
var toSvgNode = function (htmlNode) {
var svgNode = document.createElementNS(_namespace.svg, (htmlNode.tagName + "").toLowerCase());
var attrs = htmlNode.attributes, i, svgNodeClay = clay(svgNode);
for (i = 0; attrs && i < attrs.length; i++) {
svgNodeClay.attr(attrs[i].nodeName, htmlNode.getAttribute(attrs[i].nodeName));
}
return svgNode;
};
var rslNode = toSvgNode(frame.firstChild);
(function toSVG(pnode, svgPnode) {
var node = pnode.firstChild;
if (node && node.nodeType == 3) {
svgPnode.textContent = pnode.innerText;
return;
}
while (node) {
var svgNode = toSvgNode(node);
svgPnode.appendChild(svgNode);
if (node.firstChild) toSVG(node, svgNode);
node = node.nextSibling;
}
})(frame.firstChild, rslNode);
this.appendChild(rslNode);
}
};
Object.defineProperty(SVGElement.prototype, 'innerHTML', _innerHTML);
Object.defineProperty(SVGSVGElement.prototype, 'innerHTML', _innerHTML);
}