【问题标题】:Recursively Scan DOM Elements - Javascript递归扫描 DOM 元素 - Javascript
【发布时间】:2023-04-01 11:14:01
【问题描述】:

我有以下 html -

<a>
  <b>
   ....

    .....
    <input type="button" name="add" onclick="..." value="add another"/>
    </d>
   </b>
....
</a>

而我使用下面的js sn-ps-

/**
 *  Dynamically add a remove button on next to the add button.
 *
 */
addRemoveButton = function(node) {
    if(node.nodeType == 3) {
        if(node.nodeName == "input") {
            if(node.getAttribute("type") == "button") {
                if(node.getAttribute("name") == "add") {
                    var removeButton = node.cloneNode(true);
                    removeButton.removeAttribute("name");
                    removeButton.setAttribute("value", "remove");
                    removeButton.setAttribute("onclick", "");
                    removeButton.setAttribute("id", "");
                    (node.parentNode).appendChild(removeButton);
                    return;
                }
            }
        }
    }
    if(node.nodeType == 1) {
        var list = node.childNodes;
        var i = 0;
        while(i<list.length) {
            return addRemoveButton(list[i]);
            i++;
        }
    }
    return;
}

现在我想在上面列表中显示的当前按钮旁边添加一个按钮类型的输入(删除按钮)。我试图递归地做到这一点。但这不起作用。你能从上面的代码中找到问题吗?

【问题讨论】:

    标签: javascript jquery xml ajax dom


    【解决方案1】:

    据我所知,您的代码相差甚远。您使用了错误的 nodeType 并且在 nodeName 上使用了错误的大小写,并且没有理由使用大量嵌套的 if 语句。但是,你可以让它像这样递归地工作:

    addRemoveButton = function(node) {
        if (node.nodeType == 1) {
            if (node.nodeName.toLowerCase() == "input" &&
              node.getAttribute("type") == "button" &&
              node.getAttribute("name") == "add") {
                var removeButton = node.cloneNode(true);
                removeButton.removeAttribute("name");
                removeButton.setAttribute("value", "remove");
                removeButton.setAttribute("onclick", "");
                removeButton.setAttribute("id", "");
                (node.parentNode).appendChild(removeButton);
                return;
            } else {
                var list = node.childNodes;
                for (var i=0; i < list.length; i++) {
                    // be aware of childNodes changing on us live here
                    // when we modify the DOM
                    addRemoveButton(list[i]);
                }
            }
        }
    }
    
    addRemoveButton(document.body);
    

    你可以在这里看到它的工作原理:http://jsfiddle.net/jfriend00/WCj4b/

    使用 jQuery(你也用它来标记你的问题)并继续使用克隆操作,你可以这样做:

    $("input[type='button'][name='add']").each(function(index, el) {
        $(this).clone(false)
            .val("remove")
            .removeAttr("name")
            .attr("onclick", "")
            .attr("id", "")
            .insertAfter(this);
    });
    

    在这里演示:http://jsfiddle.net/jfriend00/JKsZC/

    或者一个简单得多的版本,它只是插入新的 HTML 而不是克隆现有的按钮:

    $("input[type='button'][name='add']").after('<input type="button" value="Remove" />');
    

    在这里演示:http://jsfiddle.net/jfriend00/vSZwp/

    【讨论】:

    • 显示 OP 做错了什么很好,但是使用 jQuery 之类的库,您无需编写那种代码
    • @JuanMendes - 我同意。所以我也写了一个jQuery版本。
    【解决方案2】:

    为什么要递归?只是为了找到现有的按钮?让 jQuery 担心找到它

    $('input[type=button]').after("<input type='button' value='Remove' />");
    

    对此进行调整以使您的删除按钮执行您需要的操作。

    【讨论】:

    • OP 的代码正在尝试在现有按钮旁边创建一个新按钮。您的代码只是更改现有按钮。
    • OP 的代码无法正常工作,但 cloneNode 正在尝试创建一个重复按钮,然后将该重复按钮设置为“删除”按钮。我制作了一个在我的答案中有效的 OPs 代码版本。
    • @jfriend00 据我所知,OP 希望在现有按钮旁边插入一个按钮。我的代码就是这样做的。
    • 我现在明白了。您的代码确实假定按钮后没有其他兄弟姐妹,而不是将其插入按钮后。
    猜你喜欢
    • 2012-11-30
    • 1970-01-01
    • 2014-04-21
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 2010-11-02
    相关资源
    最近更新 更多