- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
正在 SVGElements
上进行转换并发现了一些我不理解的东西。
基本上我正在尝试克隆现有的 SVGElement
使用cloneNode(true)
并使用 transform.baseVal.getItem(0).setMatrix()
更改其矩阵。只要我不记录新的SVGElement
,这一切都可以正常工作。使用console.log()
.
必须检查实际的控制台,而不是代码片段的内联输出。
;window.onload = function(){
var tSVG = document.querySelector('svg');
var tSVGElement = tSVG.querySelector('#AL > g');
var tSVGElement2 = tSVGElement.cloneNode(1);
var tMatrix2 = tSVGElement2.transform.baseVal.numberOfItems ? tSVGElement2.transform.baseVal.getItem(0).matrix : tSVGElement2.transform.baseVal.appendItem(tSVG.createSVGTransform()).matrix
console.log(1, tSVGElement2);
tMatrix2.e += 50;
tMatrix2.f += 50;
tSVGElement2.transform.baseVal.getItem(0).setMatrix(tMatrix2)
tSVGElement.parentNode.appendChild(tSVGElement2);
console.log(2, tSVGElement2);
};
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2253" width="811" height="661">
<g id="AL" class="Touchable">
<g transform="matrix(0.0736096,0,0,0.0736094,313.881,379.029)">
<g stroke-width=".39819491" transform="matrix(2.51133 0 0 2.51134 -239.06 -636.03)">
<rect width="397" height="397" x="95.790001" y="253.86" fill="#ccc" stroke="#000" stroke-width="1.19458485" stroke-miterlimit="3" ry="0" rx="0"></rect>
<path fill="#fff" d="M153.88 347.3H354.4v207.58H153.88z"></path>
<path fill="#010002" d="M202.2 395.8c-3.22-3.24-4.84-7.17-4.84-11.8 0-4.63 1.62-8.55 4.85-11.8 3.3-3.23 7.2-4.85 11.8-4.85 4.6 0 8.6 1.62 11.8 4.86 3.3 3.3 4.9 7.2 4.9 11.8 0 4.6-1.6 8.6-4.8 11.8-3.2 3.3-7.1 4.9-11.8 4.9-4.7 0-8.5-1.6-11.8-4.8zm-21.32 79.6c1.04.8 2.26 1.22 3.64 1.22 1.4 0 2.6-.4 3.65-1.22 1.04-.8 1.56-2.13 1.56-3.98v-45.1c0-.7.34-1.16 1.04-1.4.7-.22 1.27-.33 1.73-.33.46 0 1.04.1 1.74.3.7.2 1.04.7 1.04 1.4V530c0 2.1.75 3.83 2.25 5.2 1.5 1.4 3.3 2.1 5.38 2.1s3.9-.7 5.4-2.1c1.5-1.37 2.3-3.1 2.3-5.2v-63.46c0-1.16.5-1.9 1.4-2.26.9-.36 1.6-.53 2.1-.53s1.1.18 1.9.52c.8.34 1.2 1.1 1.2 2.25V530c0 2.08.8 3.8 2.3 5.2 1.5 1.4 3.3 2.08 5.4 2.08 2.3 0 4.2-.7 5.6-2.07 1.4-1.4 2.1-3.1 2.1-5.2l.4-103.7c0-.7.4-1.1 1.1-1.4.7-.2 1.3-.3 1.78-.3.5 0 1.05.1 1.75.4.7.3 1 .7 1 1.4v45.1c0 1.9.5 3.2 1.55 4 1 .8 2.2 1.2 3.45 1.2s2.4-.4 3.46-1.2c1.03-.8 1.55-2.1 1.55-4v-47.9c0-4.6-1.54-8.8-4.66-12.5-3.15-3.7-7.37-5.5-12.7-5.5h-36.5c-5.3 0-9.2 1.9-11.6 5.6-2.44 3.7-3.65 7.8-3.65 12.5v47.8c0 1.9.5 3.2 1.53 4zm179.86-134.93c2.08 1.96 3.12 4.45 3.12 7.46v206.73c0 3-1.04 5.5-3.12 7.46-2.1 1.97-4.63 2.95-7.64 2.95H155.04c-3 0-5.55-.98-7.63-2.95-2-1.96-3.1-4.45-3.1-7.46V347.93c0-3 1.1-5.5 3.1-7.46 2.1-1.97 4.7-2.95 7.7-2.95h198c3 0 5.6.98 7.7 2.95zm-14.23 14.4H161.7v192.86h184.8V354.86zm-52.7 45.78c4.6 0 8.6-1.62 11.8-4.85 3.2-3.23 4.9-7.17 4.9-11.8 0-4.63-1.6-8.55-4.8-11.8-3.2-3.23-7.1-4.85-11.8-4.85-4.6 0-8.5 1.62-11.8 4.86-3.2 3.3-4.8 7.2-4.8 11.8 0 4.6 1.6 8.6 4.9 11.8 3.3 3.2 7.2 4.9 11.8 4.9zm-33.1 74.75c1.1.8 2.3 1.22 3.7 1.22 1.4 0 2.6-.4 3.7-1.22 1.1-.8 1.6-2.13 1.6-3.98v-45.1c0-.7.4-1.16 1.1-1.4.7-.22 1.3-.33 1.8-.33s1.1.1 1.8.3c.7.2 1.06.7 1.06 1.4V530c0 2.1.75 3.83 2.25 5.2 1.5 1.4 3.3 2.1 5.4 2.1 2.08 0 3.87-.7 5.38-2.1 1.5-1.37 2.27-3.1 2.27-5.2v-63.46c0-1.16.43-1.9 1.4-2.26.9-.35 1.6-.53 2.1-.53s1.1.18 2 .52c.95.34 1.4 1.1 1.4 2.25V530c0 2.08.7 3.8 2.1 5.2 1.4 1.4 3.24 2.08 5.56 2.08 2.1 0 3.9-.7 5.4-2.07 1.5-1.4 2.26-3.1 2.26-5.2V426.3c0-.7.3-1.16 1-1.4.7-.22 1.25-.33 1.7-.33.46 0 1.03.1 1.73.32s1.02.7 1.02 1.4v45.1c0 1.8.5 3.1 1.56 3.9 1.05.8 2.27 1.2 3.65 1.2 1.4 0 2.6-.4 3.65-1.2 1.04-.8 1.56-2.2 1.56-4v-47.8c0-4.7-1.6-8.8-4.84-12.5-3.25-3.7-7.53-5.6-12.84-5.6H275c-5.3 0-9.26 1.8-11.8 5.5-2.55 3.7-3.8 7.8-3.8 12.5v47.8c0 1.8.5 3.1 1.54 4zm180.6 49.16h-15.6V472.7s.1-2.13-2.7-2.13h-23.7c-3.9 0-3.2 2.55-3.2 2.55v52.52h-16.8c-4.9 0-.4 4.27-.4 4.27l29.8 36.1s2.5 2.9 5.1.3c3.6-3.5 28.9-37.2 28.9-37.2s4.5-4.4-1.4-4.4zm-61.2-140.98h15.6v51.85s0 2.14 2.7 2.14H422c3.88 0 3.2-2.56 3.2-2.56v-52.5H442c4.9 0 .4-4.2.4-4.2l-29.87-36.1s-2.45-2.8-5.02-.3c-3.5 3.6-28.9 37.3-28.9 37.3s-4.5 4.5 1.5 4.5z"></path>
</g>
</g>
</g>
</svg>
预期输出:
<g transform="matrix(0.0736096 0 0 0.0736094 363.881 429.029)">..</g>
实际输出:
<g transform="matrix(0.0736096 0 0 0.0736094 363.881 429.029)" requiredExtensions="" systemLanguage="">..</g>
所以一旦我记录了克隆的 SVGElement
Chrome 添加了两个属性 requiredExtensions
和systemLanguage
, which leads to the element no being rendered 。一旦我删除 console.log(tSVGElement2);
在克隆上一切正常。
为什么 Chrome 在日志记录中添加这两个属性?IE11 也只将其添加到子元素上。
最佳答案
对于您的原因问题:
我为此提出了一个问题,经 chrome ( https://bugs.chromium.org/p/chromium/issues/detail?id=873470 ) 确认,似乎这是一个错误。原因是:
<小时/>I'd guess that this is caused by attribute synchronization, and the reason console.log triggers it is that it enumerates all properties and thus creates the tear-off/wrapper for systemLanguage/requiredExtensions - which in turn makes them require synching.
预编辑:似乎我对 namespace 不被继承的看法是错误的,一件有趣的事情是虽然 'requiredExtensions'
属性应该设置为“true”或不存在可供渲染的元素。这是 SVG 规范 @ 5.7.1 here 的一部分通常,该属性(与 systemLanguage
一起)在 switch
元素上设置。有趣的是,在主线程中控制台 cloned g 时,会添加此属性,其值 ""
会转换为 false,并最终导致元素不被渲染。
但是,如果您等待事件循环完成然后记录,则属性不存在,请参阅此 FIDDLE .
作为结论,如果您克隆 g 节点并控制台记录它而不将其附加到树中,则这些属性将出现并且元素将不会被渲染。虽然我不知道这是预期的行为还是错误。
解决方案
在行为得到解决之前,猴子修补appendChild,我必须使用微任务队列,因为显然属性是在调用appendChild期间添加的:
SVGGraphicsElement.prototype.appendChild = (function(append){
return function(node){
setTimeout(function(){
node.removeAttribute("requiredExtensions");
node.removeAttribute("systemLanguage");
},0);
return append.apply(this,arguments);
}
}(SVGGraphicsElement.prototype.appendChild));
http://jsfiddle.net/ibowankenobi/8s97ophj/
解决方案 2:
显然,您必须对其他修改 DOM 树的函数进行猴子修补,例如 inserNode 等。在这种情况下,突变观察器提供了更通用的解决方案。您可以与不同的 parent 一起观看多次,同一观察者被回收:
function watch(node,parentNode){
var config = watch._config,
callback = function(list,observer){
list.forEach(function(d,i){
if(d.type !== "childList"){return}
if(
Array.prototype.slice.call(d.addedNodes)
.some(function(d,i){
return d === node
})
) {
console.log("added??");
setTimeout(function(){
node.removeAttribute("requiredExtensions");
node.removeAttribute("systemLanguage");
},0);
observer.disconnect();
}
})
},
observer = node._observer || (node._observer = new MutationObserver(callback));
observer.observe(parentNode,config);
return node;
}
watch._config = {childList:true,subtree:true};
使用:
var tSVG = document.querySelector('svg');
var tSVGElement = tSVG.querySelector('#AL > g');
var tSVGElement2 = tSVGElement.cloneNode(1);
watch(tSVGElement2,tSVGElement.parentNode/*Or tSVG since subtree:true*/);
....
一旦进入 DOM,观察者就会断开连接,属性也会被删除,如果需要,您可以修改函数并提供要更改的属性列表。查看此工作 FIDDLE
<小时/>~~发生这种情况是因为您没有克隆整个 svg
,而是克隆 g
,此时 xmlns
尚未定义这个 g
因为它从它的 ownerSVG
继承了它。当您将其附加到其父 svg
时,浏览器就会知道它是 SVG 的一部分。如果您在 tSVGElement.parentNode.appendChild(tSVGElement2)
之后控制台日志,它应该输出正常。~~
关于javascript - Chrome 在记录克隆的 SVGElement 时添加属性 [requiredExtensions, systemLanguage],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51785795/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 3 年前。 Improv
我是一名优秀的程序员,十分优秀!