DOM中的JavaScript移动元素


97

假设我<div>在页面上有三个元素。如何交换第一和第三的头寸<div>?jQuery很好。

Answers:


110

jQuery琐碎

$('#div1').insertAfter('#div3');
$('#div3').insertBefore('#div2');

如果要重复执行此操作,则需要使用其他选择器,因为div在移动时会保留其id。

$(function() {
    setInterval( function() {
        $('div:first').insertAfter($('div').eq(2));
        $('div').eq(1).insertBefore('div:first');
    }, 3000 );
});

1
@Ionut-关键在于它取决于元素的相对位置。更改顺序后,您将无法再通过其ID找到第一个和第三个,因此需要采用其他方法。我的回答仅是为了说明完成所请求任务的方法的功能,而不是将第一个和第三个div交换为任意次数的全面解决方案。
tvanfosson

大家好,一个简单的问题:上述jquery函数完成后,是否有一种简单的方法可将其重置回原始的Dom状态?
Vikita

@Vikita-是的,保存原始HTML,然后将其还原。如果已直接应用所有处理程序,而不是将它们委托给更高级别的元素,则可能必须重新应用它们。例如,var html = $('#container').html(); ...; $('#container').html(html);
tvanfosson

171

无需将库用于此类琐碎的任务:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[2].parentNode.insertBefore(divs[2], divs[0]); // order: third, first, second
divs[2].parentNode.insertBefore(divs[2], divs[1]); // order: third, second, first

这考虑到getElementsByTagName返回一个实时的NodeList 的事实,该节点列表在被操作时会自动更新以反映DOM中元素的顺序。

您还可以使用:

var divs = document.getElementsByTagName("div");   // order: first, second, third
divs[0].parentNode.appendChild(divs[0]);           // order: second, third, first
divs[1].parentNode.insertBefore(divs[0], divs[1]); // order: third, second, first

如果您想尝试的话,还有其他各种可能的排列方式:

divs[0].parentNode.appendChild(divs[0].parentNode.replaceChild(divs[2], divs[0]));

例如 :-)


15
没错,但是很难与jQuery之类的工具所具有的优雅和可读性相提并论-更不用说开箱即用的增强功能了。
疯狂的乔Malloy

13
是的,但是谁只做这件事?
tvanfosson

1
...或页面上只有3个div
Ryan Florence

38
@everybody:最初的问题问如何在具有三个div的页面上交换第三和第一div。那就是我回答的问题。如果OP有一个更复杂的问题,他们应该已经提出了,他们会得到一个更复杂的答案;-)
NickFitz

26
如果有人在2014年寻找此内容,请考虑此答案。jQuery那时很有用,但现在不再有用了,因为浏览器是标准化的,因此无需添加80 kb的库即可完成这样的简单任务。另外,直到您尝试不使用jQuery才知道DOM的真正
含义

29

。之前和之后

使用现代香草JS!比以前更好/更干净的方式。无需引用父母。

const div1 = document.getElementById("div1");
const div2 = document.getElementById("div2");
const div3 = document.getElementById("div3");

div2.after(div1);
div2.before(div3);

浏览器支持 -截至20年7月,全球支持率达到94.23%


尚无Internet Explorer支持。
justnorris '17

11
您不必编写较少可维护的代码来支持旧版或不符合标准的浏览器上的人员。除非您在企业工作,否则很少有用户会错过
Gibolt

就可维护性而言,其他方法也同样有效,尤其是在包装良好的清洁功能时。我全都在写现代代码,但这是最前沿的。很高兴知道未来会怎样,但是就我不喜欢与IE相关的任何事情而言- 了解您的决定的影响很重要。在这种情况下-任何IE浏览器中损坏的Web应用程序。如果您还可以-太好了!我添加评论仅是为了通知任何使用Google搜索的人:)
justnorris

1
那么27%的用户是几个用户?我们正在谈论数百万!
SandRock '17

5
一年后,这个数字将接近10%。它主要是企业,政府和较旧的移动设备。这通常意味着非个人设备或技术倾向较低的用户。答案应该是前瞻性的,这样我们就不会在2009
陷入困境。– Gibolt

11
jQuery.fn.swap = function(b){ 
    b = jQuery(b)[0]; 
    var a = this[0]; 
    var t = a.parentNode.insertBefore(document.createTextNode(''), a); 
    b.parentNode.insertBefore(a, b); 
    t.parentNode.insertBefore(b, t); 
    t.parentNode.removeChild(t); 
    return this; 
};

并像这样使用它:

$('#div1').swap('#div2');

如果您不想使用jQuery,则可以轻松修改该函数。


5
var swap = function () {
    var divs = document.getElementsByTagName('div');
    var div1 = divs[0];
    var div2 = divs[1];
    var div3 = divs[2];

    div3.parentNode.insertBefore(div1, div3);
    div1.parentNode.insertBefore(div3, div2);
};

该功能可能看起来很奇怪,但是它严重依赖于标准才能正常运行。实际上,它的功能似乎比tvanfosson发布的jQuery版本更好,后者只进行了两次交换。

它依赖什么标准特性?

insertBefore在现有子节点refChild之前插入节点newChild。如果refChild为null,则在子级列表的末尾插入newChild。如果newChild是DocumentFragment对象,则将其所有子级以相同顺序插入refChild之前。如果newChild已经在树中,则首先将其删除。


0

上面提到的Jquery方法将起作用。您也可以使用JQuery和CSS。例如,在Div上应用class1和div2上应用class2(例如,每个css类在浏览器中提供特定位置),现在您可以使用jquery或javascript(将更改位置)


0

很抱歉撞到这个线程,我偶然发现了“交换DOM元素”问题,玩了一下

结果是一个jQuery原生的“解决方案”,看起来似乎非常漂亮(不幸的是,我不知道这样做时jQuery内部发生了什么)

代码:

$('#element1').insertAfter($('#element2'));

jQuery文档说insertAfter() 移动元素而不克隆它

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.