繁体   English   中英

如何在 JavaScript 中实现“添加新项目”功能?

[英]How to implement "add new item" functionality in JavaScript?

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

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

添加新项目

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

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

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

如果您已经在您的页面上使用了 jquery 或 sencha 等框架,那么您不妨使用它。

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

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

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

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

<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')我们正在点击的当前表格( $this.closest('table')
    • 定位该表中的第一行并复制它( .clone()
    • 删除任何可能存在的填充值( .find(':input').val('')
    • 将此新克隆的行附加到“添加新项目”行上方的表中( $newRow.insertBefore(...)

您也可以采用模板方法,但这实际上取决于您以及您希望对输出进行多少控制。

虽然我意识到你已经有了一个公认的答案,但我想我会提供一种简单的 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小提琴演示

稍微修改上面的内容,添加一个简单的垫片来应对那些没有实现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);
}​

参考:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM