使用jQuery重构HTML

时间:2009-07-04 14:16:37

标签: jquery xhtml

我需要在两个结构之间切换一些HTML - 一个嵌套,一个非嵌套 - 以便用户更容易对cms中的页面组件进行排序。

这是之前的html ...

<p><a href="#" id="restructure">Toggle Structure</a></p>
<div id="modules">
  <div class="two_column_box">
    <div class="column_left">
      <p>Some text</p>
    </div>
    <div class="column_right">
      <p>Some text</p>
    </div>
  </div>
  <div class="two_column_box">
    <div class="column_left">
      <p>Some text</p>
    </div>
    <div class="column_right">
      <p>Some text</p>
    </div> 
  </div> 
</div>

并在html之后...

<p><a href="#" id="restructure">Toggle Structure</a></p>
<div id="modules">
  <div class="column_left">
    <p>Some text</p>
  </div>
  <div class="column_right">
    <p>Some text</p>
  </div>
  <div class="column_left">
    <p>Some text</p>
  </div>
  <div class="column_right">
    <p>Some text</p>
  </div>
</div>

我可以删除额外的div,没有麻烦,但之后又把它们放回去 - 我只是不知道如何从纯文本和现有DOM元素构建html。这是我到目前为止的代码......

  <script type="text/javascript" charset="utf-8">
  $(document).ready(function(){  
    $('#restructure').toggle(
      function() {
        alert('removing structure');
        var module_list = $("#modules > div > div");
        $("#modules").html(module_list);
      },
      function() {
        alert('replacing structure');
        var idx = 1;
        var next;
        var structure = $("");
        while((next = $('#modules > div:nth-child(' + idx++ + ')')).length) {
          var element = next.clone();
          if(idx%2==1) {
            $(structure).append('<div class="two_column_box">').append(element);
          } else {
            $(structure).append(element).append('</div>');
          }
        }
        $("#modules").html(structure);
      }
    );
  });
  </script>

任何帮助使得切换的第二个功能起作用(或者在工作代码的更惯用的版本中)都会非常感激...

3 个答案:

答案 0 :(得分:4)

您应该在案例中使用wrapAll,因为您将多个元素一次包装到同一个元素中。

  <script type="text/javascript" charset="utf-8">
  $(document).ready(function(){  
    $('#restructure').toggle(
      function() {
        alert('removing structure');
        var module_list = $("#modules > div > div");
        $("#modules").html(module_list);
      },
      function() {
        alert('replacing structure');
        var next;
        while((next = $('#modules > div.column_left:first, #modules > div.column_right:first')).length)
        {
          next.wrapAll('<div class="two_column_box"></div>');
        }
      }
    );
  });
  </script>

答案 1 :(得分:3)

尝试一下:

  $(document).ready(function(){  
    $('#restructure').toggle(
      function() {
        alert('removing structure');
        $("#modules .column_left, #modules .column_right").moveToGrandparent();
        $(".two_column_box").remove(); 
      },
      function() {
        alert('replacing structure');

        var next = $('#modules > .column_left:first, #modules > .column_right:first');
        while (next.length > 0)
        { 
            var wrapper = $("<div />").addClass("two_column_box");
            next.wrapAll(wrapper);
            next = $('#modules > .column_left:first, #modules > .column_right:first');
        }
      }
    );
  });


  (function($) {

    $.fn.moveToGrandparent = function() {
        return $(this).each(function() {
            $(this).parent().parent().append($(this));
        });
    };      

  })(jQuery);

虽然您正在删除结构代码,但我重新编写它以使用插件。至于替换结构,我使用jQuery wrapAll方法和一个获取第一个元素的循环,直到没有剩余任何元素。

HTH, 本

答案 2 :(得分:0)

对gradbot的建议稍作补充:重点是元素将使用UI排序进行排序,因此我需要根据列表中的位置对项目进行重新排序 - 奇数是左手边,甚至是右边的。可能有更快的方法,但......

  <script type="text/javascript" charset="utf-8">
    $(document).ready(function(){  
      $('#restructure').toggle(
        function() {
          alert('removing structure');
          var module_list = $("#modules > div > div");
          $("#modules").html(module_list);
        },
        function() {
            alert('replacing structure');
            $('#modules > div').removeClass();
            $("#modules > div:odd").addClass('column_left');
            $("#modules > div:even").addClass('column_right');
            while((next = $('#modules > div.column_left:first, #modules > div.column_right:first')).length) {  
              next.wrapAll('<div class="two_column_box"></div>');
            }
        }
      );
    });
    </script>