我如何 运行 具有不可用 DOM 对象的函数?

How can I run a function with an unavailable DOM object?

我想要 运行 一个函数来删除按钮的父元素。使用

获取父元素后
let rem_display_btn1 = document.getElementById('rem_display_btn1');

像这样

let rem_display_btn1 = document.getElementById('rem_display_btn1');
rem_display_btn1.addEventListener('click', () => {
    let parentEl = rem_display_btn1.parentElement.parentElement;
    parentEl.remove();
});

现在的问题是脚本加载到 HTML 文件的初始时刻,按钮还不存在。 即:rem_display_btn1 是在另一个函数是 运行 之后生成的,该函数依赖于 [= 上不是 运行 的函数48=]

我也会显示下面的功能,以备不时之需:

// Cart list Table Element
let cart_list = document.getElementById('cart_list');
let numy = 0;

let htmlTR = '';

let cartUpdater = () => {

    cart_list.innerHTML = "";
    htmlTR = ''
    numy = 0;

    for(let a = 0; a < cart.length; a++) {
        
        cart_list.innerHTML = "";
        numy++;
        htmlTR += `<tr id="htmlTR_ID${numy}">`;
        htmlTR += `<td style="width: 7%;">${numy}</td>`;
        htmlTR += `<td style="width: 25%;">${cart[a].name}</td>`;
        htmlTR += `<td style="width: 25%;">${cart[a].price}</td>`;
        htmlTR += `<td style="width: 15%; padding-left: 23px;"><button>-</button>1<button>+</button></td>`;
        htmlTR += '</tr>';
        console.log(htmlTR)
        cart_list.innerHTML += htmlTR;
    }

    for(let b = 0; b < cart.length; b++) {

        var remBtn_TD = document.createElement('td');
        remBtn_TD.style.width = '25%';
        var remBtn = document.createElement('button');
        remBtn.classList.add('rem_btn_');
        // Where the button element gets the **id: rem_display_btn1**
        // so I'm choosing the first button that is produced
        remBtn.id = `rem_display_btn rem_display_btn${b + 1}`;
        remBtn.innerHTML = 'remove';
        
        remBtn_TD.appendChild(remBtn);

        console.log(cart_list.children[0].children[b]);
        cart_list.children[0].children[b].appendChild(remBtn_TD);        
    }

}

我尝试在 cartUpdater() 函数 之后添加一个 if 语句来检查 document.getElementById('rem_display_btn1') 在将元素放入变量之前但即使那样它仍然不存在

if (document.getElementById('rem_display_btn1')) {
    let rem_display_btn1 = document.getElementById('rem_display_btn1');
    rem_display_btn1.addEventListener('click', () => {
        let parentEl = rem_display_btn1.parentElement.parentElement;
        parentEl.remove();
    });
} else {
    console.log('Not There')
}

我在想是否有办法获得 HTML/WebPage 的当前状态,所以我也尝试将 if 语句放在 setTimeout 和 setInterval 函数中,但它们都不起作用。问题是我确定这是一种工作方式,我就是想不通。

感谢期待。

添加 setInterval 函数:

setInterval(() => {
    if (document.getElementById('rem_display_btn1')) {
        let rem_display_btn1 = document.getElementById('rem_display_btn1');
        rem_display_btn1.addEventListener('click', () => {
            let parentEl = rem_display_btn1.parentElement.parentElement;
            parentEl.remove();
        });
    } else {
        console.log('Not There')
    }
}, 4000);

对于设置超时:

setTimeout(() => {
    if (document.getElementById('rem_display_btn1')) {
        let rem_display_btn1 = document.getElementById('rem_display_btn1');
        rem_display_btn1.addEventListener('click', () => {
            let parentEl = rem_display_btn1.parentElement.parentElement;
            parentEl.remove();
        });
    } else {
        console.log('Not There')
    }    
}, 9000);

我使用了更长的时间来设置超时,所以我可以在获得 rem_display_btn1 按钮之前 运行 cartUpdater() 函数

您还可以向任何立即存在的父元素(或整个 document)添加点击侦听器,并检查点击的元素是否与您的按钮 ID 匹配。这样以后加不加按钮也没关系

document.addEventListener("click", (e) => {
  if (!e.target.matches("#rem_display_btn1")) return;
  e.target.parentElement.remove()
})
<div>
  <button id="rem_display_btn1">Remove</button>
</div>

您根本不需要引用按钮的变量:

document.addEventListener('DOMContentLoaded', () => {
   // Dropped: let rem_display_btn1 = document.getElementById('rem_display_btn1'); 
   document.getElementById('rem_display_btn1').addEventListener('click', (e) => {
        let parentEl = e.currentTarget.parentElement.parentElement;
            // Do not use 'this' to reference the button;
            //   Cf. 
        parentEl.remove();
   });
});
<div>
  <button id="rem_display_btn1">Remove</button>
</div>

方案一(通过动态创建元素的代码添加事件处理器)

如果您要将事件处理程序附加到的元素(即。rem_display_btn1)在文档最初加载后的某个未指定时间动态插入,请使用 html 属性事件处理程序:

function hnd_removeButton (e) {
    let parentEl = e.currentTarget.parentElement.parentElement;
    parentEl.remove();
}

document.addEventListener('DOMContentLoaded', () => {
     setTimeout ( () => {
         //
         // At the time you create the dynamic element, add the proper event handler.
         let e_btn = document.createElement('button')
           , e_container = document.getElementById ( 'test-anchor' )
           ;

         e_btn.setAttribute('id', 'rem_display_btn1');
         e_btn.textContent = 'Remove';
         e_btn.addEventListener('click', hnd_removeButton);

         e_container.appendChild(e_btn);
     }, 3000 ); 
});
<div id="test-anchor">
  <div>Waiting for button to appear</div>
</div>

备选方案 2(聆听 DOM 变化)

另一种选择是将响应元素添加到DOM。当前 DOM API 实现提供 MutationObserver 接口来支持此任务(注意:以前可用的事件 DOMSubtreeModified 也允许编写合适的处理程序已被弃用)。

function hnd_removeButton (e) {
    let parentEl = e.currentTarget.parentElement.parentElement;
    parentEl.remove();
}

function mobs_addClickHandler ( a_mutationsList, x_observer ) {
    for (const o_mutation of a_mutationsList ) {
        o_mutation.target.querySelector('#rem_display_btn1').addEventListener ( 'click', hnd_removeButton );
    }
}

document.addEventListener('DOMContentLoaded', () => {
    const observer = new MutationObserver(mobs_addClickHandler)
        ;
    observer.observe ( document.getElementById ( 'test-anchor' ), { attributes: true, childList: true, subtree: true } );
     
    setTimeout ( () => { // Demo only - Elements being added. The click event handler is attached in the event handler for 'DOMSubtreeModified'
         //
         // At the time you create the dynamic element, add the proper event handler.
         let e_btn = document.createElement('button')
           , e_container = document.getElementById ( 'test-anchor' )
           ;

         e_btn.setAttribute('id', 'rem_display_btn1');
         e_btn.textContent = 'Remove';

         e_container.appendChild(e_btn);
     }, 3000 ); 
});
<div id="test-anchor">
  <div>Waiting for button to appear</div>
</div>