使用阴影增强 SVG 标签 DOM
Augmenting SVG tag with Shadow DOM
我一直在试验 HTML5 和 SVG;而且我对 JavaScript 和网络开发还很陌生,所以我可能缺少一些东西。我正在尝试创建可重用的 Web 组件,利用一些新功能,例如 HTML Imports、Shadow DOM,并扩展现有的 Web 元素。我有两个 html 个文件:
test.html
<html>
<head>
<title>Test HTML5</title>
</head>
<body>
<link rel="import" href="Elements/tank.html">
<svg width="100%"
viewBox="0 0 500 500"
style="border: solid; border-width: thin; stroke-width: 2;">
<polyline points="0,300 100,300 100,100 250,100 250,150 500,150"
style="fill:none;stroke:black;stroke-width:3"
onclick="window.alert('you clicked line')" />
<svg is="my-tank" x="200" y="350" width="50" height="50"></svg>
</svg>
</body>
</html>
tank.html
<html>
<body>
<template id="tank">
<rect fill="red" width="50" height="50"></rect>
</template>
<script type="text/javascript">
var tankElement = document.currentScript.ownerDocument.querySelector('#tank');
document.registerElement('my-tank', {
prototype: Object.create(SVGSVGElement.prototype, {
createdCallback: {
value: function () {
var root = this.createShadowRoot();
//Works
root.innerHTML = tankElement.innerHTML;
//Doesn't work
//var tankTemplate = document.importNode(tankElement.content, true);
//root.appendChild(tankTemplate);
}
}
}),
extends: 'svg'
});
</script>
</body>
</html>
//Works
注释下的代码在我期望在 SVG 可绘制对象 space 中绘制了一个红色矩形。 //Doesn't work
下的代码不绘制任何内容或产生任何错误。
//Works
的屏幕截图:
//Doesn't work
的屏幕截图:
我一直在使用 Opera 41.0 进行测试。
您不能这样做,因为 svg
不能成为影子主机。只有有限数量的元素可以成为影子主机:
article
、aside
、blockquote
、body
、div
、footer
、h1
、h2
、h3
、h4
、h5
、h6
、header
、main
、nav
、p
, section
, span
.
所以不仅svg
,像input
或textarea
这样的其他人也不能有shadow-doms(我说的是Shadow-DOM v1).
详见attachShadow
的定义:https://dom.spec.whatwg.org/#dom-element-attachshadow
另请注意:
SVGSVGElement
没有实现 HTMLElement
。
- 还听说 SVG 在其实现中已经包含阴影-dom,并且带有自定义元素 v1
你可能只有一个影子-dom(见这里:http://hayato.io/2016/shadowdomv1/)。
你为什么不创建一个常规的自定义元素,它可能包含 <svg>
个元素在它的影子中-dom?
这是因为在您的 <template>
中,<rect>
元素不在 <svg>
标签内,所以它不会被识别为 SVGRectElement
,而是 HTMLUnknownElement
代替。
要让它工作,只需在周围添加 <svg>
标签:
<template id="tank">
<svg>
<rect fill="red" width="50" height="50"></rect>
</svg>
</template>
现在您可以使用 importNode()
或 cloneNode()
:
导入元素
//Works
var rect = tankElement.content.querySelector('rect').cloneNode();
root.appendChild(rect);
更新 导入多个 SVG 元素
将元素放入 <g>
:
<template id="tank">
<svg>
<g>
<rect fill="red" width="50" height="50"></rect>
<rect fill="blue" width="25" height="50"></rect>
</g>
</svg>
</template>
克隆 <g>
及其内容:
var g = tankElement.content.querySelector('g').cloneNode(true);
root.appendChild(g);
我一直在试验 HTML5 和 SVG;而且我对 JavaScript 和网络开发还很陌生,所以我可能缺少一些东西。我正在尝试创建可重用的 Web 组件,利用一些新功能,例如 HTML Imports、Shadow DOM,并扩展现有的 Web 元素。我有两个 html 个文件:
test.html
<html>
<head>
<title>Test HTML5</title>
</head>
<body>
<link rel="import" href="Elements/tank.html">
<svg width="100%"
viewBox="0 0 500 500"
style="border: solid; border-width: thin; stroke-width: 2;">
<polyline points="0,300 100,300 100,100 250,100 250,150 500,150"
style="fill:none;stroke:black;stroke-width:3"
onclick="window.alert('you clicked line')" />
<svg is="my-tank" x="200" y="350" width="50" height="50"></svg>
</svg>
</body>
</html>
tank.html
<html>
<body>
<template id="tank">
<rect fill="red" width="50" height="50"></rect>
</template>
<script type="text/javascript">
var tankElement = document.currentScript.ownerDocument.querySelector('#tank');
document.registerElement('my-tank', {
prototype: Object.create(SVGSVGElement.prototype, {
createdCallback: {
value: function () {
var root = this.createShadowRoot();
//Works
root.innerHTML = tankElement.innerHTML;
//Doesn't work
//var tankTemplate = document.importNode(tankElement.content, true);
//root.appendChild(tankTemplate);
}
}
}),
extends: 'svg'
});
</script>
</body>
</html>
//Works
注释下的代码在我期望在 SVG 可绘制对象 space 中绘制了一个红色矩形。 //Doesn't work
下的代码不绘制任何内容或产生任何错误。
//Works
的屏幕截图:
//Doesn't work
的屏幕截图:
我一直在使用 Opera 41.0 进行测试。
您不能这样做,因为 svg
不能成为影子主机。只有有限数量的元素可以成为影子主机:
article
、aside
、blockquote
、body
、div
、footer
、h1
、h2
、h3
、h4
、h5
、h6
、header
、main
、nav
、p
, section
, span
.
所以不仅svg
,像input
或textarea
这样的其他人也不能有shadow-doms(我说的是Shadow-DOM v1).
详见attachShadow
的定义:https://dom.spec.whatwg.org/#dom-element-attachshadow
另请注意:
SVGSVGElement
没有实现HTMLElement
。- 还听说 SVG 在其实现中已经包含阴影-dom,并且带有自定义元素 v1 你可能只有一个影子-dom(见这里:http://hayato.io/2016/shadowdomv1/)。
你为什么不创建一个常规的自定义元素,它可能包含 <svg>
个元素在它的影子中-dom?
这是因为在您的 <template>
中,<rect>
元素不在 <svg>
标签内,所以它不会被识别为 SVGRectElement
,而是 HTMLUnknownElement
代替。
要让它工作,只需在周围添加 <svg>
标签:
<template id="tank">
<svg>
<rect fill="red" width="50" height="50"></rect>
</svg>
</template>
现在您可以使用 importNode()
或 cloneNode()
:
//Works
var rect = tankElement.content.querySelector('rect').cloneNode();
root.appendChild(rect);
更新 导入多个 SVG 元素
将元素放入 <g>
:
<template id="tank">
<svg>
<g>
<rect fill="red" width="50" height="50"></rect>
<rect fill="blue" width="25" height="50"></rect>
</g>
</svg>
</template>
克隆 <g>
及其内容:
var g = tankElement.content.querySelector('g').cloneNode(true);
root.appendChild(g);