发布于 2026-01-06 2 阅读
0

使用 JavaScript 自定义光标以获得更好的用户体验

使用 JavaScript 自定义光标以获得更好的用户体验

你有没有注意到现在很流行的一种趋势:网站使用与标准光标不同的自定义光标,使网站在众多网站中脱颖而出?你可能还会好奇这些光标是如何制作出来的。

我在这方面有很多经验,这一切都始于我访问创意表现工作室的网站。我完全被吸引住了。它和我以前见过的任何东西都截然不同!

在本文中,我将向您展示如何创建自定义光标,并讨论何时应该在下一个项目中使用自定义光标。但是,在开始创建自定义光标之前,让我们先来定义一下什么是自定义光标。

为什么要使用自定义光标?

  • 自定义鼠标指针在网页设计中用于为网站增添个性,并为用户带来绝佳的体验。这一简单的添加即可让您的网站脱颖而出。

考虑以下情景:

你的任务是创建一个现代网站,例如带有动画、视差效果和动态元素的作品集网站。

在设计中使用标准光标很可能会显得格格不入。

这是自定义光标如何改善用户体验的绝佳示例。

  • 您还可以使用它们来引导访客前往他们应该去的地方以及应该做什么,从而提供更具吸引力的体验。

考虑到这一点,我们将在着陆页上创建一个自定义光标,以了解如何最大限度地利用此功能来获得更好的用户体验 (UX)。

下图显示了最终设计的预览图:

已完成带有光标事件的着陆页

先决条件

本文假设您已具备以下条件:

  • 掌握HTML
  • CSS(SCSS)知识
  • 掌握 Javascript (ES6) 知识
  • 代码编辑器和浏览器

自定义光标是如何工作的?

我们通过将默认光标更改为我们想要的图像来使用自定义光标。
就像这样:

body {
 cursor: url('image-path.png'), auto;
}
Enter fullscreen mode Exit fullscreen mode

该属性的下一个值是备用值,auto它会将光标设置为默认值,以防图像未加载或找不到图像。添加此备用值非常重要,可以防止您的网站出现光标丢失的情况。

cursor 属性还可以添加到不同的元素,而不仅仅局限于 body 元素。

例如,请查看下面的 Codepen 示例:

创建自定义光标

本节内容已分解为多个步骤,以便于理解。

步骤 1:设置项目

要跟着我的代码一起编写,您可以克隆或下载位于 starter 文件夹中的着陆页设计。

首先,在 IDE 中启动开发服务器,然后打开浏览器。

这是最终的布局,自定义光标将放置在此处。

入门级着陆页

步骤二:添加光标 div

标签index.html之后立即添加以下代码<body>

<div class="cursor-ball"></div>
<div class="cursor-outline"></div>
Enter fullscreen mode Exit fullscreen mode

第一个 div 代表小球光标,第二个 div 代表较大的光标。

接下来,我们将使用 CSS 为这些空 div 设置样式。

步骤 3:设置光标 div 的样式

scss/cursor文件夹内_cursor.scss,我们将添加光标样式。

首先,我们给这两个光标设置样式。

.cursor-ball {
  width: 8px;
  height: 8px;
  background-color: #000;
}

.cursor-outline {
  width: 3rem;
  height: 3rem;
  border: 1px solid #000;
  transition: all 0.5s ease;
}
Enter fullscreen mode Exit fullscreen mode

随着我们不断深入,你会看到……的效果transition

输出结果如下👇

方形的div

这样做光标岂不是很糟糕?它看起来又方又硬。

因此,我们将添加一些两种光标共享的样式:

.cursor-ball,
.cursor-outline {
  border-radius: 50%;
  position: absolute;
  z-index: 100;
  pointer-events: none;
  transform: translate(-50%, -50%)
}
Enter fullscreen mode Exit fullscreen mode

上面的代码块包含一个border-radius将 div 元素变成圆形的元素。

我们添加了一个position,以便我们可以在 Javascript 中absolute更改鼠标光标top及其位置。left

z-index函数100使两个光标位于网页上任何其他元素的上方。

注意:确保在您实现自定义光标的任何项目中,鼠标具有最高的 z-index,这样光标就不会在任何时候被隐藏。

此操作pointer-eventsnone禁用 div 元素上的所有指针事件,以便我们可以选择光标所在 div 元素后面的其他元素。要更好地理解,请参阅文档

