使用jQuery交换两个div的位置

37

我在想是否可以用jQuery来交换两个div的位置。

我有两个像这样的div:

<div class="div1">STUFF ONE</div>
<div class="div2">STUFF TWO</div>
如果div2有内容(或包含不只是空格),它会交换div1div2的顺序。 所以这个:
<div class="div1">STUFF ONE</div>
<div class="div2">STUFF TWO</div>

会变成这样:

<div class="div2">STUFF TWO</div>
<div class="div1">STUFF ONE</div>

但如果是这样的:

<div class="div1">STUFF ONE</div>
<div class="div2"></div>

或者这个:

<div class="div1">STUFF ONE</div>
<div class="div2">    </div>

它不会做任何事情。

而且...如果可能的话,如果切换了,我想添加一个类到div1

非常感谢任何帮助。

更新:

我忘记了要在同一页上运行多个实例。

每个实例的格式如下:

<div class="view-container"> 
  <div class="view-content"> 
   <div class="views-row">
     <div class="div1">STUFF ONE</div>
     <div class="div2">STUFF TWO</div>
   </div>
   <div class="views-row">
     <div class="div1">STUFF ONE</div>
     <div class="div2">STUFF TWO</div>
   </div>
  </div>
</div>
6个回答

49

我来提供我的解决方案。

$('.div2:parent').each(function () {
    $(this).insertBefore($(this).prev('.div1'));
});

编辑:此方法无法处理div2中的空格。这是更新后的解决方案:

$('.div2').each(function () {
    if (!$(this).text().match(/^\s*$/)) {
        $(this).insertBefore($(this).prev('.div1'));
    }
});

2
我真的很喜欢这个解决方案。非常极简主义。 - David Richard
1
这不会创建重复吗? - Lightness Races in Orbit
1
不是的。"如果用这种方式选择的元素被插入到其他地方,它将被移动到目标之前(而不是克隆)"。请参阅http://api.jquery.com/insertBefore/。 - Rusty Fausak
其实我并不理解这段代码,但它很棒。如果你能给我一些指引就太好了。 :) - Max
1
@KiranP。我知道这是6年前的事情,但我仍然尝试解释!$('.div2')是一个Jquery选择器,它选择具有类“div2”的每个元素-->使用.each可以迭代遍历每个元素并对其应用函数,在其中使用$(this)选择元素-->使用!$(this).text().match(/^\s*$/),当当前迭代的元素没有空格(->正则表达式)时返回true-->使用$(this).insertBefore($(this).prev('.div1'))将元素插入到括号中的元素之前,该元素是直接在元素本身之前的类为div1的元素 - lxg95
显示剩余2条评论

23

这是一个例子:

http://jsfiddle.net/52xQP/1/

首先,您需要克隆元素。然后,检查条件,如果div2为空,则进行交换:

div1 = $('#div1');
div2 = $('#div2');

tdiv1 = div1.clone();
tdiv2 = div2.clone();

if(!div2.is(':empty')){
    div1.replaceWith(tdiv2);
    div2.replaceWith(tdiv1);

    tdiv1.addClass("replaced");
}

4

1
我真的很喜欢那个分离方法。在这之前我从未听说过它。不错。 - David Richard

3
var row2content = $('.div2').html();                //Get row 2s content
row2contentnospaces = row2content.replace(' ', ''); //Eliminate whitespace
if(!(row2contentnospaces == '')){                   //Check if row2 is empty
    var row2 = $('.div2');                          //Get row 2
    $('.div2').remove();                            //remove row2
    $('.div1').before(row2);                        //add row 2 before row 1
}

谢谢@David。这看起来很棒。我忘了添加我必须在同一页上运行多个实例。这会改变什么吗? - Cybercampbell
假设他们一遍又一遍地使用相同的类名,那么是的,这会导致问题。为了解决这个问题,我会将每个配对放在一个div中,然后改变一些代码以查找兄弟元素。是否是这种情况? - David Richard
嗨@David。你对rfausak的解决方案有什么想法? - Cybercampbell
1
这是一个非常优雅的解决方案,我会选择它。 - David Richard

2

好的...为什么你要改变div元素的位置呢?这很重要吗?为什么不改变内容呢?

var divOneText = $('#div1').html();
var divTwoText = $('#div2').html();

if (divOneText != '' && divTwoText != '') {
  $('#div1').html(divTwoText);
  $('#div2').html(divOneText);
}

如果您想去除空格,请添加trim()。

嗨@Grrbrr404。我需要让类与内容保持相关。不过还是谢谢你的回复。 - Cybercampbell
然后也要更改CSS。这比切换整个元素要容易和快速。 - Grrbrr404
1
@Grrbrr404:我不同意。如果你知道你想要将div的所有内容互换,那么最可靠的方法就是交换节点本身。如果你创建一个白名单来确定要交换的内容,那么你可能会错过一些东西:即使现在没有问题,当标记发生变化时,以后也可能出现问题。 - Lightness Races in Orbit
2
我喜欢这个解决方案,比起“检查和复制非空格字符”的解决方案更好。简单而且有效! - trante

2

我找到了一个优雅的jQuery插件,只需4行代码就可以实现。 作者是Yannick Guinness

/**
 * Swap an element with another one
 * @author: Yannick Guinness
 * @version: 0.1
 *
 * @params {Object} element - object that has to be swapped
 * @return: {jQuery Object}
 *
 * @usage:
 *     $('.one').swap('.two');
 *
 * @license: MIT
 * @date: 2013/07/22
 **/
$.fn.swap = function (elem) {
    elem = elem.jquery ? elem : $(elem);
    return this.each(function () {
        $(document.createTextNode('')).insertBefore(this).before(elem.before(this)).remove();
    });
};

$('.one').on('click', function () {
    alert(true);
});

$('input').click(function () {
    $('.one').swap('.two');
});

在fiddle中运行

尽管@Vigront的回答简单而且很好(我已经点赞了),但是它有一个严重的缺陷——克隆元素将失去与其绑定的事件……

这个插件没有这个问题。即使fiddle包含点击事件来演示它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接