2

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

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

添加新项目

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

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

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

4

4 回答 4

1

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

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

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

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

于 2012-11-13T19:48:39.583 回答
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(...))

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

于 2012-11-13T19:49:15.480 回答
1

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

稍微修改了上面的内容,添加一个简单的 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);
}​

参考:

于 2012-11-13T20:07:43.197 回答
0

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

于 2012-11-13T19:46:41.703 回答