试图在this问题上使我的答案更加灵活:
function invertDivs(parentDiv) {
var first = document.getElementById(parentDiv).firstChild;
console.log(first);
var second = document.getElementById(parentDiv).lastChild;
console.log(second);
document.getElementById(parentDiv).insertBefore(second, first);
}
<div id="parent">
<div id="first">Div 1</div>
<div id="second">Div 2</div>
</div>
<button onclick="invertDivs('parent');">Invert Divs</button>
然而,div有时只是倒置,而不是总是。
初次点击按钮会在控制台上显示:
第二次点击:
经过一番点击后:
我对代码有什么问题感到困惑。我选择父div的第一个孩子,并为最后一个孩子做同样的事情。然后我只是在第一个div之前插入当前的第二个div。这是功能的结束。根据{{1}}函数的要求,它们也是父div的直接子节点。
答案 0 :(得分:5)
如评论中所述,firstChild
和lastChild
可以返回元素之间空白的文本节点。您可以使用firstElementChild
和lastElementChild
忽略这些内容。
function invertDivs(parentDiv) {
var first = document.getElementById(parentDiv).firstElementChild;
console.log(first);
var second = document.getElementById(parentDiv).lastElementChild;
console.log(second);
document.getElementById(parentDiv).insertBefore(second, first);
}
&#13;
<div id="parent">
<div id="first">Div 1</div>
<div id="second">Div 2</div>
</div>
<button onclick="invertDivs('parent');">Invert Divs</button>
&#13;
对于旧版浏览器可能需要的其他一些解决方法,请参阅element.firstChild is returning '<TextNode ...' instead of an Object in FF
答案 1 :(得分:3)
您没有考虑文字节点。在上面的HTML示例中,有5个节点。
[0] => TextNode
[1] => #first
[2] => TextNode
[3] => #second
[4] => TextNode
很明显,你不在乎这里的文本节点。你有很多选择。
一种选择是过滤掉所有文本节点。 (不能使用Array.prototype.filter方法,因为childNodes不是数组,而是NodeList)
这将为您提供仅包含DOM元素的数组。
function invertDivs(parentNodeId) {
var childElements = [],
parentNode = document.getElementById(parentNodeId);
//Filter out the child nodes that aren't elements.
//parentNode.childNodes is a NodeList, and not an array (even though it looks like one)
for (var i = 0; i < parentNode.childNodes.length; ++i) {
if (parentNode.childNodes[i].nodeType === 1)
childElements.push(parentNode.childNodes[i]);
}
parentNode.insertBefore(childElements[childElements.length - 1], childElements[0]);
}
&#13;
<div id="parent">
<div id="first">Div 1</div>
<div id="second">Div 2</div>
</div>
<button onclick="invertDivs('parent');">Invert Divs</button>
&#13;
另一个选择是使用更现代的DOM API属性:请参阅Barmar或GolezTrol的答案。如果观众支持IE9 +浏览器,它们的性能会更高。
答案 2 :(得分:1)
这不是随意的。如果我单击2次,将Div 2添加到列表的末尾,然后单击3次以在列表的末尾获得Div 1。这种模式重复。
原因是因为中间还有下一个节点。这是元素之间的空白。
要解决此问题,请使用children
属性。这将选择子元素(而不是节点)。
function invertDivs(parentDiv) {
var parent = document.getElementById(parentDiv);
var first = parent.children[0];
console.log(first);
var second = parent.children[parent.children.length-1];
console.log(second);
document.getElementById(parentDiv).insertBefore(second, first);
}
<div id="parent">
<div id="first">Div 1</div>
<div id="second">Div 2</div>
</div>
<button onclick="invertDivs('parent');">Invert Divs</button>
答案 3 :(得分:1)
您的问题的答案在Node.firstChild的MDN文档(https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild)中给出。如果您引用文档,您将理解为什么将#text作为第一个节点。