无法获取通过JavaScript添加的HTML元素

时间:2019-02-15 07:31:32

标签: javascript html mutation-observers

正如标题所述,我无法访问随JavaScript添加的HTML元素。我尝试使用JavaScript添加HTML div后,使用document.getElementById('sampleID')来获取DOM元素。但是,HTML源代码无法反映所做的更改,因此我实际上无法获取新元素。

该应用程序与“待办事项”列表非常相似,但是跟踪应用程序而不是任务。提交的每个应用程序的div中都包含一个复选框,并且POST请求仍会通过,从而从数据库中删除了该应用程序,但是直到刷新后它才会反映在页面中。

我偶然发现的唯一相关概念是JavaScript的MutationObserver接口,该接口似乎不允许访问添加的元素。

感谢所有建议!

$('#applicationDelete').submit(function(event) {
    event.preventDefault(); // Stops browser from navigating away from page
    var names = [];
    $(":checkbox").each(function () {
        var isChecked = $(this).is(":checked");
        if (isChecked) {
            names.push($(this).attr("class"));
        }
    });
    var data = { names: names }
    console.log('Data: ' + names);
    $.ajax({
        type: 'POST',
        contentType: 'application/json',
        url: window.location + 'applications/delete',
        data: JSON.stringify(data),
        dataType: 'json',
        success: function(res) {
            if (res.response == 'success') {
                var application;
                for (i in names) {
                    application = document.getElementById(names[i]);
                    application.parentNode.removeChild(application);
                }
            }
        }
    });
});

编辑:

function addApplication(application) {
    const container = document.getElementsByClassName('applicationDelete')[0];
    const appWrap = document.createElement('div');
    appWrap.classList.add('application-wrapper');

    // ADDED THIS LINE THANKS TO SUGGESTIONS!
    appWrap.id = application.company;

    const checkbox = document.createElement('div')
    checkbox.classList.add('checkbox');
    const check = document.createElement('input');
    check.type = 'checkbox';
    check.classList.add(application.company);
    const app = document.createElement('div')
    app.classList.add('application');

    checkbox.appendChild(check);
    appWrap.appendChild(checkbox);
    appWrap.appendChild(app);
    container.insertBefore(appWrap, container.childNodes[3]);

    app.innerHTML = '\
    Company: ' + application.company + '<br>\
    Position: ' + application.position + '<br>\
    Experience: ' + application.experience + '<br>\
    Source: ' + application.source + '<br>';

}

意粉代码的道歉!我确信我对类和ID的使用与正确的编码约定相去甚远,但是你们仍然设法找到我的错误(甚至没有看到addApplication方法)。谢谢!

2 个答案:

答案 0 :(得分:0)

您正在使用此方法将类名称添加到名称数组。

names.push($(this).attr("class"));

并通过id检索元素。

application = document.getElementById(names[i]);

您应该将id存储在名称数组中(我也会为数组选择其他名称,这建议您存储名称)。

 names.push($(this).attr("id"));

或使用以下一种方法获取元素。

document.getElementsByClassName(names[i]); //returns array

document.querySelector('.' + names[i]); //returns dom element

$('.' + names[i]); //returns jQuery object.

由于您使用的是jQuery,因此建议您使用jQuery解决方案。

答案 1 :(得分:0)

isChecked检查下,您正在将元素的class属性推入names数组:

names.push($(this).attr("class"));

这意味着您的names数组由可以在DOM中找到的classes组成,但是您稍后会寻找ID。最简单的解决方法是将document.getElementById(names[i]);换成.querySelector()方法:

document.querySelector(names[i]);
// or via jQuery:
$(`.${names[i]}`)

☝️,但这只有在您可以确保您的类唯一的情况下(因为querySelector()找到与传递的查询选择器匹配的 first 元素)。

但是,一种更优雅的解决方案是使用而不是类,因为HTML规范要求它们在开始时必须是唯一的(这使您没有编写过故障保护功能)或生成重复的类)。因此,鉴于您所有复选框现在都具有唯一的ID,

names.push($(this).attr("id"));
// now you can look for ID-s again!
document.getElementById(names[i]);
// Or a shortcut via jQuery (saving the extra variable):
application.parentNode.removeChild($(`#${names[i]}`));