簡體   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