【问题标题】:Appending multiple items using jQuery使用 jQuery 追加多个项目
【发布时间】:2009-10-23 20:25:36
【问题描述】:

我从这个标记开始:

<div>
  <span>
    <label for="Item[0]">Item #1</label>
    <input type="text" value="" name="Item" id="Item[0]"/>
  </span>
</div>

在每次单击按钮时,我都想添加与上面完全相同的部分,但索引会增加。

<div>
  <span>
    <label for="Item[0]">Item #1</label>
    <input type="text" value="" name="Item" id="Item[0]"/>
  </span>
</div>
<div>
  <span>
    <label for="Item[1]">Item #2</label>
    <input type="text" value="" name="Item" id="Item[1]"/>
  </span>
</div>

我正在尝试使用这个 javascript:

 $(document).ready(function(){

    var count = <%= Items.Count - 1 %>;

    $('#AddItem').click(function(e) {
        e.preventDefault();
        count++;

        var tb = $('#Item[0]').clone().attr('id', 'Item[' + count + ']');

        var label = document.createElement('label')
        label.setAttribute('For', 'Item[' + count + ']')

        $('#ItemFields').append(label);
        $('#ItemFields').append(tb);
    });
});

所以有几个问题:

添加标签有效,但我克隆的文本框无效。

标签没有文字。我似乎找不到那个属性。谁能告诉我这是什么?

我不知道如何将标签和文本框包装在一个 div 和 span 中。如果我尝试

$('#ItemFields').append('<div><span>' + label + tb + '</span></div>');

