首页 > 解决方案 > CSS 动画仅在第一次触发

问题描述

我正在制作一个以巫师为主题的页面作为一个副项目并且遇到了一个问题。我制作了一个炼金术页面,列出了所有成分,旁边还有所有可以提取的元素。我用以下逻辑制作了一个触发动画的函数:单击一种成分将触发可以从该成分中提取的相应元素的动画。例如:傻瓜欧芹可以产生红叶和硫酸,点击傻瓜欧芹,红叶会发出红色和硫酸蓝色。我的问题是,一旦动画被触发一次,如果需要另一种成分,它就不会再次触发。示例:傻瓜欧芹使 rubedo 和硫酸发光,尸胺使 rubedo 和乙醚发光。如果我点击傻瓜欧芹,然后点击尸胺,当点击尸胺时,只有以太会发光,因为 rubedo 已经触发过一次。这也使得单击相同的成分两次毫无意义,因为第二次没有任何元素会发光。

这是代码:

HTML

<!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>Alchemy</title>
<link rel="stylesheet" href="alchemy-page-style.css">
</head>
<body>

<script type="text/javascript" src="alchemy-page.js"></script>




<!--<audio id="source" autoplay loop>
    <source src="C:\Users\user\AngularProjects\The ModernWitcher's Journal\audio\pages\home-page-theme.mp3">
</audio>-->



<div class="container">

    <br>
    <h1 class="homepage-title">
        <img src="../images/witcher-transparent.png"
        class="witcher-transparent-logo">
        Alchemy
        <img src="../images/witcher-transparent.png"
        class="witcher-transparent-logo">
    </h1>
    
    <div class="grid-col">

        <div class="grid-ingredients">
            <div>
                <ul>
                    <h2>Herbal Extracts</h2>

                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Allspice_root.png);"
                    onclick="lightUpElements(['aether', 'nigredo'])">Allspice root</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Balisse_fruit.png);"
                    onclick="lightUpElements(['quebirth', 'rubedo'])">Balisse fruit</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Beggartick_blossom.png);"
                    onclick="lightUpElements(['hydragenum', 'rubedo'])">Beggartick blossom</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Berbercane_fruit.png);"
                    onclick="lightUpElements(['aether', 'albedo'])">Berbercane fruit</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Bryonia.png);"
                    onclick="lightUpElements(['vermilion', 'nigredo'])">Bryonia</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Celandine.png);"
                    onclick="lightUpElements(['rebis', 'nigredo'])">Celandine</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Crows_eye.png);"
                    onclick="lightUpElements(['vitriol', 'nigredo'])">Crow's eye</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Ergot_seeds.png);"
                    onclick="lightUpElements(['vermilion', 'rubedo'])">Ergot seeds</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Feainnewedd.png);"
                    onclick="lightUpElements(['vermilion', 'rubedo'])">Feainnewedd</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Fools_parsley_leaves.png);"
                    onclick="lightUpElements(['quebirth', 'rubedo'])">Fool's parsley leaves</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Ginatia_petals.png);"
                    onclick="lightUpElements(['aether', 'nigredo'])">Ginatia petals</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Green_mold.png);"
                    onclick="lightUpElements(['rebis', 'rubedo'])">Green mold</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Han.png);"
                    onclick="lightUpElements(['rebis', 'nigredo'])">Han</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Hellebore_petals.png);"
                    onclick="lightUpElements(['aether', 'rubedo'])">Hellebore petals</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Honeysuckle.png);"
                    onclick="lightUpElements(['quebirth', 'albedo'])">Honeysuckle</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Hop_umbels.png);"
                    onclick="lightUpElements(['vitriol', 'nigredo'])">Hop umbels</li>
                    <li
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Mandrake_root.png);"
                    onclick="lightUpElements(['quebirth', 'nigredo'])">Mandrake root</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Mistletoe.png);"
                    onclick="lightUpElements(['hydragenum', 'nigredo'])">Mistletoe</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Sewants.png);"
                    onclick="lightUpElements(['vitriol', 'rubedo'])">Sewant mushroom</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Verbena.png);"
                    onclick="lightUpElements(['quebirth', 'albedo'])">Verbena</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/White_myrtle_petals.png);"
                    onclick="lightUpElements(['vitriol', 'albedo'])">White myrtle petals</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Wolfs_aloe.png);"
                    onclick="lightUpElements(['hydragenum', 'albedo'])">Wolf's aloe leaves</li>
                    <li 
                    style="list-style-image: url(../images/icons/alchemy/ingredients/herbs/Wolfsbane.png);"
                    onclick="lightUpElements(['vermilion', 'albedo'])">Wolfsbane</li>
                </ul>

                

        <div class="grid-elements">
            <div>
                <ul>
                    <h2>Elements</h2>
                    <li style="list-style-image: url(../images/icons/alchemy/elements/Vitriol.png);" >
                        <span id="vitriol">Vitriol</span>
                    </li>
                    <li style="list-style-image: url(../images/icons/alchemy/elements/Rebis.png);">
                        <span id="rebis">Rebis</span>
                    </li>
                    <li style="list-style-image: url(../images/icons/alchemy/elements/Aether.png);">
                        <span id="aether">Aether</span>
                    </li>
                    <li style="list-style-image: url(../images/icons/alchemy/elements/Quebrith.png);">
                        <span id="quebirth">Quebirth</span>
                    </li>
                    <li style="list-style-image: url(../images/icons/alchemy/elements/Hydragenum.png);">
                        <span id="hydragenum">Hydragenum</span>
                    </li>
                    <li style="list-style-image: url(../images/icons/alchemy/elements/Vermilion.png);">
                        <span id="vermilion">Vermilion</span>
                    </li>
                    <li style="list-style-image: url(../images/icons/alchemy/elements/Albedo.png);">
                        <span id="albedo">Albedo</span>
                    </li>
                    <li style="list-style-image: url(../images/icons/alchemy/elements/Nigredo.png);">
                        <span id="nigredo">Nigredo</span>
                    </li>
                    <li style="list-style-image: url(../images/icons/alchemy/elements/Rubedo.png);">
                        <span id="rubedo">Rubedo</span>
                    </li>
                </ul>
            </div>
        </div>

        <div class="grid-descriptions">
            <p id="description"></p>
        </div>

    </div>
    
