У меня есть 4 сложные полилинии в SVG, содержащиеся в родительском элементе (myLines). Я хочу сохранить полилинии в массиве, чтобы вызывать их позже в моем коде. По какой-то причине браузер считает, что между полилиниями в родительском элементе «myLines» есть скрытые текстовые узлы. Когда я пытаюсь найти узлы в инспекторе с помощью инструментов разработчика, браузеры говорят, что «некоторые узлы были скрыты», имея в виду эти узлы.
Однако, когда я использую appendChild и перемещаю полилинии из одного элемента в другой, браузер обнаруживает только 4 полилинии, которые на самом деле существуют.
Что тут происходит?
Я придумал несколько обходных путей, чтобы избежать этой проблемы, но я бы предпочел знать, что происходит wtf, поэтому я действительно могу это исправить и узнать, что я сделал неправильно.
var main = document.querySelector('main');
var lines = main.querySelectorAll('g#myLines');
var element=document.getElementById("myLines2");
var elArray=[];
console.info(lines);
for (z=0; z<4; z++){
console.info("lines[0].childNodes["+z+"]= "+lines[0].childNodes[z]);
elArray[z]=(lines[0].childNodes[z]);
/* element.appendChild(lines[0].childNodes[z]); */
}
Пожалуйста, проверьте эту скрипку. Если вы посмотрите в консоль и включите этот код "element.appendChild(lines[0].childNodes[z]);" в строке 9 вы можете видеть, что текстовые узлы не отображаются с помощью appendChild. https://jsfiddle.net/NZSIL/8psru5mv/
Спасибо!!
Текстовые узлы относятся к пробелам (символам новой строки), которые присутствуют в вашем SVG-представлении между элементами polyline
.
Рассмотрим этот пример, где мы получаем ссылку на группу g1
и проверяем количество дочерних узлов. В этом примере будет напечатано 3
, ссылаясь на пробел перед элементом rect
(текстовый узел), сам элемент rect
(узел элемента) и пробел после элемента rect
(текстовый узел).
const group = document.getElementById('g1');
console.info(group.childNodes.length); // 3 nodes
<svg id = "svg1">
<g id = "g1">
<rect width = "100" height = "100"/>
</g>
</svg>
Напротив, приведенный ниже фрагмент кода будет считать дочерним узлом только элемент rect
, потому что между тегами g
и тегами rect
нет пробелов.
const group = document.getElementById('g1');
console.info(group.childNodes.length); // 1 node
<svg id = "svg1"><g id = "g1"><rect width = "100" height = "100"/></g></svg>
Распространенным решением для подобных случаев является отфильтровывание текстовых узлов и работа только с узлами элементов:
const group = document.getElementById('g1');
const nodes = [...group.childNodes];
console.info(nodes.length) // 3 nodes
const elements = nodes.filter(n => n.nodeType === Node.ELEMENT_NODE);
console.info(elements.length); // 1 element
<svg id = "svg1">
<g id = "g1">
<rect width = "100" height = "100"/>
</g>
</svg>
В приведенном выше фрагменте все узлы, не являющиеся узлами элементов (тип узла Node.ELEMENT_NODE
), отфильтровываются, в результате чего получается массив из одного элемента, содержащий узел rect
.
Чтобы повысить читаемость, вы можете использовать n.nodeType === Node.ELEMENT_NODE
Не уверен, что хорошо понимаю ваш вопрос, но я думаю, что эти скрытые текстовые узлы представляют собой пробелы, новые строки и/или вкладки, которые вы используете для форматирования html-кода, чтобы сделать его более читаемым. Когда вы добавляете элементы к некоторому родительскому элементу, этих вкладок, новых строк и пробелов нет, потому что элементы добавляются непосредственно друг за другом без форматирования кода.