- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了简单难度下有 12 张卡片的内存卡游戏,我想通过创建新的动态元素来添加更多卡片,并在我更改难度时将其附加到游戏容器。
使用此代码,我希望新创建的元素具有 flipCard() 函数,当我单击它时它将翻转卡片。然而,这不起作用,每当我点击卡片时,它都会给我一个错误
'TypeError: this.classlist is undefined'
(flipCard 函数内部的错误)
game.addEventListener('click', function (e) {
if (e.target) {
flipCard();
}
});
下面的代码可以工作,但不适用于动态元素。
cards.forEach(card => {
cardCount.push(card);
card.addEventListener('click', flipCard);
});
window.onload = function() {
const game = document.querySelector('.game');
const cards = document.querySelectorAll('.card');
const scoreboard = document.querySelector('.score');
const move = document.querySelector('.move');
const difficulties = document.getElementById("difficulties");
let isCardFlipped = false,
lockBoard = false,
firstCard,
secondCard,
score = 0,
moves = 0,
unflipTimeout = 1500,
cardCount = [];
difficulties.addEventListener("change", function() {
resetGame();
});
function addCard() {
for (i = 0; i < 4; i++) {
game.innerHTML += "<div class='card'>" + "<img src='assets/image/default/bellsprout.svg' class='front-face'>" +
"<img src='assets/image/default/pokeball.svg' class='back-face'>" + "</div>";
}
};
// ATTACH CLICK EVENT AND flipCard() FUNCTION FOR EVERY CARD.
// THIS DOESN'T WORK FOR DYNAMICALLY CREATED ELEMENT
// cards.forEach(card => {
// cardCount.push(card);
// card.addEventListener('click', flipCard);
// });
// ATTACH CLICK EVENT AND flipCard() FUNCTION FOR EVERY CARD.
// THIS WILL WORK FOR DYNAMICALLY CREATED ELEMENT,
// BUT "this." INSIDE flipCard() function is not defined/initialize
game.addEventListener('click', function(e) {
if (e.target) {
flipCard();
}
});
// Difficulty Option
(difficulty = () => {
let selected = difficulties.options[difficulties.selectedIndex].value;
if (selected === 'easy') {
unflipTimeout = 1500;
} else if (selected === 'hard') {
unflipTimeout = 500;
// ADD MORE CARD ONLY IF HARD DIFFICULTY IS SELECTED
addCard();
}
})();
// flip card when card is clicked
function flipCard() {
if (lockBoard || this === firstCard) return;
this.classList.add('flip');
if (!isCardFlipped) {
isCardFlipped = true;
firstCard = this;
return;
}
isCardFlipped = false;
secondCard = this;
checkForMatch();
}
// check if 2 selected card are match.
checkForMatch = () => {
// if matched disabled card function, unflip card if not matched.
let isMatch = firstCard.dataset.pokemon ===
secondCard.dataset.pokemon;
isMatch ? disableCard() : unflipCard(unflipTimeout);
}
// disable flip card function
disableCard = () => {
moves++;
score++;
updateScore();
firstCard.removeEventListener('click', flipCard);
secondCard.removeEventListener('click', flipCard);
}
unflipCard = (timeout) => {
lockBoard = true;
moves++;
updateScore();
setTimeout(() => {
firstCard.classList.remove('flip');
secondCard.classList.remove('flip');
resetBoard();
}, timeout);
}
resetBoard = () => {
[isCardFlipped, lockBoard] = [false, false];
[firstCard, secondCard] = [null, null];
}
resetGame = () => {
if (moves > 0) {
var confirm = window.confirm("Changes will be applied after reset \n \n \t \t Reset The Game?");
if (confirm === true) {
score = 0;
moves = 0;
updateScore();
for (var i = 0; i < cardCount.length; i++) {
cardCount[i].classList.remove('flip');
}
alert('Game Restarted! \n \n \t Card Reshuffle.');
shuffle();
} else return;
}
}
var shuffle;
(shuffle = () => {
cards.forEach(card => {
let randomPos = Math.round(Math.random() * cardCount.length);
card.style.order = randomPos;
});
})();
updateScore = () => {
scoreboard.innerText = score;
move.innerText = moves;
if (score === cardCount.length / 2) {
alert("You Win!");
}
}
};
.scoreboard {
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
align-items: center;
padding: 2px;
border-radius: 5px;
background: #363636;
color: #0a8ec2;
}
.scoreboard h1 {
font-size: 1.5rem;
}
.game {
width: 580px;
height: 580px;
margin: auto;
display: flex;
flex-wrap: wrap;
perspective: 1000px;
position: relative;
}
.game .card {
position: relative;
width: calc(25% - 10px);
height: calc(33.333% - 10px);
margin: 5px;
transform-style: preserve-3d;
transition: transform 500ms linear;
}
.game .card.active {
transform: scale(0.97);
}
.game .card.flip {
transform: rotateY(180deg);
}
.game .card .front-face,
.game .card .back-face {
width: 100%;
height: 100%;
position: absolute;
border-radius: 5px;
padding: 20px;
background: #363636;
backface-visibility: hidden;
}
.game .card .front-face {
transform: rotateY(180deg);
backface-visibility: visible;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="assets/css/styles.css">
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/main.js"></script>
<script src="assets/js/app.js"></script>
<title>Memory Card Game</title>
</head>
<body>
<section class="scoreboard">
<h1>Score: <span class="score">0</span> <br> Moves: <span class="move">0</span></h1>
<select id="difficulties" name="difficulties">
<option value="default" disabled>Select Difficulty</option>
<option value="easy" selected>Easy</option>
<option value="hard">Hard</option>
</select>
</section>
<main class="game">
<div class="card" data-pokemon="rattata">
<img src="assets/image/default/rattata.svg" alt="Rattata" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="rattata">
<img src="assets/image/default/rattata.svg" alt="Rattata" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="meowth">
<img src="assets/image/default/meowth.svg" alt="Meowth" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="meowth">
<img src="assets/image/default/meowth.svg" alt="Meowth" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="mew">
<img src="assets/image/default/mew.svg" alt="Mew" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="mew">
<img src="assets/image/default/mew.svg" alt="Mew" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="mankey">
<img src="assets/image/default/mankey.svg" alt="Mankey" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="mankey">
<img src="assets/image/default/mankey.svg" alt="Mankey" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="venonat">
<img src="assets/image/default/venonat.svg" alt="Venonat" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="venonat">
<img src="assets/image/default/venonat.svg" alt="Venonat" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="psyduck">
<img src="assets/image/default/psyduck.svg" alt="Psyduck" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
<div class="card" data-pokemon="psyduck">
<img src="assets/image/default/psyduck.svg" alt="Psyduck" class="front-face">
<img src="assets/image/default/pokeball.svg" alt="Pokemon" class="back-face">
</div>
</main>
</body>
</html>
最佳答案
代替这个:
if (e.target) {
flipCard();
}
这样做:
if (e.target) {
flipCard.bind(this)();
}
将其添加到点击监听器中。 flipCard
函数中的 this
指向 window
。
关于javascript - 使用 Vanilla JS 将事件和函数附加到动态元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55532701/
我正在尝试将 WPF CodeBehid 事件(如 Event、Handler、EventSetter)转换为 MVVM 模式。我不允许使用 System.Windows.Controls,因为我使用
我可能误解了 Backbone 中的事件系统,但是当我尝试以下代码时什么也没有发生。当我向 Backbone.Events 扩展对象添加新属性时,它不应该触发某种更改、更新或重置事件吗?就像模型一样吗
我遇到了一个简单的问题,就是无法弄清楚为什么它不起作用。我有一个子组件“app-buttons”,其中我有一个输入字段,我想听,所以我可以根据输入值过滤列表。 如果我将输入放在我有列表的根组件中,一切
System.Timers.Timer 的 Elapsed 事件实际上与 System.Windows.Forms.Timer 的 Tick 事件相同吗? 在特定情况下使用其中一种比使用另一种有优势吗
嗨,这个 javascript 代码段是什么意思。(evt) 部分是如此令人困惑.. evt 不是 bool 值。这个怎么运作? function checkIt(evt) { evt
我正在使用jquery full calendar我试图在事件被删除时保存它。 $('calendar').fullCalendar ({
我有两个链接的鼠标事件: $('body > form').on("mousedown", function(e){ //Do stuff }).on("mouseup", function(
这是我的代码: $( '#Example' ).on( "keypress", function( keyEvent ) { if ( keyEvent.which != 44 ) {
我尝试了 dragOver 事件处理程序,但它没有正常工作。 我正在研究钢琴,我希望能够弹奏音符,即使那个键上没有发生鼠标按下。 是否有事件处理程序? 下面是我正在制作的钢琴的图片。 最佳答案 您应该
当悬停在相邻文本上时,我需要使隐藏按钮可见。这是通过 onMouseEnter 和 onMouseLeave 事件完成的。但是当点击另外的文本时,我需要使按钮完全可见并停止 onMouseLeave
我有ul标签内 div标签。我申请了mouseup事件 div标记和 click事件 ul标签。 问题 每当我点击 ul标签,然后都是 mouseup和 click事件被触发。 我想要的是当我点击 u
我是 Javascript 和 jQuery 的新手,所以我有一个非常愚蠢的疑问,请耐心等待 $(document).click(function () { alert("!"); v
我有一个邮政编码解析器,我正在使用 keyup 事件处理程序来跟踪输入长度何时达到 5,然后查询服务器以解析邮政编码。但是我想防止脚本被不必要地调用,所以我想知道是否有一种方法可以跟踪 keydown
使用事件 API,我有以下代码来发布带有事件照片的事件 $facebook = new Facebook(array( "appId" => "XXX", "se
首次加载 Microsoft Word 时,既不会触发 NewDocument 事件也不会触发 DocumentOpen 事件。当 Word 实例已打开并打开新文档或现有文档时,这些事件会正常触发。
我发现了很多相关问题(这里和其他地方),但还没有具体找到这个问题。 我正在尝试监听箭头键 (37-40) 的按键事件,但是当以特定顺序使用箭头键时,后续箭头不会生成“按键”事件。 例子: http:/
给定的 HTML: 和 JavaScript 的: var $test = $('#test'); $test.on('keydown', function(event) { if (eve
我是 Node.js 的新手,希望使用流运行程序。对于其他程序,我必须同时启动一个服务器(mongodb、redis 等),但我不知道我是否应该用这个运行一个服务器。请让我知道我哪里出了问题以及如何纠
我正在尝试使用 Swift 和 Cocoa 创建一个适用于 OS X 的应用程序。我希望应用程序能够响应关键事件,而不将焦点放在文本字段上/文本字段中。我在 Xcode 中创建了一个带有 Storyb
我有以下代码: (function(w,d,s,l,i){ w[l]=w[l]||[];w[l].push({
我是一名优秀的程序员,十分优秀!