与光标移动功能一起使用时出现光标悬停问题

问题描述 投票:0回答:1

我正在尝试创建一个自定义鼠标光标,其中主体标记根据鼠标光标的状态应用一些类。 喜欢:

  1. 光标移动:每当鼠标移动时
  2. cursor-idle:每当鼠标空闲时
  3. 光标悬停:每当鼠标移到
    anchor
    button
    标签上时。

但是当我尝试将鼠标悬停在链接元素上时,这段 JavaScript 代码不起作用。我尝试制作一个控制台,它显示

cursor-hover
正在工作,但非常间歇性,而且也持续了一小会儿。

提示:我还编写了一种样式,当这个

background-color
起作用时,它会改变
body
hover

const customCursor = document.querySelector(".cursor");
let isCursorMoving = false;
let cursorIdleTimeout;
let isCursorOverLink = false;

function updateCursor(event) {
  const x = event.clientX + "px";
  const y = event.clientY + "px";

  customCursor.style.setProperty("--cursor-left", x);
  customCursor.style.setProperty("--cursor-top", y);

  if (!isCursorMoving) {
    document.body.classList.add("cursor-moving");
    document.body.classList.remove("cursor-idle");
    clearTimeout(cursorIdleTimeout);
  }

  cursorIdleTimeout = setTimeout(() => {
    isCursorMoving = false;
    document.body.classList.remove("cursor-moving");
    document.body.classList.add("cursor-idle");
  }, 1000);
}

function handleLinkEnter(event) {
  if (event.target.tagName === "A" || event.target.tagName === "BUTTON") {
    document.body.classList.add("cursor-hover");
  }
}

function handleLinkLeave(event) {
  if (event.target.tagName === "A" || event.target.tagName === "BUTTON") {
    document.body.classList.remove("cursor-hover");
  }
}

document.addEventListener("mousemove", updateCursor);
document.addEventListener("mouseenter", handleLinkEnter);
document.addEventListener("mouseleave", handleLinkLeave);
* {
  box-sizing: border-box;
}

body {
  background: #3f3f3f;
}

:root {
  --cursor-size: 32px;
  --tail-size: 1px;
  --tail-gap: 48px;
  --tail-color: #111;
  --cursor-color: #fff;
}

.cursor {
  position: fixed;
  left: var(--cursor-left, 0);
  top: var(--cursor-top, 0);
  width: var(--cursor-width, var(--cursor-size));
  height: var(--cursor-height, var(--cursor-size));
  z-index: 999999;
}

.cursor::before,
.cursor::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  background: var(--cursor-color);
  transform: translate(-50%, -50%);
}

.cursor::before {
  width: 1px;
  height: var(--cursor-size);
}

.cursor::after {
  width: var(--cursor-size);
  height: 1px;
}

.cursor .tail {
  position: absolute;
  left: 0;
  top: 0;
  background: var(--tail-color);
  opacity: 0.6;
}

.cursor .tail::before {
  content: "";
  position: absolute;
  background: var(--tail-color);
}

.cursor .tail-x {
  width: 100vw;
  height: var(--tail-size);
  left: var(--tail-gap);
}

.cursor .tail-x::before {
  left: calc(-100vw - var(--tail-gap) - var(--tail-gap));
  right: 0;
  width: 100vw;
  height: var(--tail-size);
}

.cursor .tail-y {
  width: var(--tail-size);
  height: 100vh;
  top: var(--tail-gap);
}

.cursor .tail-y::before {
  top: calc(-100vw - var(--tail-gap) - var(--tail-gap));
  bottom: 0;
  height: 100vw;
  width: var(--tail-size);
}

body {
  display: grid;
  height: 100vh;
  width: 100vw;
  place-items: center;
}

body.cursor-hover {
  background: yellow;
}

body.cursor-hover a {
  color: #000;
}

a {
  display: inline-block;
  color: #fff;
  padding: 4px;
}
<div class="cursor">
  <span class="tail tail-x"></span>
  <span class="tail tail-y"></span>
</div>

<a href="#">Link</a>

javascript css cursor mouseevent mousehover
1个回答
0
投票

首先,您用

.cursor
遮盖了链接,因为
.cursor
具有更大的
z-index
。因此,应给予
.cursor
pointer-events:none;

其次,您在

mouseenter
上调用
mouseleave
document
事件,它们不会以任何方式影响链接。

稍微修正了你的代码:

const customCursor = document.querySelector('.cursor');
let isCursorMoving = false;
let cursorIdleTimeout;
let isCursorOverLink = false;

function updateCursor(event) {
  const {clientX, clientY} = event;
  customCursor.style.transform = `translate3d(${clientX}px, ${clientY}px, 0)`;
  
  if (event.target.tagName === 'A' || event.target.tagName === 'BUTTON') {
    document.body.classList.add('cursor-hover');
  } else {
      document.body.classList.remove('cursor-hover');
  }

  if (!isCursorMoving) {
    document.body.classList.add('cursor-moving');
    document.body.classList.remove('cursor-idle');
    clearTimeout(cursorIdleTimeout);
  }

  
  cursorIdleTimeout = setTimeout(() => {
    isCursorMoving = false;
    document.body.classList.remove('cursor-moving');
    document.body.classList.add('cursor-idle');
  }, 1000);
}

window.addEventListener('mousemove', updateCursor);
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  cursor: none;
}

:root {
  --cursor-size: 32px;
  --tail-size: 1px;
  --tail-gap: 48px;
  --tail-color: #111;
  --cursor-color: #fff;
}

body {
  background: #3f3f3f;
  display: grid;
  height: 100dvh;
  place-items: center;
  overflow:hidden;
  transition: background-color .4s;
}

body.cursor-hover {
  background: yellow;
}

body.cursor-hover .cursor {
  color:blue;
}

body.cursor-hover a {
  color: #000;
}

a {
  color: #fff;
  padding: 4px;
}

.cursor {
  pointer-events: none;
  position: fixed;
  width: var(--cursor-size);
  height: var(--cursor-size);
  margin: calc(var(--cursor-size) / -2) 0 0 calc(var(--cursor-size) / -2);
  left: 0;
  top: 0;
  color: var(--cursor-color);
  transition: color .4s;
  z-index: 666;
}

.cursor:before,
.cursor:after {
  content: '';
  position: absolute;
  inset: calc(50% - var(--tail-size) / 2) 0 auto 0;
  background: currentColor;
  height: var(--tail-size);
}

.cursor::after {
  transform: rotate(90deg);
}

.cursor .tail {
  position: absolute;
  inset: 0;
  opacity: 0.6;
}

.cursor .tail:before,
.cursor .tail:after {
  content: '';
  position: absolute;
  background: var(--tail-color);
}

.cursor .tail-x:before,
.cursor .tail-x:after {
  top:calc(50% - var(--tail-size) / 2);
  height: var(--tail-size);
  width:100vmax;
}

.cursor .tail-x:before {
  right: calc(100% + var(--tail-gap))
}

.cursor .tail-x:after {
  left: calc(100% + var(--tail-gap))
}

.cursor .tail-y:before,
.cursor .tail-y:after {
  left: calc(50% - var(--tail-size) / 2);
  width: var(--tail-size);
  height: 100vmax;
}

.cursor .tail-y:before {
  bottom: calc(100% + var(--tail-gap))
}

.cursor .tail-y:after {
  top:calc(100% + var(--tail-gap))
}
<div class="cursor">
  <span class="tail tail-x"></span>
  <span class="tail tail-y"></span>
</div>
<a href="#">Link</a>

© www.soinside.com 2019 - 2024. All rights reserved.