</div>

</body>
</html>

JS

let elementList = [];
let color = '';
var i = 0;

const vitriol = document.getElementById('vitriol');
const rebis = document.getElementById('rebis');
const aether = document.getElementById('aether');
const quebirth = document.getElementById('quebirth');
const hydragenum = document.getElementById('hydragenum');
const vermilion = document.getElementById('vermilion');
const albedo = document.getElementById('albedo');
const nigredo = document.getElementById('nigredo');
const rubedo = document.getElementById('rubedo');

function lightUpElements(elementList)
{
for(i = 0; i < elementList.length; i++)
{
    if(elementList[i] == 'vitriol')
    {
        this.vitriol.style.animation = "vitriolShine 0.5s alternate 6";
    }

    if(elementList[i] == 'rebis')
    {
        this.rebis.style.animation = "rebisShine 0.5s alternate 6";
    }

    if(elementList[i] == 'hydragenum')
    {
        this.hydragenum.style.animation = "hydragenumShine 0.5s alternate 6";
    }

    if(elementList[i] == 'quebirth')
    {
        this.quebirth.style.animation = "quebirthShine 0.5s alternate 6";
    }

    if(elementList[i] == 'vermilion')
    {
        this.vermilion.style.animation = "vermilionShine 0.5s alternate 6";
    }

    if(elementList[i] == 'albedo')
    {
        this.albedo.style.animation = "albedoShine 0.5s alternate 6";
    }

    if(elementList[i] == 'nigredo')
    {
        this.nigredo.style.animation = "nigredoShine 0.5s alternate 6";
    }

    if(elementList[i] == 'rubedo')
    {
        this.rubedo.style.animation = "rubedoShine 0.5s alternate 6";
    }

    if(elementList[i] == 'aether')
    {
        this.aether.style.animation = "aetherShine 0.5s alternate 6";
    }
}
}

CSS

@font-face {
src: url(../fonts/FantaisieArtistique/FantaisieArtistique.ttf);
font-family: witcher;
}

@font-face {
font-family: wonderland;
src: url(../fonts/BeyondWonderland/Beyond\ Wonderland.ttf);
}

@font-face {
font-family: witcher-videogame;
src: url(fonts/WitcherVideogame/Thewitcher-jnOj.ttf);
}

@font-face {
font-family: journal;
src: url(../fonts/Journal/Handwritten_Crystal_v2.ttf);
}

@keyframes elementsFadeIn {
from{opacity: 0;}
to{opacity: 1;}
}

@keyframes vitriolShine {
from{opacity: 1;}
to
{
    background-color: rgba(0, 217, 255, 0.507);
    border-radius: 10px;
}
}

@keyframes rebisShine {
from{opacity: 1;}
to
{
    background-color: rgba(0, 255, 76, 0.507);
    border-radius: 10px;
}
}

