I’m editing a Tampermonkey script that takes elements from the DOM and makes a new element from those to add them to a different part of the page. The original element has an X button that changes the display value of the div (to style="display: none"
)
<div id="alertTable">
<ul>
<li>Element 0 index 0
<img src="example.com/img0.jpg">
<img class="x-close" src="example.com/x_icon.png">
</li>
</ul>
</div>
$(document).ready(function newDiv() {
var newElementText = document.querySelector('#alertTable li');
var newElementImg = document.querySelector('#alertTable li img');
var newElementClose = document.querySelector('.x-close');
var newElementCSS = `
<style>
#scriptDiv img {
width: 500px;
}
#scriptDiv li {
color: #f8f8f8;
}
</style>
`;
const HTMLElement = `
<div id="scriptDiv">
${newElementText}
${newElementImg}
${newElementClose}
</div>
`;
$('.DOMheader').prepend(HTMLElement);
});
The issue with that code is that sometimes the <ul>
element of the DOM contains more than one element, like so, and the original code only detects and interacts with the first instance of the elements it finds with querySelector (logically)
<div id="alertTable">
<ul>
<li>Element 0 index 0
<img src="example.com/img0.jpg">
<img class="x-close" src="example.com/x_icon.png">
</li>
<li>Element 1 index 1
<img src="example.com/img1.jpg">
<img class="x-close" src="example.com/x_icon.png">
</li>
<li>Element 2 index 2
<img src="example.com/img2.jpg">
<img class="x-close" src="example.com/x_icon.png">
</li>
</ul>
</div>
I’d like to modify the original code to listen for the click on the .x-close
element, and display the next <li>
element’s information on the newElement
variables. How could this be achieved? The original code includes this to "close" the DOM’s div when clicking on the injected element’s close button
var DOMClose = document.querySelector('#alertTable.x-close');
var ScriptClose = document.querySelector('#scriptDiv.x-click');
ScriptClose.addEventListener('click', function () {
DOMClose.click();
}
2
Answers
Ended up going with the following solution. The divs to be closed (and the divs they take information from) are just alerts, they are meant to be closed in the website in question. The following code keeps track of the index number of the
li
node, and will both remove the script-generated node and render the nextli
node if one is present when a specific part of the site is interacted with. The specific node can then be appended (and styled) to whatever part of the page it's told to.In the OP code the function
newDiv()
makes very little sense and doesn’t look like it has much to do with building a<ul>
within a<div id="alertTable">
. So assuming that this<ul>
already exists you can register the<ul>
to listen for any "click" events that trigger on itself and any elements within it (ie children elements). Then only define what happens when a particular element is clicked by the user and ignore the other elements (see Event Delegation).Clicking an item closed and opening the next item sounds like bad UX. How would the user reopen a closed item? In the example below, the user can toggle any item to open or close. If you prefer to have only a single item open at a time, refer to the comment labeled with a
✤
in the JavaScript portion of the example.Details are commented in example.