如何在原版 javascript 中使用 class 在特定 html 元素上触发事件

How to trigger an event on specific html element with class in vanilla javascript

我正在尝试将我的 jquery 代码重构为原始代码,因为我想正确使用 js。但我遇到了问题。我不知道如何仅在具有特定 class 的第三个元素上触发事件。因为 querySelector 总是 returns 第一个元素 class 例如这是我完成了一半的代码

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>

您可以在代码段中找到示例

这个答案应该强调一些事情。您可能需要以不同方式处理事件冒泡。我在悬停消息中添加了 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>

您可以使用 querySelectorAll 检索与您的选择器匹配的所有节点。

因为它 returns 是一个类似于数组的对象的节点列表,您可以通过调用 array.prototype.foreach 并遍历节点列表来遍历它。

从那里您可以将事件侦听器添加到节点列表中的每个项目,或基于迭代器的任何单个节点。

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>

如果您想为一个元素添加监听器,请使用下面的代码。

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 returns 一个对象,querySelectorAllgetElementsByClassName return 对象数组。不是 getElementsByClassName 需要 class 名称,而不是参数中的选择器。

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>

请注意,如果页面上没有元素,方法将 return 为空。所以,你应该检查这个案例。如果 box 将为空,代码将中断并出现错误。

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>