transform 属性会将元素移动到中心位置。

现在你应该能在屏幕左上角看到一部分光标了。

步骤四:在屏幕上移动光标

现在,让我们动起来!

app.js文件中,我们将首先提取所需的元素:

let cursorBall = document.querySelector(".cursor-ball");
let cursorOutline = document.querySelector(".cursor-outline");
Enter fullscreen mode Exit fullscreen mode

现在,让我们添加一个事件监听器,以便在鼠标移动时获取鼠标的确切坐标:

document.addEventListener("mousemove", (e) => {
  cursorBall.style.top = e.pageY + "px";
  cursorBall.style.left = e.pageX + "px";

  cursorOutline.style.top = e.pageY + "px";
  cursorOutline.style.left = e.pageX + "px";
});
Enter fullscreen mode Exit fullscreen mode

position因为我们使用 为光标设置了样式absolute,现在可以使用 Javascript 动态修改和 的topleft属性。cursorBallcursorOutline

e.pageYe返回鼠标在屏幕上移动的每次事件在 Y 轴(垂直)上的坐标。

while返回鼠标移动e.pageX每次事件在 X 轴(水平)上的坐标。e

结果如下👇

动画自定义光标

你会注意到,较大的光标跟上较小的光标之间存在延迟cursorOutline。这是因为我们在设置样式时添加了该transition属性all 0.5s ease.cursor-outline

附注:您可以尝试使用不同的值animation-duration。这里我们使用了0.5s,您甚至可以尝试不使用任何过渡属性。

此外,要完全移除默认指针光标,我们需要将以下代码添加到样式表中的 body 标签中cursor: none

这样可以确保只显示我们自定义的光标。

我们之所以能这样做,是因为我们使用的是纯 CSS,它的加载和渲染速度很快。

但是,如果我们选择的图片由于网络故障而无法及时加载,用户体验就会很差。

在这种情况下,添加图像位置url和备用方案auto,正如我们在前面章节中讨论的那样。

目前为止做得非常棒!😃


我们的网页现在应该看起来像这样👇

图片描述

目前我们所做的已经很好了,但我希望我们能更进一步,根据鼠标事件添加更多功能。

更多事件监听器

为了让网页更有趣,我们来给光标添加更多功能:

鼠标抬起和鼠标向下

app.js文件中,我们将使用mousedown事件mouseup类型来监听鼠标按钮何时被按下。

document.addEventListener("mousedown", (e) => {
  if (e.button === 0) {
    cursorOutline.classList.add("cursor-mousedown");
  }
});

document.addEventListener("mouseup", () => {
  cursorOutline.classList.remove("cursor-mousedown");
});
Enter fullscreen mode Exit fullscreen mode

为了使mousedown效果仅在单击鼠标左键时生效,我们使用button属性来选择要使用的鼠标部分。有关此属性的更多信息,请参阅文档button

这段代码翻译过来就是:“如果单击鼠标左键,则将类添加cursor-mousedowncursorOutline.

mouseup当鼠标从被推动的状态释放时,移除cursor-mousedown该类。

然后,前往此处scss/cursor/_cursor.scss添加此新效果的样式:

.cursor-mousedown {
  width: 1.5rem;
  height: 1.5rem;
  border: 2px solid #000;
  background-color: #8454f4;
}
Enter fullscreen mode Exit fullscreen mode

这就是最终效果👇

鼠标悬停事件演示

鼠标悬停和鼠标离开

在 app.js 文件中,要从 DOM 中获取所有社交媒体链接,请在链接的父元素上使用 querySelectorAll:

let links = document.querySelectorAll(".social-links a");
Enter fullscreen mode Exit fullscreen mode

现在,使用 ES6 语法,forEach监听每个social-link链接事件的方法如下:

links.forEach((link) => {
  link.addEventListener("mouseover", () => {
    cursorOutline.classList.add("scale-link");
    link.classList.add("hovered-link");
  });
Enter fullscreen mode Exit fullscreen mode

在上面的代码中,

  • 我们正在监听mouseover每个事件link
  • scale-link我们正在 JavaScript中添加一个类cursorOutline,稍后会在 SCSS 中进行设置。
  • 我们正在添加一个类,hovered-link以便link在光标悬停在链接上时改变链接的外观。

新类的样式:

.scale-link {
  transform: scale(1.5);
  background: #000;
}

.hovered-link {
  color: #fff;
}
Enter fullscreen mode Exit fullscreen mode

这意味着当光标悬停在任何一个元素上时link

  • 它将cursorOutline放大/缩放至原尺寸的 1.5 倍。
  • hovered-link将改变链接的文本颜色。

这就是我们得到的结果👇

附加功能

缩放功能运行良好,但您会注意到以下几点:

  1. cursorOutline即使鼠标悬停在链接上,该功能仍然有效。
  2. 光标不再居中。
  3. 链接没有变成白色。是不是这个hovered-link类没有生效?
  4. 链接位于鼠标下方。

这些是我在开发过程中遇到的挑战,你也可能会遇到;以下是我应对这些挑战的方法。

解决问题#1

这里我们引入一个mouseleave事件,当光标移出目标元素时触发该事件。

仍然在该forEach代码块中,添加以下代码:

link.addEventListener("mouseleave", () => {
    cursorOutline.classList.remove("scale-link");
    link.classList.remove("hovered-link");
  });
Enter fullscreen mode Exit fullscreen mode

基本上,我们只需移除鼠标移出区域scale-link即可hovered-linklink

解决问题#2

问题在于它cursorOutline无法按预期扩展。

我们将在这里对该transfom-origin属性进行实验:

  transform-origin: 130% 100%;
Enter fullscreen mode Exit fullscreen mode

这定义了变换应用的中心点。在本例中,我们将其设置为130%左侧和右侧,以及100%顶部和底部。

请访问MDN了解更多关于此房产的信息。

以下是解决问题 1 和 2 后得到的结果👇

鼠标离开事件

附注
如果您希望显示指针光标,请将其添加cursor: none;到特定元素。

解决问题#3

这个hovered-link方法确实有效,但如果我们使用 Chrome 开发者工具查看,就会发现问题的真正根源在于链接的颜色优先于这个新类。

捕获.PNG

为了解决这个问题,我们可以使用该!important属性,它确实有效。但是,不建议使用此属性,因为它通常会破坏样式表的自然层叠效果。应该谨慎使用。

更好的选择是通过使用以下方式更具体地定义样式:

a.hovered-link {
  color: #fff;
}
Enter fullscreen mode Exit fullscreen mode

要了解更多关于特异性和该!important属性的信息,请点击此处

解决第 4 号问题

如果你还记得的话,我们给光标设置了z-index高亮显示100,这样它们就会位于页面上的每个元素之上,包括链接。

以下是一个快速解决方法:

在要应用效果的元素(例如社交媒体链接)上添加一个z-index“的” 。100

最终结果👇

已完成的页面,带有自定义光标

太棒了!我们成功解决了遇到的问题。自定义光标也已经添加完毕,并且我们还探索了使用鼠标事件监听器的几种交互方式。😎💪

响应能力

最后,在部署项目之前,我们需要添加一个媒体查询,以防止自定义光标出现在没有指针设备的设备上。

因为并非所有人都使用鼠标或触控板,强迫他们使用自定义光标毫无意义,因此我们必须禁用它:

在代码中scss/responsive/_responsive.scss
我们将创建一个 mixin,然后将其包含在代码中。_cursor.scss

@mixin anyPointer {
  @media (any-pointer: fine) {
    @content;
  }
}
Enter fullscreen mode Exit fullscreen mode

让我们把 mixin 添加到 中_cursor.scss,我们已经为两个光标应用了样式。

我们会将默认值设置displaynone,并使用该@include规则将光标设置为仅在用户使用指针设备(例如鼠标或触控板)时才显示光标displayblock

.cursor-ball,
.cursor-outline {
   ...

  display: none; 
  @include anyPointer {
    display: block; 
    pointer-events: none;
  }
}
Enter fullscreen mode Exit fullscreen mode

结论

终于,太棒了!🥳 我们创建了一个很酷的自定义光标,你也了解了自定义光标以及它们如何影响网站的用户体验。

如果您觉得这篇文章有用(我相信您一定觉得有用),请与您的朋友和同事分享,并关注我以获取更多内容。
如果您有任何疑问、发现错误或拼写错误,请在评论区留言。

另外,也请分享一下您的想法。您认为自定义光标是个好主意吗?还有哪些情况下不需要自定义光标?请在评论区留言。

灵感来自网络

文章来源:https://dev.to/israelmitolu/using-custom-cursors-with-javascript-for-a-better-user-experience-1n0b