@keyframes aetherShine {
from{opacity: 1;}
to
{
    background-color: rgba(195, 0, 255, 0.507);
    border-radius: 10px;
}
}

@keyframes quebirthShine {
from{opacity: 1;}
to
{
    background-color: rgba(251, 255, 0, 0.507);
    border-radius: 10px;
}
}

@keyframes hydragenumShine {
from{opacity: 1;}
to
{
    background-color: rgb(226, 226, 226);
    border-radius: 10px;
}
}

@keyframes vermilionShine {
from{opacity: 1;}
to
{
    background-color: rgba(109, 74, 0, 0.541);
    border-radius: 10px;
}
}

@keyframes albedoShine {
from{opacity: 1;}
to
{
    background-color: rgb(255, 255, 255);
    border-radius: 10px;
}
}

@keyframes nigredoShine {
from{opacity: 1;}
to
{
    background-color: rgba(0, 0, 0, 0.541);
    border-radius: 10px;
}
}

@keyframes rubedoShine {
from{opacity: 1;}
to
{
    background-color: rgba(109, 0, 0, 0.541);
    border-radius: 10px;
}
}

html, body
{
height: 100%;
margin: 0;
padding: 0;
}

.container
{
background-image: url(../images/witcher-bestiary-background.jpg);
height: max-content;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
margin: 0 auto;
position: relative;
text-align: center;
animation: elementsFadeIn 1s;
}

.homepage-title
 {
margin: 0 auto;
font-family: witcher;
font-size: 45px;
color: rgb(189, 0, 0);
animation: elementsFadeIn 2s;
}

.homepage-title .witcher-transparent-logo
{
bottom: 0;
background: rgba(231, 228, 228, 0.342);
border-radius: 5px;
border-style:hidden;
height: 30px;
width: 30px;
animation: elementsFadeIn 3s;
}

.grid-col
{
display:grid;
grid-template-columns: repeat(2, 300px);
justify-content: center;
padding-bottom: 50px;
margin-top: 5vh;
}

h2
{
font-family: journal;
color: rgb(180, 0, 0);
}

li
{
font-family: journal;
font-size: large;
list-style-position: inside;
justify-content: center;
}

.grid-ingredients
{
display: grid;
grid-template-columns: repeat(1);
height: max-content;
border: 10px solid transparent;
padding: 0px;
border-image: url(../images/border.png) 70 round;
background-image: url(../images/icons/notebook-clipart-old-writing-paper-5.png);
background-repeat:repeat-y;
background-position: center;
background-size: 120% 120%;
}

.grid-ingredients li:hover
{
cursor: pointer;
}

.grid-elements
{
display: grid;
grid-template-columns: repeat(1);
top: 0;
position: sticky;
height: max-content;
background-image: url(../images/icons/notebook-clipart-old-writing-paper-5.png);
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}

似乎是一个非常基本的 JS 问题,但我被卡住了,似乎找不到解决方法。先感谢您!

标签: javascripthtmlcssif-statementcss-animations

解决方案


诚然,这不应该是一个code restructuring discussion问题,但是有一种方法可以使用animationend事件来解决这个问题,并通过相关的回调删除通过单击 Herbal 提取物分配的动画。

您会注意到,其中大部分是使用 Javascript 完成的,而不是大量的内联样式和函数调用 - 它使 (imo) 更容易扩展和维护,但其他人可能会对此作出判断。

您可以从中获得的重要部分是分配给每个 Herbal Extract li 元素的事件侦听器 - 如下所示:

const extracts={
    'Allspice root':['aether', 'nigredo'],
    'Balisse fruit':['quebirth', 'rubedo'],
    'Beggartick blossom':['hydragenum', 'rubedo'],
    'Berbercane fruit':['aether', 'albedo'],
    'Bryonia':['vermilion', 'nigredo'],
    'Celandine':['rebis', 'nigredo'],
    'Crow\'s eye':['vitriol', 'nigredo'],
    'Ergot seeds':['vermilion', 'rubedo'],
    'Feainnewedd':['vermilion', 'rubedo'],
    'Fool\'s parsley leaves':['quebirth', 'rubedo'],
    'Ginatia petals':['aether', 'nigredo'],
    'Green mold':['rebis', 'rubedo'],
    'Han':['rebis', 'nigredo'],
    'Hellebore petals':['aether', 'rubedo'],
    'Honeysuckle':['quebirth', 'albedo'],
    'Hop umbels':['vitriol', 'nigredo'],
    'Mandrake root':['quebirth', 'nigredo'],
    'Mistletoe':['hydragenum', 'nigredo'],
    'Sewant mushroom':['vitriol', 'rubedo'],
    'Verbena':['quebirth', 'albedo'],
    'White myrtle petals':['vitriol', 'albedo'],
    'Wolf\'s aloe leaves':['hydragenum', 'albedo'],
    'Wolfsbane':['vermilion', 'albedo']
};
const images={
  'elements':{
    'Vitriol':'../images/icons/alchemy/elements/Vitriol.png',
    'Rebis':'../images/icons/alchemy/elements/Rebis.png',
    'Aether':'../images/icons/alchemy/elements/Aether.png',
    'Quebirth':'../images/icons/alchemy/elements/quebirth.png',
    'Hydragenum':'../images/icons/alchemy/elements/Hydragenum.png',
    'Vermilion':'../images/icons/alchemy/elements/Vermilion.png',
    'Albedo':'../images/icons/alchemy/elements/Albedo.png',
    'Nigredo':'../images/icons/alchemy/elements/Nigredo.png',
    'Rubedo':'../images/icons/alchemy/elements/Rubedo.png',
  },
  'ingredients':{
    'Allspice root':'../images/icons/alchemy/ingredients/herbs/Allspice_root.png',
    'Balisse fruit':'../images/icons/alchemy/ingredients/herbs/Balisse_fruit.png',
    'Beggartick blossom':'../images/icons/alchemy/ingredients/herbs/Beggartick_blossom.png',
    'Berbercane fruit':'../images/icons/alchemy/ingredients/herbs/Berbercane_fruit.png',
    'Bryonia':'../images/icons/alchemy/ingredients/herbs/Bryonia.png',
    'Celandine':'../images/icons/alchemy/ingredients/herbs/Celandine.png',
    'Crow\'s eye':'../images/icons/alchemy/ingredients/herbs/Crows_eye.png',
    'Ergot seeds':'../images/icons/alchemy/ingredients/herbs/Ergot_seeds.png',
    'Feainnewedd':'../images/icons/alchemy/ingredients/herbs/Feainnewedd.png',
    'Fool\'s parsley leaves':'../images/icons/alchemy/ingredients/herbs/Fools_parsley_leaves.png',
    'Ginatia petals':'../images/icons/alchemy/ingredients/herbs/Ginatia_petals.png',
    'Green mold':'../images/icons/alchemy/ingredients/herbs/Green_mold.png',
    'Han':'../images/icons/alchemy/ingredients/herbs/Han.png',
    'Hellebore petals':'../images/icons/alchemy/ingredients/herbs/Hellebore_petals.png',
    'Honeysuckle':'../images/icons/alchemy/ingredients/herbs/Honeysuckle.png',
    'Hop umbels':'../images/icons/alchemy/ingredients/herbs/Hop_umbels.png',
    'Mandrake root':'../images/icons/alchemy/ingredients/herbs/Mandrake_root.png',
    'Mistletoe':'../images/icons/alchemy/ingredients/herbs/Mistletoe.png',
    'Sewant mushroom':'../images/icons/alchemy/ingredients/herbs/Sewants.png',
    'Verbena':'../images/icons/alchemy/ingredients/herbs/Verbena.png',
    'White myrtle petals':'../images/icons/alchemy/ingredients/herbs/White_myrtle_petals.png',
    'Wolf\'s aloe leaves':'../images/icons/alchemy/ingredients/herbs/Wolfs_aloe.png',
    'Wolfsbane':'../images/icons/alchemy/ingredients/herbs/Wolfsbane.png'
  }
};

const q=(e,n=document)=>n.querySelector(e);

Object.keys( extracts ).forEach( k=>{
  let li=document.createElement('li');
      li.style.listStyleImage=images.ingredients[k];
      li.textContent=k;
      li.dataset.elements=extracts[ k ];
      li.addEventListener('click',function(e){
        [ ...this.dataset.elements.split(',') ].forEach( element=>{
          let node=q('.grid-elements li[data-name="'+element+'"]');
              node.style.animation=element + 'Shine 0.5s alternate 6';
              /*
                this is what removes the assigned animation
                and prepares it for a new invocation.
              */
              node.addEventListener('animationend', ()=>{
                node.removeAttribute('style');
              });
        });
      });
  q('.grid-ingredients ul').appendChild( li );
});



