javascript - 单击按钮清除对象属性

标签 javascript css events button

有 5 个框,可以通过鼠标事件(鼠标悬停、鼠标移开和单击)从“白色”<->“黄色”更改颜色。还有一个蓝色区域,其中的文本显示单击框的级别。 点击第三个框后,我得到了蓝色区域的“困难级别”文本和黄色的 3 个框颜色。

我需要的是通过单击重置按钮将其恢复到默认级别(“简单级别”和第一个黄色框)。

我一直在尝试这样做,但它不起作用:

resetBtn = document.querySelector('#update');

和事件监听器:

resetBtn.addEventListener('click', highlightStars(`#star1`), true)

这是一个例子:

    window.addEventListener('DOMContentLoaded', changeStars, false);
    
    const resetBtn = document.querySelector('#update');
    
    /* Change level of the game depending on user choice */
    
    function changeStars() {
    	/* Displaying level text inside blue box */
    	const updateAltText = currentLevelIndex => {
    		let levelText = document.querySelector('#level-text');
    		/* 'currentLevelIndex + 1' replaces event 'currentElement' */
    		levelText.textContent = document.querySelector(`#star${currentLevelIndex + 1}`).alt;
    	}
    	
    	/* Captcha level number - default is 1 */
    	const getNumber = str => Number(str.match(/\d+/)[0]) || 1;
    	
    	/* Star index is always one number lower than level number (indexing rules) */
    	const getStarIndex = event => getNumber(event.target.id) - 1;
    	
    	let stars = document.querySelectorAll('.star');
    	
    		const handleStarClick = event => {
    		/* FIRST - blocking possibility to change star behaviour by mouse events */
    		gameLevel.removeEventListener('mouseover', highlightStars);
    		gameLevel.removeEventListener('mouseout', highlightStars);
    
    		/* SECOND - making all needed star with yellow color */
    		const stars = document.querySelectorAll('.star');
    		for (let i = 0; i <= getStarIndex(event); i++) {
    			stars[i].classList.add('yellow');
    		}
      	};
    
    	const highlightStars = event => {
    		const starIndex = getStarIndex(event);
    		updateAltText(starIndex);
    		for (let i = 1; i <= starIndex; i++) {
    			const star = document.querySelector(`#star${i + 1}`);
    			star.classList.toggle('yellow');
    		}
    	};
    
    	// resetBtn.addEventListener('click', highlightStars(`#star1`), true);
    	
resetBtn.addEventListener('click', updateAltText(0), true);

    	const gameLevel = document.querySelector('.game-level');
    	gameLevel.addEventListener("mouseover", highlightStars);
    	gameLevel.addEventListener("mouseout", highlightStars);
    	gameLevel.addEventListener('click', handleStarClick, {once: true});
    }
    .stars {
      display: flex;
      margin: 10px auto;
      width: 500px;
    }
    
    input[type='image'] {
      width: 60px;
      height: 60px;
      border: thin solid black;
    }
    
    .yellow {
      background-color: yellow;
    }
    
    .game-level {
      display: flex;
      width: 300px;
      height: 100%;
    }
    
    .level-block {
      display: flex;
      width: 200px;
      margin-left: 10px;
      justify-content: center;
      align-items: center;
      border: 1px solid hsl(217, 86%, 50%);
      border-radius: 25px;
      background-color: hsl(212, 29%, 80%);
    }
    
    .level-block > span {
      font-size: 18px;
    }
    
    .reset {
      width: 80px;
      height: 80px;
    }
    <div class="stars">
      <div class="game-level">
        <input type="image" class="star yellow" id="star1" src="" width="60" alt="easy level">
        <input type="image" class="star" id="star2" src="" width="60" alt="normal level">
        <input type="image" class="star" id="star3" src="" width="60" alt="hard level">
        <input type="image" class="star" id="star4" src="" width="60" alt="very hard level">
        <input type="image" class="star" id="star5" src="" width="60" alt="impossible level">
      </div>
      <div class="level-block">
        <span id="level-text">Easy level</span>
      </div>
    </div>
    <input type="button" class="reset" id="update" value="RESET">





    

最佳答案

以下演示仅使用 JavaScript 处理点击事件,所有鼠标事件(即悬停)都是纯 CSS。重置行为只是删除所有按钮上的 .active 类,然后将 .active 类添加到第一个按钮。重置后显示的不是第一个按钮标题,而是显示重置按钮标题:"Game Reset",如果没有确认重置,用户可能会有点困惑。演示中包含的其他行为是合乎逻辑且一致的,例如切换、悬停到临时状态和单击持久状态等。详细信息在演示中进行了注释。

// Reference the form
const stars = document.forms.stars;

/*
Register the form to the click event -- when a click occurs anywhere on or within the form, callback function twinkle() is
called
*/
stars.onclick = twinkle;

