Удаление пустых текстовых нод работает только на верхнем уровне DOM
Имеется вот такая функция:
domNormalize = function ( element ) {
var childs = element.childNodes;
for ( var i = 0; i < childs.length; i++ ) {
if ( childs[i].nodeType != 3 ) {
domNormalize( childs[i] );
} else if ( childs[i].nodeType == 3 && /\s*/.test(childs[i].textContent || childs[i].innerText) ) {
childs[i].parentNode.removeChild( childs[i] );
}
}
return element.innerHTML;
};
Например, если написать domNormalize( document.body ); то будут удалены только те ноды, которые являются прямыми потомками BODY. Почему так происходит? В 5-й строчке ведь ясно написано, что если текущая нода — не текстовая, продолжать разбор дальше. |
да, не.вроде нормально работает же?
обходит все элементы. по крайней мере в FF |
Проверял только в Opera 10.6, сейчас в других браузерах проверю.
|
childNodes динамическая структура же, когда в цикле удаляешь элементы, length меняется
function normalize(element) {
var i, textNodes = [];
(function (element) {
var i, node, nodes = element.childNodes, length = nodes.length;
for (i = 0; i < length; i++) {
node = nodes[i];
if (node.nodeType == 3 && !node.nodeValue) {
textNodes.push(node);
} else if(node.hasChildNodes()) {
arguments.callee(node);
}
}
})(element);
for (i = 0; i < textNodes.length; i++) {
textNodes[i].parentNode.removeChild(textNodes[i]);
}
}
normalize(document.body);
И у текстовых узлов нет геттеров innerText и textContent |
ещё вариант ))) ...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script language="JavaScript" type="text/javascript">
domNormalize = function (c) {
var d = c.innerHTML;
(function (e) {
for (var b = e.childNodes, a = b.length - 1; a >= 0; a--) {
b[a].hasChildNodes() && arguments.callee(b[a]);
b[a].nodeType == 3 && /^\s+$/.test(b[a].data) && b[a].parentNode.removeChild(b[a])
}
})(c);
alert(d + "\n" + c.innerHTML)
};
window.onload=function(){domNormalize(document.body);};
</script>
</head>
<body>
<div> <div> <p> </p> <p> </p> </div> </div> 123
</body>
</html>
|
Octane,
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div> </div> <p> </p> <p> </p> 123
<script language="JavaScript" type="text/javascript">
alert( document.getElementsByTagName('div')[0].nextSibling ); // object text
function normalize(element) {
var i, textNodes = [];
(function (element) {
var i, node, nodes = element.childNodes, length = nodes.length;
for (i = 0; i < length; i++) {
node = nodes[i];
if (node.nodeType == 3 && !node.nodeValue) {
textNodes.push(node);
} else if(node.hasChildNodes()) {
arguments.callee(node);
}
}
})(element);
for (i = 0; i < textNodes.length; i++) {
textNodes[i].parentNode.removeChild(textNodes[i]);
}
}
normalize(document.body);
alert( document.getElementsByTagName('div')[0].nextSibling ); /// object text
</script>
</body>
</html>
Тестил под Opera. |
потому что строка, состоящая из пробелов - это true ;)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div> </div> <p> </p> <p> </p> 123
<script language="JavaScript" type="text/javascript">
alert( document.getElementsByTagName('div')[0].nextSibling ); // object text
function normalize(element) {
var children = element.childNodes;
var textNodes = [];
for( var i=0, n=children.length; i<n; i++ ){
var child = children[i];
if( isEmptyTextNode(child) )
textNodes.push( child );
else if( child.hasChildNodes() )
normalize(child);
}
for( var i=0, n=textNodes.length; i<n; i++ ){
var textNode = textNodes[i];
textNode.parentNode.removeChild( textNode );
}
function isEmptyTextNode( node ){
return node.nodeType == 3 &&
! node.nodeValue.replace(/\s+/, '');
}
}
normalize(document.body);
alert( document.getElementsByTagName('div')[0].nextSibling ); /// object text
</script>
</body>
</html>
Octane, зачем цикл в функцию заворачивать? |
Цитата:
|
Как вам нерекурсивный вариант, который базируется на регулярных выражениях?
var normalize=function normalize(htmlRoot){
if(!htmlRoot)
htmlRoot=document.documentElement;
htmlRoot.innerHTML=(htmlRoot.innerHTML+"").replace(/\b([ \t\n\r]){2,}\b/g,function(x,y){return y[0];}).replace(/[ \t\n\r]{2,}/g,"").replace(/>[ \t\n\r]*\b/g,">").replace(/\b[ \t\n\r]*</g,"<");
};
Первый реплейс делает пробелы между словами одиночными. Второй - удаляет все остальные множественные пробелы. Третий - удаляет пробелы после открытия тега. Четвертый - перед закрытием. Кстати, набор заменяемых символов можно подправить. |
Цитата:
А вы представляете последствия изменения innerHTML? |
| Часовой пояс GMT +3, время: 08:34. |