I want to run a function to remove a button's parent element. parent element after getting it with
let rem_display_btn1 = document.getElementById('rem_display_btn1');
like this
let rem_display_btn1 = document.getElementById('rem_display_btn1');
rem_display_btn1.addEventListener('click', () => {
let parentEl = rem_display_btn1.parentElement.parentElement;
parentEl.remove();
});
The problem now is that the initial moment the script loads in the HTML file, the button is not yet there. That is: rem_display_btn1 is produced after another function is run and that function it depends on those not run on window.onload
I will also display the function below in case it will be of help:
// 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);
}
}
I've tried adding an if statement after the cartUpdater() function to check for document.getElementById('rem_display_btn1') before getting the element into a variable but even then it still doesn't exist
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')
}
I'm thinking if there's a way to get the current state of the HTML/WebPage in total, so I also tried putting the if statement in a setTimeout and setInterval function but neither of them worked as well. The thing is I'm sure the is a way for this to work, I just can't figure it out.
Thanks in anticipation.
Adding the setInterval function:
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);
For the setTimeout:
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);
I used a longer time for the set timeout so I can run the cartUpdater() function before I get the rem_display_btn1 button
CodePudding user response:
You can also add a click listener to any parent element that exists right away (or the entire document
) and check if the clicked element matches your button's id. This way, it does not matter if the button is added at a later point.
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>
CodePudding user response:
You do not need the variable referencing the button at all:
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. https://stackoverflow.com/a/46270771/
parentEl.remove();
});
});
<div>
<button id="rem_display_btn1">Remove</button>
</div>
Alternative 1 (Add event handler through the code that dynamically creates an element)
In case the element you want to attach the event handler to ( ie . rem_display_btn1
) is inserted dynamically at some unspecified time after the document has initially been loaded, use the html attributes for event handlers:
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>
Alternative 2 (Listen to DOM changes)
Another option is to respond to elements added to the DOM.
function hnd_removeButton (e) {
let parentEl = e.currentTarget.parentElement.parentElement;
parentEl.remove();
}
document.addEventListener('DOMContentLoaded', () => {
document.addEventListener ( 'DOMSubtreeModified', (e) => {
e.target.querySelector('#rem_display_btn1').addEventListener ( 'click', hnd_removeButton );
});
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>