/**
//A -- twinkle passes a reference to the Event Object... (e)
//B1 - Two Event Object properties are used to reference:
          The tag the was clicked by user: event.target 
          The tag registered to the event: event.currentTarget
//B2 - The HTMLFormElement property: .elements collects all form
       controls into a Live HTML Collection (aka NodeList)
//C -- ui.star is a Collection of form controls with [name=star] 
       The brackets [] and spread operator ... converts the  
       NodeList into an Array
//D -- Reference the message tag. If the clicked tag was the reset
       button -- for...of loop iterates through each [name=star]
       and removes the class .active from all [name=star]
//E1 - Next add .active class to the default button
//E2 - Set the legend.message text to the value of clicked button
       [title] attribute...
~~~~~~~
//F -- ...But if a button.star was clicked, a check to verify if 
       clicked tag has the .active class -- then a for...of
       loop identical to the one described in line D is used to
       remove any .active class.
//G -- After there are no .active, the Boolean declared in line F
       determines whether the clicked tag gets the .active class 
       and its [title] attribute displayed or not
*/
function twinkle(e) {
  const active = e.target;
  const ui = e.currentTarget.elements;
  const starZ = [...ui.star];
  const msg = document.querySelector(".message");
  if (active.matches("#clear")) {
    for (let star of starZ) {
      star.classList.remove("active");
    }
    ui.star1.classList.add('active');
    msg.textContent = active.title;
  } else if (active.matches(".star")) {
    let status = active.classList.contains("active");
    for (let star of starZ) {
      star.classList.remove("active");
    }
    if (!status) {
      active.classList.add("active");
      msg.textContent = active.title;
    } else {
      active.classList.remove("active");
      msg.textContent = "";
    }
  }
  return false;
}
:root {
  font: 400 small-caps 2.5vw/1 Arial
}

.levels {
  display: table;
  width: 96%;
  height: auto;
  border: 1px solid hsl(217, 86%, 50%);
  border-radius:4px;
}

.message {
  display: table-caption;
  width: 40vw;
  height: 6vh;
  margin: 0 auto 2vh;
  padding: 0.5vh 0;
  border: 1px solid hsl(217, 86%, 50%);
  border-radius: 1.5rem;
  background-color: hsla(212, 29%, 80%, 25%);
  text-align: center;
  font-size: 1.5rem;
  color: #0078D7;
}

#clear {
  float: right;
  transform: rotate(45deg);
  padding: 0;
  border: none;
  background: none;
  font-size: 3.5rem;
  cursor: pointer;
}

#clear:focus {
  outline: 0;
}

/*
Flex is applied to the button.star'S parent tag so the order
property can be utilized.
*/
.flex {
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  width: 70vw;
}

.star {
  display: table-cell;
  position: relative;
  width: 16vw;
  height: 24vh;
  border: thin solid black;
  background: #DDD;
  font-size: 3.75rem;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
}

/*
GSC (General Sibling Combinator: ~ ) provides highlighting across 
multiple buttons.
Exp. 5 buttons: [-] [-] [X] ~ [>] ~ [>]
*/
.star.active,
.star:hover,
.star.active ~ .star,
.star:hover ~ .star {
  background: gold;
}

/*
HTML layout has button.star in reverse order. Applying order to
each button rectifies the order by APPEARING in order while the
HTML structure remains reversed.
*/
#star1 {
  order: 1;
  border-top-left-radius: 6px;
  border-bottom-left-radius: 6px;
}

#star2 {
  order: 2;
}

#star3 {
  order: 3;
}

#star4 {
  order: 4;
}

#star5 {
  order: 5;
  border-top-right-radius: 6px;
  border-bottom-right-radius: 6px;
}

#star1:hover,
#star1.active {
  color: #5BC0DE;
}

#star2:hover,
#star2.active {
  color: #FF1C8D;
}

#star3:hover,
#star3.active {
  color: #00D800;
}

#star4:hover,
#star4.active {
  color: #0000D5;
}

#star5:hover,
#star5.active {
  color: #D50000;
}
<form id="stars" action="">
  <fieldset name="levels" class="levels">
    <legend class="message">Novice</legend>
    <button id="clear" type="reset" title="Game Reset">&#128260;</button>
    <section class="flex">
      <button id="star5" name='star' class="star" title="Master">&#128976;</button>
      <button id="star4" name='star' class="star" title="Expert">&#128972;</button>
      <button id="star3" name='star' class="star" title="Advanced">&#128970;</button>
      <button id="star2" name='star' class="star" title="Intermediate">&#128966;</button>
      <button id="star1" name='star' class="star active" title="Novice">&#128962;</button>
    </section>
  </fieldset>
</form>

关于javascript - 单击按钮清除对象属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56716558/

相关文章:

html - 基于 Bootstrap 的垂直制表符 : alignment issues

html - 使用 ng-click 属性禁用 AngularJS 中的 div?

c# - 区分用户交互引发的事件和我自己的代码

javascript - 如何延迟 JavaScript 生成器函数中的循环?

javascript - 如何在 Knex JS 中使用 IS NOT NULL

javascript - 访问对象中的函数

JavaScript - 如何使用 EXIF 数据在网络摄像头中拍照?

jquery - ios safari 上的 CSS 动画

vb.net - 在 VB.NET 的新线程上引发事件

JavaScript 'div empty' 事件监听器