• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

如何使用 JavaScript 鼠标事件制作多预览缩略图

在本教程中,我们将通过构建一些有用且有趣的东西来享受 javascript 鼠标事件的乐趣:缩略图,当鼠标悬停在上面时,会显示一系列不同的电子书。

这是我们要构建的演示(在每个缩略图上移动鼠标):

See the Pen  How to Make Multi-Preview Thumbnails With JavaScript Mouse Events by Envato Tuts+ (@tutsplus)  on CodePen.

每个缩略图显示隐藏在下面的相应电子书,具体取决于光标位置。这是预览可用内容的理想方式(在本例中位于Envato Tuts+ 电子书库)。

在我们构建它时,我们将使用 css 网格布局和 JavaScript mousemove 事件等。

1.  html 标记

我们将使用的标记非常简单;一个普通的无序列表,每个列表项(卡片)内都有一些大小相同的图像。 

<ul class="cards">

  <li class="card">

    <img src="IMG_SRC" alt="">

    <!-- 4 more images here -->

  </li>

  <li class="card">

    <img src="IMG_SRC" alt="">

    <!-- 3 more images here -->

  </li>

  <li class="card">

    <img src="IMG_SRC" alt="">

    <!-- 2 more images here -->

  </li>

  <li class="card">

    <img src="IMG_SRC" alt="">

    <!-- 1 more image here -->

  </li>

</ul>

2.CSS  _

现在,关于 CSS 样式,有两件事很重要:

  • 我们将无序列表定义为网格容器并给出列表项 width: 25%。除了 CSS 网格,您可以使用 flexbox 或您喜欢的布局方法。

  • 除了第一个之外,我们在视觉上隐藏并绝对定位列表项中的所有图像。

我们应用于演示的 CSS 规则如下所示:

.cards {

  display: grid;

  grid-gap: 20px;

  grid-template-columns: repeat(4, 1fr);

}

 

.card {

  position: relative;

  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5);

}

 

.card:hover {

  cursor: pointer;

}

 

.card img:not(:first-of-type) {

  position: absolute;

  top: 0;

  right: 0;

  bottom: 0;

  left: 0;

  opacity: 0;

}

 

.card img.is-visible {

  opacity: 1;

}

使用其他几种重置样式(从无序列表中删除项目符号,为主体提供背景颜色等),我们最终得到以下结果:

See the Pen  Mouse hover step 2 by Envato Tuts+ (@tutsplus)  on CodePen.

3.  javaScript

让我们添加以下两行,以便当所有页面资源准备好时, init 执行该函数。每次调整浏览器窗口大小时,我们也会触发它。

window.addeventListener("load", init);

window.addEventListener("resize", init);

在这个函数内部,发生了很多事情;首先我们遍历卡片。

function init() {

  const cards = document.queryselectorAll(".card");

  cards.forEach(el => {

    // actions here

  });

 }

循环子图像

接下来,对于每张卡片,我们在不考虑第一张图像的情况下检索子图像的数量。 

注意:默认情况下,第一个图像是可见的,而不是绝对定位的。 

const numOfChildImages = el.querySelectorAll("img:not(:first-of-type)").length;

如果至少有一个子图像,我们会执行以下操作:

  • 计算卡片的宽度(第一张图片的宽度)和...

  • ...通过将卡片的宽度除以子图像的数量将卡片分成相等的部分。

if (numOfChildImages > 0) {

  const { width } = el.getBoundingClientRect();

  const parts = width / numOfChildImages;

}

  • 为了更好地理解这一点,我们假设我们的第一张卡片是 235px 宽。这张卡片包含四张图片(记住我们忽略了第一张图片),所以除法 235px/4 会给我们 58.75px。那么这个号码的作用是什么?好吧,它创建了我们的范围,所以在卡片悬停时,我们跟踪鼠标 X 位置,检查它的范围,最后显示适当的图像。


对于我们的简单示例,以下是生成的范围:

鼠标 X 位置要显示的图像
0<X≤58.75px第1
58.75px<X≤117.5px第2
117.5px<X≤176.25px第3
176.25px<X≤235px第 4

请注意,“要显示的图像”列显示了应该从四个子图像池中显示的图像(我们再次排除了第一个可见图像)。

如何使用 JavaScript 鼠标事件制作多预览缩略图  第1张

现在我们知道了需求,让我们将它们转换为代码。仍然在循环中,我们监听mousemove事件。

// hover cards

el.addEventListener("mousemove", e => {

  // do stuff here

});

当此事件触发时,我们执行以下操作:

  1. 获取鼠标指针相对于“悬停”卡片而不是相对于浏览器窗口的 X 坐标。

  2. is-visible从所有卡片图像中删除类。

  3. 根据鼠标位置显示适当的图像(参见上表的示例)。 

实现上述行为的部分代码如下:

el.addEventListener("mousemove", e => {

  //1

  const xPos = e.pageX - el.offsetLeft;

   

  //2

  removeIsVisibleClass();

   

  //3

  switch (numOfChildImages) {

    case 1:

      if (xPos > 0 && xPos <= parts) {

        addClass(el, "img:nth-child(2)");

      }

      break;

    case 2:

      if (xPos > 0 && xPos <= parts) {

        addClass(el, "img:nth-child(2)");

      } else if (xPos > parts && xPos <= parts * 2) {

        addClass(el, "img:nth-child(3)");

      }

      break;

       

      // more cases below

  }

});

如您所见,有两个自定义函数。首先,removeIsVisibleClass负责is-visible从相应图像中删除类的函数。其次, addClass 负责将is-visible类添加到目标图像的更通用的功能。 

这是他们的签名:

function removeIsVisibleClass() {

  if (document.querySelector("img.is-visible")) {

    document.querySelector("img.is-visible").classList.remove("is-visible");

  }

}

 

function addClass(parent, child, className = "is-visible") {

  parent.querySelector(child).classList.add(className);

}

到目前为止,我们已经看到每次将鼠标悬停在卡片上时会发生什么。现在让我们讨论相反的情况。换句话说,如果我们停止将鼠标悬停在一张卡片上会发生什么。在这种情况下,应显示第一个初始图像:

// inside cards loop

el.addEventListener("mouseleave", () => {

  removeIsVisibleClass();

});

See the Pen  How to Make Multi-Preview Thumbnails With JavaScript Mouse Events by Envato Tuts+ (@tutsplus)  on CodePen.

4. 浏览器支持

我们的演示应该在大多数桌面浏览器中运行良好。不过有几点注意事项:

  • 该演示使用了并非所有浏览器都支持的 CSS Grid和foreach循环。如果您更喜欢使用回退,则两种情况都有替代解决方案。

  • 该演示在所有屏幕/设备上的工作方式相似,并未针对小屏幕/触摸设备进行优化。对于我们的简单演示,这很好,但在实际项目中,您可能希望将此实现仅限于更大的屏幕(或非触摸设备)。

最后,像往常一样,我们使用 Babel 将 ES6 代码编译为 ES5。

结论

在本教程中,我们设法利用 JavaScript 鼠标事件构建了一个有趣的悬停效果。希望你已经受到足够的启发来创造一些令人惊叹的东西。 


文章目录
  • 1. html 标记
  • 2.CSS _
  • 3. javaScript
  • 4. 浏览器支持
  • 结论