Object.keys( images.elements ).forEach( k=>{
  let li=document.createElement('li');
      li.style.listStyleImage=images.elements[ k ];
      li.dataset.name=k.toLowerCase();
      
  let span=document.createElement('span');
      span.textContent=k;
  li.appendChild( span );
  
  q('.grid-elements ul').appendChild( li );
})
@font-face {
  src: url(../fonts/FantaisieArtistique/FantaisieArtistique.ttf);
  font-family: witcher;
}
@font-face {
  font-family: wonderland;
  src: url(../fonts/BeyondWonderland/Beyond/Wonderland.ttf);
}
@font-face {
  font-family: witcher-videogame;
  src: url(fonts/WitcherVideogame/Thewitcher-jnOj.ttf);
}
@font-face {
  font-family: journal;
  src: url(../fonts/Journal/Handwritten_Crystal_v2.ttf);
}




@keyframes elementsFadeIn {
  from{opacity: 0;}
  to{opacity: 1;}
}
@keyframes vitriolShine {
  from{opacity: 1;}
  to{
    background-color: rgba(0, 217, 255, 0.507);
    border-radius: 10px;
  }
}
@keyframes rebisShine {
  from{opacity: 1;}
  to
  {
      background-color: rgba(0, 255, 76, 0.507);
      border-radius: 10px;
  }
}
@keyframes aetherShine {
  from{opacity: 1;}
  to
  {
      background-color: rgba(195, 0, 255, 0.507);
      border-radius: 10px;
  }
}
@keyframes quebirthShine {
  from{opacity: 1;}
  to
  {
      background-color: rgba(251, 255, 0, 0.507);
      border-radius: 10px;
  }
}
@keyframes hydragenumShine {
  from{opacity: 1;}
  to
  {
      background-color: rgb(226, 226, 226);
      border-radius: 10px;
  }
}
@keyframes vermilionShine {
  from{opacity: 1;}
  to
  {
      background-color: rgba(109, 74, 0, 0.541);
      border-radius: 10px;
  }
}
@keyframes albedoShine {
  from{opacity: 1;}
  to
  {
      background-color: rgb(255, 255, 255);
      border-radius: 10px;
  }
}
@keyframes nigredoShine {
  from{opacity: 1;}
  to
  {
      background-color: rgba(0, 0, 0, 0.541);
      border-radius: 10px;
  }
}
@keyframes rubedoShine {
  from{opacity: 1;}
  to
  {
      background-color: rgba(109, 0, 0, 0.541);
      border-radius: 10px;
  }
}




html, body
{
  height: 100%;
  margin: 0;
  padding: 0;
}

.container
{
  background-image: url(../images/witcher-bestiary-background.jpg);
  height: max-content;
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  margin: 0 auto;
  position: relative;
  text-align: center;
  animation: elementsFadeIn 1s;
}

.homepage-title
 {
  margin: 0 auto;
  font-family: witcher;
  font-size: 45px;
  color: rgb(189, 0, 0);
  animation: elementsFadeIn 2s;
}

.homepage-title .witcher-transparent-logo
{
  bottom: 0;
  background: rgba(231, 228, 228, 0.342);
  border-radius: 5px;
  border-style:hidden;
  height: 30px;
  width: 30px;
  animation: elementsFadeIn 3s;
}

.grid-col
{
  display:grid;
  grid-template-columns: repeat(2, 300px);
  justify-content: center;
  padding-bottom: 50px;
  margin-top: 5vh;
}

h2
{
  font-family: journal;
  color: rgb(180, 0, 0);
}

li
{
  font-family: journal;
  font-size: large;
  list-style-position: inside;
  justify-content: center;
}

.grid-ingredients
{
  display: grid;
  grid-template-columns: repeat(1);
  height: max-content;
  border: 10px solid transparent;
  padding: 0px;
  border-image: url(../images/border.png) 70 round;
  background-image: url(../images/icons/notebook-clipart-old-writing-paper-5.png);
  background-repeat:repeat-y;
  background-position: center;
  background-size: 120% 120%;
}

.grid-ingredients li:hover
{
cursor: pointer;
}

.grid-elements
{
  display: grid;
  grid-template-columns: repeat(1);
  top: 0;
  position: sticky;
  height: max-content;
  background-image: url(../images/icons/notebook-clipart-old-writing-paper-5.png);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}
<div class="container">

  <h1 class="homepage-title">
    <img src="../images/witcher-transparent.png" class="witcher-transparent-logo">
    Alchemy
    <img src="../images/witcher-transparent.png" class="witcher-transparent-logo">
  </h1>

  <div class="grid-col">
    <div class="grid-ingredients">
      <div>
        <h2>Herbal Extracts</h2>
        <ul></ul>   
      </div>
    </div>
    
    <div class="grid-elements">
      <div>
        <h2>Elements</h2>
        <ul></ul>
      </div>
    </div>
    
    <div class="grid-descriptions">
      <p id="description"></p>
    </div>
  </div>
  
</div>


推荐阅读