【问题标题】:How to implement "add new item" functionality in JavaScript?如何在 JavaScript 中实现“添加新项目”功能?
【发布时间】:2012-11-02 06:46:46
【问题描述】:

标题描述性不是很好,但我找不到更好的。随意编辑它。

基本上我正在寻找的是执行以下操作的最佳方法:

当用户单击“添加新项目”时,会添加一个带有相同文本框的新行,并如上所示下拉。我能想到的选项如下:

  • 在 JavaScript 代码中对 HTML 进行硬编码。这显然是一个非常丑陋的解决方案。
  • 从 DOM 节点(或 jQuery 对象)组装 HTML。这也很丑。
  • 使用客户端模板系统。我曾经使用过其中一个,它很奇怪(它使用<script language="html"> 标签来定义模板)。
  • 制作一个临时的客户端“模板”并使用 CSS 以某种方式隐藏它。
  • 发出 AJAX 请求以获取 HTML。这很慢,而且会不必要地使用服务器资源。

你有什么建议?我对上述任何解决方案都不完全满意。

【问题讨论】:

  • 使用 jQuery 是否重要,或者您想要一个简单的 jane javascript 解决方案?
  • 克隆最后一行,修改ids(如果有)并附加到当前最后一行的父级。
  • @BradChristie:我更喜欢 jQuery。
  • @BotondBalázs:this 怎么样?
  • @DavidThomas:这看起来是个不错的解决方案,谢谢。也许将其扩展为答案,以便我可以投票?

标签: javascript html web-applications web


【解决方案1】:

假设超级简单的方法并且您的格式在表格中:

<table>
    <tr>
        <td><input type="text" name="item_name" placeholder="item name" /></td>
        <td><select name="item_type"><option value="" selected="selected">Type</option></select></td>
    </tr>
    <tr>
        <td><input type="text" name="item_name" placeholder="item name" /></td>
        <td><select name="item_type"><option value="" selected="selected">Type</option></select></td>
    </tr>
    <tr>
        <td colspan="2" id="add">+ Add new item</td>
    </tr>
</table>

您可以使用以下内容:

$('#add').on('click',function(e){
    var $this = $(this);
    var $newRow = $this.closest('table').find('tr:first').clone();
    $newRow.find(':input').val('');
    $newRow.insertBefore($this.parent());
});

分解:

  1. 我们为最后一项提供了 ID,以便更轻松地将点击事件绑定到。
  2. 使用 jQuery 并将点击事件绑定到以下 ID:
    • 抓取我们正在点击的当前表格 ($this.closest('table'))
    • 找到该表中的第一行并将其复制 (.clone())
    • 删除任何可能存在的填充值 (.find(':input').val(''))
    • 将此新的克隆行附加到“添加新项目”行上方的表格中 ($newRow.insertBefore(...))

您也可以采用模板方法,但这完全取决于您以及您希望对输出的控制程度。

【讨论】:

  • 谢谢。这是相当可维护的(HTML 在它崩溃之前可以改变很多)并且也是轻量级的。
  • 虽然我认为我会使用包装 div 而不是表格 :)
  • 我也喜欢你如何在包含 jQuery 对象的变量前加上'$'。这很常见吗?
  • @botond 不知道它是否常见,但我倾向于喜欢它,因为它有助于区分普通值变量和 jQuery 对象。我也同意 div,但表格更容易显示,格式或样式要求最少。
【解决方案2】:

如果您已经在页面上使用 jquery 或 sencha 之类的框架,则不妨使用它。

否则,我会尽可能简单。这看起来不是一个非常重要的核心功能,所以不要创建需要额外 https 请求甚至加载整个库的东西。克隆或生成 html 可能看起来不优雅,但它会是:

  • 快速实施
  • 易于阅读,因此易于调试
  • 资源浪费少,速度极快
  • 稳定
  • 不需要服务器端代码或额外的 http 请求
  • 如果需要,以后可以很容易地更改实现

不要为像这样微不足道的事情创造一些矫枉过正的东西。

【讨论】:

    【解决方案3】:

    虽然我知道您已经有了一个公认的答案,但我想我会提供一种简单的 JavaScript 方法来实现相同的目标:

    function closest(el, tag) {
        if (!el || !tag) {
            return false;
        }
        else {
            var curTag = el.tagName.toLowerCase();
            return curTag == tag.toLowerCase() && curTag !== 'body' ? el : closest(el.parentNode, tag);
        }
    }
    
    function addRow(el) {
        if (!el) {
            return false;
        }
        else {
            var tr = closest(el, 'tr').previousElementSibling,
                newRow = tr.cloneNode(true);
            tr.parentNode.insertBefore(newRow, tr.nextSibling);
        }
    }
    
    document.getElementById('add').onclick = function() {
        addRow(this);
    }​
    

    JS Fiddle demo.

    稍微修改了上面的内容,添加了一个简单的 shim 来应对那些没有实现 previousElementSibling 的浏览器:

    function closest(el, tag) {
        if (!el || !tag) {
            return false;
        }
        else {
            var curTag = el.tagName.toLowerCase();
            return curTag == tag.toLowerCase() && curTag !== 'body' ? el : closest(el.parentNode, tag);
        }
    }
    
    function prevElementSiblingShim(el) {
        if (!el) {
            return false;
        }
        else {
            var prevSibling = el.previousSibling;
            return prevSibling.nodeType == 1 ? prevSibling : prevElementSiblingShim(prevSibling);
        }
    }
    
    function addRow(el) {
        if (!el) {
            return false;
        }
        else {
            var par = closest(el, 'tr'),
                tr = par.previousElementSibling || prevElementSiblingShim(par),
                newRow = tr.cloneNode(true);
            tr.parentNode.insertBefore(newRow, tr.nextSibling);
        }
    }
    
    document.getElementById('add').onclick = function() {
        addRow(this);
    }​
    

    参考资料:

    【讨论】:

      【解决方案4】:

      将字符串中的 HTML 插入 DOM 是最有效的方法。除非您一次插入数百个,否则这并不重要。

      【讨论】:

      • 也许它很有效,但我不会在一秒钟内进行数千次插入,因此可读性和可维护性对我来说更重要。不过还是谢谢。
      猜你喜欢
      • 1970-01-01
      • 2021-04-26
      • 2021-06-26
      • 1970-01-01
      • 2022-10-24
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 2013-02-04
      相关资源
      最近更新 更多