它输出 [object HTMLLabelElement] 而不是实际的标签。如果我尝试将它们拆分为多个附加语句,它会自行终止 div 和 span。我是 jQuery/Javascript 的新手,所以我不太确定自己做错了什么。

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    我想我会找到一种方法从标记中的现有数字中提取下一个数字,而不是依赖于保持变量同步。另外,我认为您只需要正确嵌套您的附加即可获得所需的包含。

    $(document).ready(function(){
    
        $('#AddItem').click(function(e) {
            var count = $('[name=Item]:last').attr('id').replace(/Item\[/,'').replace(/\]/,'');
            count = Number(count) + 1;
    
            var newItemID = 'Item[' + count + ']';
    
            var tb = $('#Item[0]').clone();
            tb.attr('id', newItemID );
    
            var label = $('<label for="' + newItemID + '">Item #' + count + '</label>');
    
            var container = $('<div></div>');
    
            $('<span></span>').append(label)
                              .append(tb)
                              .appendTo(container);
    
            $('#ItemFields').append(container);
            return false;
        });
    });
    

    【讨论】:

    • 感谢您的回复。我尝试了您的代码,但它生成了标记:
      它有一个自终止跨度并且没有文本框。
    • 另外,计数器没有递增。 .replace 中的第一个参数也应该用引号引起来吗?
    • 我没想到它会在跨度之后附加标签和输入。我已经更新为将 div 和 span 的创建分开并以正确的顺序组合它们。
    • 第一个参数不是正则表达式。也许,它没有正确匹配。尝试删除括号前面的反斜杠。括号只有在有两个时才可能是特殊的。
    • 删除反斜杠使其成为 NaN,您的解决方案效果更好,但仍然没有文本框。
    【解决方案2】:

    克隆整个块(但添加一个项目类)的示例,因为我认为它对未来更加健壮(例如,如果您更改项目的 html)并处理标签的文本:

    <html>
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <title>Demo</title>
      <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
      <script type="text/javascript">
      $(document).ready(function(){
        $('#AddItem').click(function(e) {
          e.preventDefault();
    
          var count = $('.item').length;
          var id = 'Item[' + count + ']';
          var item = $('.item:first').clone();
          item.find('input:first').attr('id', id);
          item.find('label:first').attr('for', id)
              .html('Item #' + (1+count));
          item.appendTo('#ItemFields');
        });
      });
      </script>
    </head>
    <body>
      <input type="button" id="AddItem" value="Add" />
      <div id="ItemFields">
        <div class="item">
          <span>
            <label for="Item[0]">Item #1</label>
            <input type="text" value="" name="Item" id="Item[0]"/>
          </span>
        </div>
      </div>
    </body>
    </html>
    

    【讨论】:

    • 这很好用,只是计数没有增加。
    • 糟糕,没关系。在 div 上使用 id 而不是类。现在效果很好。谢谢。
    • 是的,计数是具有'item'类的元素的数量。
    • 如果要使用长度,请确保不要删除其中任何一个(或仅删除最后一个)。如果除最后一个之外的任何一个被删除,然后您添加更多,您将重复数字。
    【解决方案3】:

    从“出了什么问题”开始,您混合了原生 DOM 调用、jQuery 和其他东西(我不知道 &lt;%= Items.Count - 1 %&gt; 是什么 - 也许是 PHP?)。我会留下最后一个,因为它听起来对你有用。否则,如果您要使用 jQuery,请尽量坚持使用它的方法。

    标签文本的“属性”只是值,由 jQuery value() 方法获取/设置。

    要附加标签,我建议您这样做:

    $('#ItemFields').append('<label for=Item["' + count + ']">'+ '</label>')
    

    我知道 append 可以接受文本、jQuery 对象或 DOM 元素,但我个人更喜欢用字符串来完成。如果您不想这样做,您可以这样做:

    $('#ItemFields').append($('<label></label>')
        .attr('for', 'Item["' + count + ']')
        .value('your label text here'));
    

    等等。

    原因

    $('#ItemFields').append('<div><span>' + label + tb + '</span></div>');
    

    没有给你你想要的是你正在将 Javascript 对象与字符串连接起来,它(如 Java)会在连接之前自动将对象转换为字符串。

    我将留下这个答案的其余部分不完整,因为 tvanfosson 的答案应该涵盖它。

    【讨论】:

    • 感谢您的回答。我不知道我不应该将本机 DOM 与 Jquery 混合,我实际上是按照另一个 SO 问题 stackoverflow.com/questions/953415/… 作为指导,它使用 Jquery 但在常规 javascript 中创建了元素。
    • 哦,其他的东西实际上是 C#。
    • 这并不是真正的“不应该”的事情。没有什么会真正打破。但是,最好避免混合来自提供重叠功能的 2 个不同 API 的调用。如果您已经在使用 jQuery,为什么不尽可能地使用它呢?回复:“别的东西” - 接受 tvanfosson 的建议并使用 Javascript 计算 count 的值。
    【解决方案4】:

    使用函数来构建你的 html;如果结构简单,则将其组装为字符串更容易:

    $(document).ready(function(){
    
        var count = <%= Items.Count - 1 %>;
    
        $('#AddItem').click(function(e) {
            e.preventDefault();
            count++;
    
            $('#ItemFields').append(create_item(count));
        });
    
    
        function create_item(i) {
            return $(['<div><span>'
                    ,'<label for="Item[', i, ']">Item #', i, '</label>'
                    ,'<input type="text" value="" name="Item" id="Item[', i ,']"/>'
                ,'</span></div>'].join(''), document);
        };
    });
    

    【讨论】:

      【解决方案5】:
      var oldDiv = $('whatever');//Get div here somehow
      var newHTML = $( oldDiv ).html();
      newHTML.replace(/\[[0-9]+\]/g, '['+count+']');
      newHTML.replace(/#[0-9]+/g, '#'+(count+1));    
      var newDiv = $('<div></div>').html( newHTML );
      

      这将创建一个新的 div,从 oldDiv 中获取 HTML,并对 [index] 和 #number 区域执行两次正则表达式替换。我尚未对其进行测试,但只需稍作修改即可使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-12
        • 1970-01-01
        • 2015-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多