【问题标题】:How to trigger an event on specific html element with class in vanilla javascript如何使用香草javascript中的类触发特定html元素上的事件
【发布时间】:2018-06-17 23:38:04
【问题描述】:
我正在尝试将我的 jquery 代码重构为 vanilla,因为我想正确使用 js。但我有一个问题。我无法弄清楚如何仅在具有特定类的第三个元素上触发事件。因为 querySelector 总是返回该类的第一个元素,例如这是我的半成品代码
const box = document.querySelector('.media-page--box-container');
$(box).on('mouseenter', () => {
// $(this). => select hovered element and do something only on it
console.log('enter')
}).on('mouseleave', () => {
console.log('leave')
});
.media-page--box-container:not(:first-child){
margin-top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
您可以在 sn-p 中找到示例
【问题讨论】:
标签:
javascript
jquery
html
ecmascript-6
dom-manipulation
【解决方案1】:
这个答案应该强调一些事情。您可能需要以不同的方式处理事件冒泡。我将 e.target 添加到悬停消息中。你的目标是一个块元素,即使你看不到它也会触发鼠标事件,所以我用红色突出显示它。 querySelectorAll 将抓取所有元素,而不仅仅是 querySelector 工作方式的第一个元素。
const boxes = document.querySelectorAll('.media-page--box-container');
boxes[2].addEventListener("mouseover", myMouseover );
boxes[2].addEventListener("mouseleave", myMouseout);
function myMouseover(e) {
console.log('enter' + e.target);
}
function myMouseout() {
console.log('leave');
}
.media-page--box-container:not(:first-child) {
margin-top: 50px;
}
.media-page--box-container {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
【解决方案2】:
您可以使用 querySelectorAll 检索与您的选择器匹配的所有节点。
因为它返回一个NodeList,它是一个类似数组的对象,你可以通过调用array.prototype.foreach并通过nodelist来遍历它。
您可以从那里为节点列表中的每个项目或基于迭代器的任何单个节点添加事件侦听器。
const boxes = document.querySelectorAll('.media-page--box-container');
Array.prototype.forEach.call(boxes, (box, i) => {
if (i===2) {
box.addEventListener('mouseenter', () => {
console.log('enter')
});
box.addEventListener('mouseleave', () => {
console.log('leave')
});
}
});
.media-page--box-container:not(:first-child){
margin-top: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
<div class="media-page--box-container">
<div class="media-page--inner-wrapper">
<div class="media-page--image-wrapper">
<img class="media-page--image" src="http://via.placeholder.com/212x169">
</div>
<div class="media-page--image-title-wrapper">
<span class="media-page--image-title">Image.jpg</span>
</div>
<div class="media-page--download-link-wrapper">
<a class="media-page--download-link" href="#">Download</a>
</div>
</div>
</div>
【解决方案3】:
如果您想为一个元素添加监听器,请使用下面的代码。
const box = document.querySelector('.media-page--box-container');
box.addEventListener("click", function() {
console.log("Clicked!");
});
<div class="media-page--box-container">.media-page--box-container</div>
或此代码用于少数元素
const boxes = document.querySelectorAll('.media-page--box-container');
boxes.forEach(function(box){
box.addEventListener("click", function() {
console.log("Clicked!");
});
});
<div class="media-page--box-container">.media-page--box-container 1</div>
<div class="media-page--box-container">.media-page--box-container 2</div>
<div class="media-page--box-container">.media-page--box-container 3</div>
querySelector 返回一个对象,querySelectorAll 和 getElementsByClassName 返回对象数组。不是 getElementsByClassName 需要类名,而不是参数中的选择器。
console.log("querySelector", document.querySelector('.media-page--box-container'));
console.log("querySelectorAll", document.querySelectorAll('.media-page--box-container'));
console.log("getElementsByClassName", document.getElementsByClassName('media-page--box-container'));
<div class="media-page--box-container">.media-page--box-container 1</div>
<div class="media-page--box-container">.media-page--box-container 2</div>
<div class="media-page--box-container">.media-page--box-container 3</div>
注意,如果页面上没有元素,方法将返回 null。所以,你应该检查这种情况。如果 box 为 null,则代码将因错误而中断。
const box = document.querySelector('.media-page--box-container');
console.log("box value", box);
// Wrong:
box.addEventListener("click", function() {
console.log("Clicked!");
});
// Correct:
if (box !== null)
box.addEventListener("click", function() {
console.log("Clicked!");
});
<div class="media-page--box-container-A">.media-page--box-container-A</div>
<div class="media-page--box-container-B">.media-page--box-container-B</div>