我正在编辑一个 Tampermonkey 脚本,该脚本从 DOM 中获取元素并从中创建一个新元素,以将它们添加到页面的不同部分。原始元素有一个 X 按钮,可以更改 div 的显示值(至
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);
});
该代码的问题在于,有时 DOM 的
<ul>
元素包含多个元素,就像这样,原始代码仅检测使用 querySelector 找到的元素的第一个实例并与之交互(逻辑上)
<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>
我想修改原始代码以监听
.x-close
元素的点击,并在 <li>
变量上显示下一个 newElement
元素的信息。如何才能实现这一目标?原始代码包含此内容,以便在单击注入元素的关闭按钮时“关闭”DOM 的 div
var DOMClose = document.querySelector('#alertTable.x-close');
var ScriptClose = document.querySelector('#scriptDiv.x-click');
ScriptClose.addEventListener('click', function () {
DOMClose.click();
}
在 OP 代码中,函数
newDiv()
没有什么意义,并且看起来与在 <ul>
中构建 <div id="alertTable">
没有太大关系。因此,假设这个 <ul>
已经存在,您可以注册 <ul>
来侦听在其自身及其中的任何元素(即子元素)上触发的任何“单击”事件。然后仅定义用户单击特定元素时发生的情况并忽略其他元素(请参阅事件委托)。
示例中注释了详细信息。
// Reference the <ul>
const list = document.querySelector('#alertTable ul');
// Register <ul> to the "click" event...
list.addEventListener("click", function(e) {
/**
* e.target is the element the user clicked.
*/
// Reference the <li> that contains e.target
const li = e.target.parentElement;
// If e.target has class of "x-close"...
if (e.target.matches(".x-close")) {
// change e.target class to "x-open"...
e.target.className = "x-open";
// change e.target src...
e.target.src = "https://i.ibb.co/vcpdyvK/open-white.png";
// remove any class from the <li> that contains e.target.
li.className = "";
// Otherwise if e.target has class of "x-open"...
} else if (e.target.matches(".x-open")) {
// change e.target class to "x-close"...
e.target.className = "x-close";
// change e.target src...
e.target.src = "https://i.ibb.co/dbLgV41/x-square-white.png";
// add class "active" to the <li> that contains e.target.
li.className = "active";
} else {
// Otherwise if e.target is any other element end function
return false;
}
}
:root {
font: 16px/1 "Segoe UI";
overflow-y: scroll;
}
#alertTable {
padding: 3px;
background: black;
}
#alertTable li {
display: flex;
justify-content: space-between;
margin: 3px 6px;
padding: 3px;
color: #f8f8f8;
}
/**
* For each first <img> in a <li>,
* hide it by making it's height 0
*/
#alertTable li img:first-of-type {
width: 200px;
height: 0;
/* This animates the height when it goes to/from 0 */
transition: height 0.5s ease-out;
}
/**
* If a <li> has class "active",
* the first <img> height becomes 200px
*/
#alertTable li.active img:first-of-type {
height: 200px;
}
#alertTable .x-close,
#alertTable .x-open {
width: 18px;
height: 18px;
margin-bottom: 1px;
cursor: pointer;
}
#alertTable .x-close {
width: 20px;
}
<div id="alertTable">
<ul>
<li>Matrix
<img src="https://i.ibb.co/c1PtcM7/matrix1.gif">
<img class="x-open" src="https://i.ibb.co/vcpdyvK/open-white.png">
</li>
<li>Static
<img src="https://i.ibb.co/bBGX3Sq/static.gif">
<img class="x-open" src="https://i.ibb.co/vcpdyvK/open-white.png">
</li>
<li>Stars
<img src="https://i.ibb.co/FHRS8Gx/stars.gif">
<img class="x-open" src="https://i.ibb.co/vcpdyvK/open-white.png">
</li>
</ul>
</div>