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();
}
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 next li
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.
// Declare the initial index number and make an array from all <li> elements within #alertTable
var index = 0;
var arr = Array.from(document.querySelectorAll('#alertTable li'));
// Display the new HTML element, with a bit of a wait to make sure all elements have loaded before running
function runInsert () { setTimeout(() => { insertElementFromArray(); }, 1000); }
// Create the new HTML element and insert it
function insertElementFromArray() {
// The new HTML we will add to the site, including its own style
const elementHTML = `
<div id="newElement">
<style>
#newElement {
width: 300px;
height: 100%;
background: #e7fe87;
}
#newElement img {
width: 30px;
height: 30px;
margin: 10px;
}
#newElement .x-close {
float: right;
background: url(https://cdn-icons-png.flaticon.com/512/1828/1828843.png);
background-size: 100%;
width: 40px;
height: 40px;
top: 5px;
right: 5px;
margin: 10px;
cursor: pointer;
}
</style>
${arr[index].innerHTML}
</div>
`;
$('#upperDiv').append(elementHTML);
// Listen for the click on the '#newElement x-close' element, and remove the elementHTML div. Move to the next element in the index, and render the next one if there is one.
document.querySelector('#newElement .x-close').addEventListener('click', function () {
$('#newElement').remove();
index = index + 1;
(arr[index] !== undefined) && (runInsert());
});
}
runInsert();
#upperDiv {
position: fixed;
top: 0;
width: 100%;
height: 85px;
background: #000;
background-size: auto 100%;
}
#alertTable {
display: block;
width: 200px;
padding: 10px;
overflow: auto;
position: fixed;
top: 90px;
box-sizing: border-box;
background-color: #4c4c4c
}
#alertTable ul {
list-style: none;
padding: 0;
margin: auto;
width: 100%;
}
#alertTable ul li {
box-sizing: border-box;
border-radius: 5px;
width: 100%;
height: auto;
padding: 10px;
margin-bottom: 15px;
min-height: 85px;
position: relative;
background-color: #fff;
}
#alertTable img {
width: 75px;
height: 75px;
}
#alertTable .x-close {
float: left;
background: url(https://cdn-icons-png.flaticon.com/512/1828/1828843.png);
background-size: 100%;
width: 30px;
height: 30px;
top: 5px;
right: 5px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<body>
<div id="upperDiv"></div>
<div id="alertTable" style="visibility: hidden;">
<ul>
<li>
<img src="https://cdn-icons-png.flaticon.com/512/4213/4213689.png">
<div class="x-close" src="example.com/x_icon.png"></div>
Element 0 index 0
</li>
<li>
<img src="https://cdn-icons-png.flaticon.com/512/4213/4213633.png">
<div class="x-close" src="example.com/x_icon.png"></div>
Element 1 index 1
</li>
<li>
<img src="https://cdn-icons-png.flaticon.com/512/4213/4213663.png">
<div class="x-close"></div>
Element 2 index 2
</li>
</ul>
</div>
</body>