Chrome 触发鼠标上的关键帧事件

ivqmmu1c  于 2023-09-28  发布在  Go
关注(0)|答案(2)|浏览(110)

我试图触发鼠标悬停事件的CSS动画。不幸的是,它并没有像预期的那样工作。
这就是我所尝试的。我试图在mouseover上实现与CSS中的关键帧声明相同的运动。
它可以在Firefox +Chrome(移动的)中工作,但不能在Chrome(PC)中工作。

const element = document.querySelector('.circ');
element.addEventListener('mouseover', function() {
console.log(1);
    element.style.animation = "move 1000ms infinite ease-in-out alternate";
});
element.addEventListener('mouseout', function() {
//mouseout triggers automatically following mouseover without provocation
console.log(2); 
    element.style.animation = "none";
});
.circ {
     pointer-events: all;
}
 .rect {
     pointer-events: none;
}
 @keyframes move {
     0% {
         transform: translateX(0);
    }
     100% {
         transform: translateX(500px);
    }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
  <div id="container" class="svg-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 100">
      <rect x="0" y="0" width="530" height="200" fill="#EFEFEF"></rect>
      <g class="crcl">  
        <circle class="circ" cx="10" cy="50" r="10" fill="blue"></circle>
      </g>
    </svg>
  </div>

</body>

</html>
qoefvg9y

qoefvg9y1#

动画实际上工作,但它不断重置自己。
问题是:将事件侦听器附加到动画圆圈。
当这个圆圈在鼠标悬停时开始移动时,它几乎会立即触发mouseout事件。
你可能应该在悬停svg或rect时开始和停止动画。

const svg = document.querySelector('svg');
const element = document.querySelector('.circ');
svg.addEventListener('mouseover', function() {
    element.style.animation = "move 1000ms infinite ease-in-out alternate";
});
svg.addEventListener('mouseout', function() {
//mouseout triggers automatically following mouseover without provocation
    element.style.animation = "none";
});
.circ {
     pointer-events: all;
}
 .rect {
     pointer-events: none;
}
 @keyframes move {
     0% {
         transform: translateX(0);
    }
     100% {
         transform: translateX(500px);
    }
}
<div id="container" class="svg-container">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 100">
      <rect x="0" y="0" width="530" height="200" fill="#EFEFEF"></rect>
      <g class="crcl">  
        <circle class="circ" cx="10" cy="50" r="10" fill="blue"></circle>
      </g>
    </svg>
  </div>

示例二:悬停时启动动画;点击停止

const svg = document.querySelector("svg");
const circles = document.querySelectorAll(".circ");

circles.forEach((circ) => {
  circ.addEventListener("mouseover", (e) => {
    let current = e.currentTarget;
    current.classList.add("running");
    //current.style.animation = "move 1000ms infinite ease-in-out alternate";
  });
});

svg.addEventListener("click", function() {
  togglePlayState(circles);
});

function togglePlayState(els) {
  els.forEach((el) => {
    let style = window.getComputedStyle(el);
    if (style.animationPlayState === "running") {
      //el.style.animationPlayState = "paused";
      el.classList.add("paused");
      el.classList.remove("running");

    } else if (el.classList.contains('paused')) {
      //el.style.animationPlayState = "running";
      el.classList.remove("paused");
      el.classList.add("running");
    }
  });
}
.circ {
  pointer-events: all;
}

.rect {}

.ani {
  animation: move 1000ms infinite ease-in-out alternate;
  animation-play-state: paused;
}

.running {
  animation-play-state: running;
}

.paused {
  animation-play-state: paused;
}

@keyframes move {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(500px);
  }
}
<div id="container" class="svg-container">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 100">
      <rect x="0" y="0" width="530" height="200" fill="#EFEFEF"></rect>
      <g class="crcl">  
        <circle class="circ ani" cx="10" cy="50" r="10" fill="blue"></circle>
        <circle class="circ ani" cx="10" cy="75" r="10" fill="green"></circle>
      </g>
    </svg>
</div>
falq053o

falq053o2#

通过覆盖与接收方keyframe元件完全相同的透明元件,可以利用现有的mouseovermouseout实现期望的效果。然后在覆盖的元素上添加一个侦听器,以编程底部元素上的移动。

const data = [
    [0, 0], //bottom for action i=0, top for overlaying i=1
    [1, 1],
    [2, 2]
];

const svg = d3.select('svg');

const grp =
    svg
    .append('g')
    .classed('all', true);

const circ = grp
    .selectAll('g')
    .data(data)
    .join('g')
    .attr('id', (_, i) => i)
    .attr('transform', (_, i) => `translate(0 ${20*(i+1)})`)
    .selectAll('circle')
    .data(function(_, i) {
        return data[i]
    })
    .join('circle')
    .attr('id', function(_, i) {
        return d3.select(this).node().parentNode.id + i
    })
    .attr('cx', (_, i) => 20)
    .attr('cy', (_, i) => 20)
    .attr('r', '5')
    .attr('fill', (_, i) => { if (i === 0) { return 'blue' } else { return 'transparent' } }); //bottom blue, overlay transparent


d3.selectAll('svg g.all g circle:nth-of-type(2)').on('mouseover', function(_, i) {
        d3.select(
                d3.select(this).node().parentElement.firstChild
            ).style('animation', 'move 1000ms infinite ease-in-out alternate')
            
    })
    .on('mouseout', function(_, i) {
        d3.select(
            d3.select(this).node().parentElement.firstChild
        ).style('animation', 'none')
    })
#container>svg>g>g>circle:nth-child(1) {
    pointer-events: none;
}

@keyframes move {
    0% {
        transform: translateX(0);
    }
    100% {
        transform: translateX(500px);
    }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="https://d3js.org/d3.v7.min.js"></script>
    <link rel="stylesheet" href="style.css">
    <title>Document</title>
</head>

<body>
    <div id="container" class="svg-container">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 100">
        <rect x="0" y="0" width="530" height="200" fill="#EFEFEF"></rect>
      </svg>
    </div>
</body>
<script src="prod.js"></script>

</html>

相关问题