如何转换多个项目的动画javascript,"querySelectorAll"不起作用



const ANIMATE_TIMEOUT = 3000 + 200;
const button = document.getElementById("button");
button.addEventListener("click", event => {
if (!button.classList.contains("animate")) {
button.classList.add("animate");
setTimeout(() => {
button.classList.remove("animate");
}, ANIMATE_TIMEOUT);
}
});

我已经试过querySelectorAll

const elementsList = document.querySelectorAll("#button, #button2");
const elementsArray = [...elementsList];
button.addEventListener("click", event => {
if (!button.classList.contains("animate")) {
button.classList.add("animate");
setTimeout(() => {
button.classList.remove("animate");
}, ANIMATE_TIMEOUT);
}

此处建议的解决方案:类似问题

和其他在同一页面中提供的,但是,在所有这些动画都不运行,但querySelectorAll一个不会破坏动画本身,但只适用于第一个项目。提前感谢您的时间***在Zer00ne支持后更新,添加:原始文档与HTML/CSS/JS

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="test sheet">
<meta name="generator" content="test content">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous">
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Amaranth:ital,wght@0,400;0,700;1,700&display=swap"
rel="stylesheet">
<title>test 2 buttons</title>
<link rel="icon" type="image/x-icon" href="/images/favicon.ico">
<link rel="canonical" href="https://www.google.com">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
</head>
<body data-bs-spy="scroll" data-bs-target=".navbar" data-bs-offset="50">
<style>
body {
font-family: 'Amaranth', sans-serif;
background: url(https://images.pexels.com/photos/531602/pexels-photo-531602.jpeg) no-repeat center center fixed;
-webkit-background-size: cover;
background-size: cover;
overflow: auto;
opacity: 99%;
overflow-x: hidden;
background-repeat: no-repeat;
background-position: center;
position: relative;
}
.z {
margin-top: 60px;
padding-top: 60px;
}
h1 {
position: relative;
text-align: center;
color: #353535;
font-size: 50px;
font-family: "Cormorant Garamond", serif;
}    
.frame {
width: 90%;
margin: 40px auto;
text-align: center;
}    
.copy-button {
height: 25px;
display: flex;
justify-content: center;
align-items: center;
position: relative
} 
:root {
/* Scale setup */
--button-height: 27;
/* in px */
--height-to-scale: 33;
/* in px */
--scale-ratio: calc(var(--height-to-scale) / var(--button-height));
/* Slide setup */
--button-height-px: 27px;
--button-vertical-padding-px: 6px;
--button-content-spacing-px: calc(var(--button-height-px) + var(--button-vertical-padding-px) * 2);
--slide-step-1: calc(var(--button-height-px) * -1);
--slide-step-2: calc(var(--button-height-px) * -2);
}
.wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 33px;
}
/* Button styles */
.button {
display: flex;
justify-content: center;
align-items: start;
flex-wrap: nowrap;
height: var(--button-height-px);
padding: var(--button-vertical-padding-px) 9px;
border-style: none;
border-radius: 6px;
background-color: #f3f6f9;
color: #708ebc;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 12.605px;
line-height: 15px;
cursor: pointer;
transition: all 200ms;
}
.button:hover {
background-color: #e4ebf2;
color: #708ebc;
}
.button:focus {
background-color: #e4ebf2;
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.7);
outline: none;
}
.button:active {
background-color: #10428f;
color: #f3f6f9;
}
.copy {
display: flex;
align-items: center;
justify-content: start;
}
.icon {
margin-right: 6px;
}
/* Align content to animate */
.button {
overflow: hidden;
}
.copied {
visibility: hidden;
margin-top: var(--button-content-spacing-px);
}
/* Animations */
.button.animate {
background-color: #10428f;
color: #b6c8eb;
box-shadow: none;
animation: scale 3s cubic-bezier(1, -0.5, 0, 1.5) forwards;
}
.animate .content {
animation: slide 3s cubic-bezier(1, -0.5, 0, 1.5) forwards;
}
.animate .copied {
visibility: visible;
}
@keyframes scale {
0% {
transform: none;
}
12.5% {
transform: none;
}
25% {
transform: scale(var(--scale-ratio));
}
37.5% {
transform: scale(var(--scale-ratio));
}
50% {
transform: none;
}
100% {
transform: none;
}
}
@keyframes slide {
0% {
transform: none;
}
12.5% {
transform: translateY(var(--slide-step-1));
}
25% {
transform: translateY(var(--slide-step-1));
}
37.5% {
transform: translateY(var(--slide-step-2));
}
87.5% {
transform: translateY(var(--slide-step-2));
}
100% {
transform: none;
}
}
body {
position: relative;
}
@media (max-width: 767px) {}
::-webkit-scrollbar {
display: none;
}
.dropdown-menu {
max-height: 280px;
overflow-y: auto;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
</style>

<div class="wrapper">
<button onclick="copy('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod')"
class="button copy-button  " type="button" id="button" title="Copy link">
<div class="content ">
<div class="copy">           
<div>
Copy Link
</div>
</div>
<div class="copied">Copied!</div>
</div>
</button>
</div>

<script>
const ANIMATE_TIMEOUT = 3000 + 200;
const button = document.getElementById("button");
button.addEventListener("click", event => {
if (!button.classList.contains("animate")) {
button.classList.add("animate");
setTimeout(() => {
button.classList.remove("animate");
}, ANIMATE_TIMEOUT);
}
});</script>

<script>

document.querySelectorAll('[data-bs-toggle="tooltip"]')
.forEach(tooltip => {
new bootstrap.Tooltip(tooltip)
})
</script>


<script>
function copy(text, target) {
setTimeout(function () {
$('#copied_tip').remove();
}, 800);
$(target).append("<div class='tip' id='copied_tip'>Copied!</div>");
var input = document.createElement('input');
input.setAttribute('value', text);
document.body.appendChild(input);
input.select();
var result = document.execCommand('copy');
document.body.removeChild(input)
return result;
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.10/dist/clipboard.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/3.1.2/svg.min.js" integrity="sha512-I+rKw3hArzZIHzrkdELbKqrXfkSvw/h0lW/GgB8FThaBVz2e5ZUlSW8kY8v3q6wq37eybIwyufkEZxe4qSlGcg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

</body>
</html>

在我开始写这个答案的时候,这个问题还没有HTML。我会用OP添加的HTML更新这个答案,但是JavaScript几乎不匹配HTML,所以它不是关键。这个答案中的HTML和JavaScript是通用的,所以适应典型的HTML布局应该不是很困难。

详细信息在示例中被注释

// Collect all <button>s into an array
const btns = [...document.querySelectorAll('button')];
// Bind click event to each <button>
btns.forEach(btn => btn.addEventListener("click", animate));
/*
Event handler passes Event Object as default
On click, toggle .increase/.decrease classes on the clicked <button>
*/
function animate(event) {
this.classList.toggle('increase');
this.classList.toggle('decrease');
}
// Added to stop animation from running when page is loaded 
document.addEventListener('DOMContentLoaded', function() {
setTimeout(() => btns.forEach(btn => btn.classList.remove('x')), 1000);
});


@keyframes inc {
0% {
transform: scale(1);
}
100% {
transform: scale(1.5);
}
}
@keyframes dec {
0% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
button {
display: flex;
justify-content: center;
align-items: center;
margin: 13px;
padding: 3px 5px;
cursor: pointer;
}
.decrease {
animation: 0.5s linear forwards dec;
}
.increase {
animation: 0.5s linear forwards inc;
}
.decrease::before {
content: '➕';
}
.increase::before {
content: '➖';
}
.x.x {
animation: 9999999s forwards paused;
}
<menu>
<button class='decrease x'></button>
<button class='decrease x'></button>
<button class='decrease x'></button>
<button class='decrease x'></button>
<button class='decrease x'></button>
<button class='decrease x'></button>
</menu>

最新更新