[英]I made a rock paper scissors game with javascript and I'm having trouble with keeping score, I really lost
function computerPlay() { let [min, max] = [1, 3] let randomNumber = Math.floor(Math.random() * (max - min + 1)) + min; if(randomNumber == 1) return 'ROCK' else if(randomNumber == 2) return 'PAPER' else return 'SCISSORS' } function play(playerSelection, computerSelection) { let move = playerSelection; let com = computerSelection; if(move == 'ROCK' && com == 'SCISSORS') return 'ROCK beats SCISSORS'; else if(move == 'ROCK' && com == 'PAPER') return 'PAPER beats ROCK' else if(move == 'SCISSORS' && com == 'ROCK') return 'ROCK beats SCISSORS' else if(move == 'SCISSORS' && com == 'PAPER') return 'SCISSORS beat PAPER' else if(move == 'PAPER' && com == 'SCISSORS') return 'SCISSORS beat PAPER' else if(move == 'PAPER' && com == 'ROCK') return 'PAPER beats ROCK' else if(move == com) return 'DRAW' } let playBtn = document.querySelector('.play-btn'); let container1 = document.querySelector('.container1'); playBtn.addEventListener('click', makeContainer); // This is the function that creates the page that needs the player's input(rock, paper or scissors) function makeContainer() { container1.remove(); let con = document.createElement('div'); con.classList.add('container'); let h1 = document.createElement('h1'); h1.classList.add('one'); h1.textContent = 'ROCK PAPER SCISSORS'; let h12 = document.createElement('h1'); h12.classList.add('two'); h12.textContent = 'ROUND 1'; let h13 = document.createElement('h1'); h13.classList.add('three'); h13.textContent = 'MAKE YOUR MOVE'; let buttons = document.createElement('div'); buttons.classList.add('buttons'); let btn1 = document.createElement('div'); btn1.classList.add('rock'); let span = document.createElement('span'); span.textContent = 'ROCK'; btn1.append(span); let btn2 = document.createElement('div'); btn2.classList.add('paper'); let span2 = document.createElement('span'); span2.textContent = 'PAPER'; btn2.append(span2); let btn3 = document.createElement('div'); btn3.classList.add('scissors'); let span3 = document.createElement('span'); span3.textContent = 'SCISSORS'; btn3.append(span3); buttons.append(btn1, btn2, btn3); con.append(h1, h12, h13, buttons); document.body.append(con); const container = document.querySelector('.container'); const rock = document.querySelector('.rock'); const paper = document.querySelector('.paper'); const scissors = document.querySelector('.scissors'); [rock, paper, scissors].forEach((c) => c.addEventListener('click', (e) => { // console.log(e.target); containerDisappear(container, c) })); } // This function removes the makeContainer page(the one that shows rock paper scissors) and adds a transition to it function containerDisappear(con, r) { let choi = r; con.style.transitionProperty = 'opacity'; con.style.transitionDuration = '1s'; con.style.opacity = '0'; setTimeout(() => con.remove('container'), 1000); animation(choi); } // This function displays the animation that pops up after the the makeContainer page has disappeared function animation(r) { let choic = r; const waitdiv = document.createElement('div'); waitdiv.classList.add('waitdiv'); const div1 = document.createElement('div'); const div2 = document.createElement('div'); const div3 = document.createElement('div'); div1.classList.add('div1'); div2.classList.add('div2'); div3.classList.add('div3'); div1.textContent = 'ROCK...'; div2.textContent = 'PAPER...'; div3.textContent = 'SCISSORS...'; waitdiv.append(div1, div2, div3); document.body.append(waitdiv); setTimeout(() => { div1.style.transitionProperty = 'opacity'; div1.style.transitionDuration = '.6s'; div1.style.opacity = '1'; }, 600); setTimeout(() => { div2.style.transitionProperty = 'opacity'; div2.style.transitionDuration = '.6s'; div2.style.opacity = '1'; }, 1200); setTimeout(() => { div3.style.transitionProperty = 'opacity'; div3.style.transitionDuration = '.6s'; div3.style.opacity = '1'; }, 1800); setTimeout(() => { waitdiv.style.transitionProperty = 'opacity'; waitdiv.style.transitionDuration = '.3s'; waitdiv.style.opacity = '0'; waitdiv.remove(); }, 2400); setTimeout(() => { results(choic) }, 2400); } // This function displays the player's move vs the computer's move and then displays information about who lost /* Theres a 0:1 right at the bottom of this page, it's static, it doesn't update after each move, it's actually one of the things I'm struggling with */ function results(c) { const cShoot = document.createElement('div'); cShoot.classList.add('container-shoot'); const shoot = document.createElement('h1'); shoot.classList.add('shoot'); const round = document.createElement('h1'); round.classList.add('round'); const versus = document.createElement('div'); versus.classList.add('versus'); const v = document.createElement('div'); v.classList.add('v'); const h6 = document.createElement('h6'); const choice = document.createElement('div'); choice.classList.add('choice'); const vs = document.createElement('div'); vs.classList.add('v'); const v2 = document.createElement('div'); v2.classList.add('v'); const choice2 = document.createElement('div'); choice2.classList.add('choice'); const h62 = document.createElement('h6'); // ----------------second part--------------------------------------- const info = document.createElement('div'); info.classList.add('info'); const h2 = document.createElement('h2'); const h3 = document.createElement('h3'); const span = document.createElement('span'); // ---------------------third part------------------------------------ const score = document.createElement('div'); score.classList.add('score'); const span2 = document.createElement('span'); span2.classList.add('player'); const span3 = document.createElement('span'); span3.classList.add('colon'); const span4 = document.createElement('span'); span4.classList.add('com'); // ---------------------time to append stuff-------------------------------------------- cShoot.append(shoot, round, versus, info, score); versus.append(v, vs, v2); v.append(h6, choice); vs.textContent = 'VS'; v2.append(choice2, h62); info.append(h2, h3); h3.append(span); span2.textContent = '0'; span3.textContent = ':'; span4.textContent = '1'; score.append(span2, span3, span4); // ----------------adding text-------------------------------------------- shoot.textContent = 'SHOOT!!!'; round.textContent = 'ROUND 1'; h6.textContent = 'YOU'; choice.textContent = (c.classList.value == 'rock') ? 'ROCK' : c.classList.value == 'paper' ? 'PAPER' : c.classList.value == 'scissors' ? 'SCISSORS' : null; vs.textContent = 'VS'; choice2.textContent = computerPlay(); h62.textContent = 'COM'; h2.textContent = play(choice.textContent, choice2.textContent); span.textContent = s(); if(span.textContent == 'YOU WIN THIS ROUND') span.style.color = 'green'; else span.style.color = 'red' // -------------------------function------------------------------------------------- function s() { if(choice.textContent == 'ROCK' && choice2.textContent == 'SCISSORS') { return 'YOU WIN THIS ROUND' } else if(choice.textContent == 'ROCK' && choice2.textContent == 'PAPER') { return 'YOU LOSE THIS ROUND' } else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'ROCK') { return 'YOU LOSE THIS ROUND' } else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'PAPER') { return 'YOU WIN THIS ROUND' } else if(choice.textContent == 'PAPER' && choice2.textContent == 'SCISSORS') { return 'YOU LOSE THIS ROUND' } else if(choice.textContent == 'PAPER' && choice2.textContent == 'ROCK') { return 'YOU WIN THIS ROUND' } } // -------------------------------------------------------------------------- document.body.append(cShoot); // cShoot is the first variable that was created inside this function, it's the div tha holds everything on this page }
* { margin: 0; padding: 0; box-sizing: border-box; color: white; } body { background-color: #333; } .container { height: 100vh; text-align: center; position: relative; opacity: 1; } .buttons { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; column-gap: 30px; } .rock { border-radius: 20px; height: 150px; width: 200px; border: 2px solid red; display: flex; align-items: center; justify-content: center; transition: transform 0.05s; } .rock:hover { cursor: pointer; transform: scale(1.05); } .paper { border-radius: 20px; height: 150px; width: 200px; border: 2px solid red; display: flex; align-items: center; justify-content: center; transition: transform 0.05s; } .paper:hover { cursor: pointer; transform: scale(1.05); } .scissors { border-radius: 20px; height: 150px; width: 200px; border: 2px solid red; display: flex; align-items: center; justify-content: center; transition: transform 0.05s; } .scissors:hover { cursor: pointer; transform: scale(1.05); } span { font-size: 22px; } .one { position: relative; top: 40px; } .two { position: relative; top: 60px; } .three { position: relative; top: 80px; font-size: 23px; } .waitdiv { display: flex; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .div1 { opacity: 0; font-size: 75px; } .div2 { opacity: 0; font-size: 75px; } .div3 { opacity: 0; font-size: 75px; } .container-shoot { height: 100vh; text-align: center; position: relative; } .shoot { font-size: 80px; position: relative; top: 50px; } .round { position: relative; top: 55px; } .versus { display: flex; text-align: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 50px; width: 80%; } .v { display: flex; text-align: center; flex-basis: 100%; justify-content: space-evenly; align-items: center; } .choice { border-radius: 20px; text-align: center; border: 2px solid red; /* font-size: 30px; */ height: 100px; display: flex; align-items: center; } .info { position: absolute; bottom: 150px; left: 50%; transform: translate(-50%, -70px); } .info h3 span { color: white; } .score { position: absolute; bottom: 20px; left: 50%; transform: translate(-50%, -20px); } .score span { font-size: 70px; } .container1 { height: 100vh; position: relative; } .play-btn { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 15px 30px; cursor: pointer; color: black; font-size: 16px; border-radius: 12px; border: none; } .next { border-radius: 17px; border: none; position: absolute; left: 90%; top: 90%; transform: translate(-50%, -50%); cursor: pointer; padding: 12px 18px; color: black; }
<div class="container1"> <button class="play-btn">PLAY</button> </div>
I made a rock paper scissors game with javascript and I'm having trouble with keeping score.我用 javascript 制作了一个石头剪刀布游戏,但我在记分时遇到了麻烦。 I need a way to keep track of who is winning between the player and the computer, that score should be displayed right at the bottom of the page.
我需要一种方法来跟踪谁在玩家和计算机之间获胜,该分数应该显示在页面底部。 If you run the whole code(html, css and javascript), you will see this example right at the bottom of the last page I encourage you to please run the whole code
如果您运行整个代码(html、css 和 javascript),您将在最后一页的底部看到这个示例 我鼓励您运行整个代码
Here's my HTML file:这是我的 HTML 文件:
<div class="container1"><button class="play-btn">PLAY</button></div>
Here's the code i wrote in my JAVASCRIPT file:这是我在 JAVASCRIPT 文件中编写的代码:
function computerPlay() {
let [min, max] = [1, 3]
let randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
if(randomNumber == 1) return 'ROCK'
else if(randomNumber == 2) return 'PAPER'
else return 'SCISSORS'
} }
function play(playerSelection, computerSelection) {
let move = playerSelection;
let com = computerSelection;
if(move == 'ROCK' && com == 'SCISSORS') return 'ROCK beats SCISSORS';
else if(move == 'ROCK' && com == 'PAPER') return 'PAPER beats ROCK'
else if(move == 'SCISSORS' && com == 'ROCK') return 'ROCK beats SCISSORS'
else if(move == 'SCISSORS' && com == 'PAPER') return 'SCISSORS beat PAPER'
else if(move == 'PAPER' && com == 'SCISSORS') return 'SCISSORS beat PAPER'
else if(move == 'PAPER' && com == 'ROCK') return 'PAPER beats ROCK'
else if(move == com) return 'DRAW'
} }
let arr = [];
let playBtn = document.querySelector('.play-btn');
let container1 = document.querySelector('.container1');
playBtn.addEventListener('click', makeContainer);
This is the function that creates the page that needs the player's input(rock, paper or scissors)这是创建需要玩家输入(石头、纸或剪刀)的页面的函数
function makeContainer() {
container1.remove();
let con = document.createElement('div');
con.classList.add('container');
let h1 = document.createElement('h1');
h1.classList.add('one');
h1.textContent = 'ROCK PAPER SCISSORS';
let h12 = document.createElement('h1');
h12.classList.add('two');
h12.textContent = 'ROUND 1';
let h13 = document.createElement('h1');
h13.classList.add('three');
h13.textContent = 'MAKE YOUR MOVE';
let buttons = document.createElement('div');
buttons.classList.add('buttons');
let btn1 = document.createElement('div');
btn1.classList.add('rock');
let span = document.createElement('span');
span.textContent = 'ROCK';
btn1.append(span);
let btn2 = document.createElement('div');
btn2.classList.add('paper');
let span2 = document.createElement('span');
span2.textContent = 'PAPER';
btn2.append(span2);
let btn3 = document.createElement('div');
btn3.classList.add('scissors');
let span3 = document.createElement('span');
span3.textContent = 'SCISSORS';
btn3.append(span3);
buttons.append(btn1, btn2, btn3);
con.append(h1, h12, h13, buttons);
document.body.append(con);
const container = document.querySelector('.container');
const rock = document.querySelector('.rock');
const paper = document.querySelector('.paper');
const scissors = document.querySelector('.scissors');
[rock, paper, scissors].forEach((c) => c.addEventListener('click', (e) => {
// console.log(e.target);
containerDisappear(container, c)
}));
}
This function removes the makeContainer page(the one that shows rock paper scissors) and adds a transition to it此函数删除 makeContainer 页面(显示石头剪刀布的页面)并为其添加过渡
function containerDisappear(con, r) {
let choi = r;
con.style.transitionProperty = 'opacity';
con.style.transitionDuration = '1s';
con.style.opacity = '0';
setTimeout(() => con.remove('container'), 1000);
animation(choi);
}
This function displays the animation that pops up after the the makeContainer page has disappeared该函数显示makeContainer页面消失后弹出的动画
function animation(r) {
let choic = r;
const waitdiv = document.createElement('div');
waitdiv.classList.add('waitdiv');
const div1 = document.createElement('div');
const div2 = document.createElement('div');
const div3 = document.createElement('div');
div1.classList.add('div1');
div2.classList.add('div2');
div3.classList.add('div3');
div1.textContent = 'ROCK...';
div2.textContent = 'PAPER...';
div3.textContent = 'SCISSORS...';
waitdiv.append(div1, div2, div3);
document.body.append(waitdiv);
setTimeout(() => {
div1.style.transitionProperty = 'opacity';
div1.style.transitionDuration = '.6s';
div1.style.opacity = '1';
}, 600);
setTimeout(() => {
div2.style.transitionProperty = 'opacity';
div2.style.transitionDuration = '.6s';
div2.style.opacity = '1';
}, 1200);
setTimeout(() => {
div3.style.transitionProperty = 'opacity';
div3.style.transitionDuration = '.6s';
div3.style.opacity = '1';
}, 1800);
setTimeout(() => {
waitdiv.style.transitionProperty = 'opacity';
waitdiv.style.transitionDuration = '.3s';
waitdiv.style.opacity = '0';
waitdiv.remove();
}, 2400);
setTimeout(() => {
results(choic)
}, 2400);
}
This function displays the player's move vs the computer's move and then displays information about who lost Theres a 0:1 right at the bottom of this page, it's static, it doesn't update after each move, it's actually one of the things I'm struggling with此功能显示玩家的移动与计算机的移动,然后显示有关谁输了的信息 在这个页面的底部有一个 0:1,它是静态的,它不会在每次移动后更新,它实际上是我的东西之一我在挣扎
function results(c) {
const cShoot = document.createElement('div');
cShoot.classList.add('container-shoot');
const shoot = document.createElement('h1');
shoot.classList.add('shoot');
const round = document.createElement('h1');
round.classList.add('round');
const versus = document.createElement('div');
versus.classList.add('versus');
const v = document.createElement('div');
v.classList.add('v');
const h6 = document.createElement('h6');
const choice = document.createElement('div');
choice.classList.add('choice');
const vs = document.createElement('div');
vs.classList.add('v');
const v2 = document.createElement('div');
v2.classList.add('v');
const choice2 = document.createElement('div');
choice2.classList.add('choice');
const h62 = document.createElement('h6');
// ----------------second part---------------------------------------
const info = document.createElement('div');
info.classList.add('info');
const h2 = document.createElement('h2');
const h3 = document.createElement('h3');
const span = document.createElement('span');
// ---------------------third part------------------------------------
const score = document.createElement('div');
score.classList.add('score');
const span2 = document.createElement('span');
span2.classList.add('player');
const span3 = document.createElement('span');
span3.classList.add('colon');
const span4 = document.createElement('span');
span4.classList.add('com');
// ---------------------time to append stuff--------------------------------------------
cShoot.append(shoot, round, versus, info, score);
versus.append(v, vs, v2);
v.append(h6, choice);
vs.textContent = 'VS';
v2.append(choice2, h62);
info.append(h2, h3);
h3.append(span);
span2.textContent = '0';
span3.textContent = ':';
span4.textContent = '1';
score.append(span2, span3, span4);
// ----------------adding text--------------------------------------------
shoot.textContent = 'SHOOT!!!';
round.textContent = 'ROUND 1';
h6.textContent = 'YOU';
choice.textContent = (c.classList.value == 'rock') ? 'ROCK' :
c.classList.value == 'paper' ? 'PAPER' :
c.classList.value == 'scissors' ? 'SCISSORS' : null;
vs.textContent = 'VS';
choice2.textContent = computerPlay();
h62.textContent = 'COM';
h2.textContent = play(choice.textContent, choice2.textContent);
span.textContent = s();
if(span.textContent == 'YOU WIN THIS ROUND') span.style.color = 'green';
else span.style.color = 'red'
// -------------------------function-------------------------------------------------
function s() {
if(choice.textContent == 'ROCK' && choice2.textContent == 'SCISSORS') {
return 'YOU WIN THIS ROUND'
}
else if(choice.textContent == 'ROCK' && choice2.textContent == 'PAPER') {
return 'YOU LOSE THIS ROUND'
}
else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'ROCK') {
return 'YOU LOSE THIS ROUND'
}
else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'PAPER') {
return 'YOU WIN THIS ROUND'
}
else if(choice.textContent == 'PAPER' && choice2.textContent == 'SCISSORS') {
return 'YOU LOSE THIS ROUND'
}
else if(choice.textContent == 'PAPER' && choice2.textContent == 'ROCK') {
return 'YOU WIN THIS ROUND'
}
}
// --------------------------------------------------------------------------
document.body.append(cShoot);
// cShoot is the first variable that was created inside this function, it's the div tha holds everything on this page
}
Here's my css file:这是我的css文件:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
color: white;
}
body {
background-color: #333;
}
.container {
height: 100vh;
text-align: center;
position: relative;
opacity: 1;
}
.buttons {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
column-gap: 30px;
}
.rock {
border-radius: 20px;
height: 150px;
width: 200px;
border: 2px solid red;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.05s;
}
.rock:hover {
cursor: pointer;
transform: scale(1.05);
}
.paper {
border-radius: 20px;
height: 150px;
width: 200px;
border: 2px solid red;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.05s;
}
.paper:hover {
cursor: pointer;
transform: scale(1.05);
}
.scissors {
border-radius: 20px;
height: 150px;
width: 200px;
border: 2px solid red;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.05s;
}
.scissors:hover {
cursor: pointer;
transform: scale(1.05);
}
span {
font-size: 22px;
}
.one {
position: relative;
top: 40px;
}
.two {
position: relative;
top: 60px;
}
.three {
position: relative;
top: 80px;
font-size: 23px;
}
.waitdiv {
display: flex;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.div1 {
opacity: 0;
font-size: 75px;
}
.div2 {
opacity: 0;
font-size: 75px;
}
.div3 {
opacity: 0;
font-size: 75px;
}
.container-shoot {
height: 100vh;
text-align: center;
position: relative;
}
.shoot {
font-size: 80px;
position: relative;
top: 50px;
}
.round {
position: relative;
top: 55px;
}
.versus {
display: flex;
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 50px;
width: 80%;
}
.v {
display: flex;
text-align: center;
flex-basis: 100%;
justify-content: space-evenly;
align-items: center;
}
.choice {
border-radius: 20px;
text-align: center;
border: 2px solid red;
/* font-size: 30px; */
height: 100px;
display: flex;
align-items: center;
}
.info {
position: absolute;
bottom: 150px;
left: 50%;
transform: translate(-50%, -70px);
}
.info h3 span {
color: white;
}
.score {
position: absolute;
bottom: 20px;
left: 50%;
transform: translate(-50%, -20px);
}
.score span {
font-size: 70px;
}
.container1 {
height: 100vh;
position: relative;
}
.play-btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 15px 30px;
cursor: pointer;
color: black;
font-size: 16px;
border-radius: 12px;
border: none;
}
.next {
border-radius: 17px;
border: none;
position: absolute;
left: 90%;
top: 90%;
transform: translate(-50%, -50%);
cursor: pointer;
padding: 12px 18px;
color: black;
}
"...I'm having trouble with keeping score. I need a way to keep track of who is winning between the player and the computer,..."
“......我在记分方面遇到了麻烦。我需要一种方法来跟踪玩家和电脑之间谁赢了,......”
I cannot be specifically say what the problem is in OP ( O riginal P ost) code because it's too bloated.我无法具体说明 OP( O riginal Post)代码中的问题是什么,因为它太臃肿了。 Instead of combing through 200 lines and ending up rewriting 80% of the code, I have made a roshambo game that behaves and appears simular to the OP code (see Example B ).
我没有梳理 200 行代码并最终重写 80% 的代码,而是制作了一个行为和外观与 OP 代码相似的 roshambo 游戏(参见示例 B )。
<form>
& Form Controls <form>
& 表单控件
The best HTML layout for simple games is a <form>
and form controls .简单游戏的最佳 HTML 布局是
<form>
和表单控件。 The HTMLFormElement and HTMLFormControlsCollection interfaces allow us to use a terse and versatile syntax (see Figure IA and Figure IB ) HTMLFormElement和HTMLFormControlsCollection接口允许我们使用简洁和通用的语法(参见图 IA和图 IB )
Figure IA - Simple HTML layout of <form>
and form controls图 IA -
<form>
和表单控件的简单 HTML 布局
<form id='contacts'>
<fieldset name='group'>
<label>First Name:
<input id='firstname' value='zer0'>
</label>
<label>Last Name:
<input id='lastname' value='0ne'>
</label>
</fieldset>
<fieldset name='group'>
<output id='fullname'></output>
</fieldset>
<fieldset name='group'>
<label>Phone: <input id='phone' type='tel'></label>
<button type='reset'>Reset</button>
<button>Submit</button>
</fieldset>
</form>
Figure IB - A comparison between DOM interfaces图 IB - DOM 接口之间的比较
Objective![]() |
HTMLFormElement ![]() |
Common DOM Methods![]() |
---|---|---|
<form> |
const C = document.forms.contacts |
const C = document.getElementById('contacts') |
All form controls![]() |
const all = C.elements |
const all = C.querySelectorAll('fieldset, input, button') |
All <fieldset> s![]() <fieldset> s |
const sets = all.group |
const sets = C.querySelectorAll('fieldset') |
Get the value of <input id='phone'> ![]() <input id='phone'> 的值 |
let cell = all.phone.value |
let cell = C.querySelector('#phone').value |
Also see Form Properties and Methods另请参阅表单属性和方法
Special Events特别活动
There are also events that are made exclusively for <form>
s and form controls (see Figure II ).还有一些专门为
<form>
和表单控件制作的事件(参见图 II )。 Specialized behavior allows us to write less and control which elements can react and which elements to exclude.专门的行为允许我们编写更少的代码并控制哪些元素可以做出反应以及哪些元素可以排除。 Moreover, it's important to know how to delegate events by binding events to a parent or ancestor element of multiple origin elements (buttons, inputs, etc) and writing event handlers that target specific elements.
此外,重要的是要知道如何通过将事件绑定到多个原始元素(按钮、输入等)的父元素或祖先元素以及编写针对特定元素的事件处理程序来委派事件。
Figure II - Special Events图二- 特别活动
Event![]() |
Tags![]() |
Trigger![]() |
Behavior![]() |
---|---|---|---|
submit![]() |
<form> |
1. User is focused on a text field and hits the Enter/Return key. ![]() 2. User clicks a <button> , <input type='submit'> , or <input type='image'> . ![]() <button> 、 <input type='submit'> 或<input type='image'> 。3. .submit() method. ![]() .submit() 方法。 |
<form> will send the values of all form controls ❉ that have a [name] attribute to a server. ![]() <form> 会将所有具有[name] 属性的表单控件的值发送到服务器。 If there is no server then it will return a blank page.![]() |
reset ![]() |
<form> |
1. User clicks a button with type="reset" ![]() type="reset" 的按钮2. .reset() method ![]() .reset() 方法 |
All form control values entered by the user are removed![]() |
change ![]() |
<form> and form controls ❉ ![]() <form> 和表单控件❉ |
User enters data or selects a value on/from a form control then loses focus![]() |
|
input ![]() |
<form> and form controls ❉ ![]() <form> 和表单控件❉ |
User enters data or selects a value on/from a form control![]() |
✳ buttons: <button>
with or without type
: "button"
, "submit"
, "reset"
, and <input>
with one of the following type
: "button"
, "submit"
, "reset"
, "image"
✳ 按钮:
<button>
有或没有type
: "button"
、 "submit"
、 "reset"
和<input>
有以下type
之一: "button"
、 "submit"
、 "reset"
、 "image"
❉ buttons ✳ and <output>
are excluded ❉按钮 ✳ 和
<output>
被排除在外
Incrementing .value
Property and Closures - See Example A递增
.value
属性和闭包- 参见示例 A
.value
property..value
属性的表单控件。In #1 we define a variable (it can be a number, an index of an array or an object value from a property, etc) outside of the function because once a function ends, everything within is garbage collected, so the value must be outside but within scope of the function, see Closures .在 #1 中,我们在函数外部定义了一个变量(可以是数字、数组的索引或来自属性的对象值等),因为一旦函数结束,内部的所有内容都会被垃圾回收,因此值必须是在函数范围之外但在函数范围内,请参阅闭包。
Details are commented in both Example A and Example B示例 A 和示例 B 中都有详细说明
// Define values outside of function #1 const coin = { sides: ['https://i.ibb.co/QvT4L5k/heads.png', 'https://i.ibb.co/C6Y3HKd/tails.png'], heads: 0, tails: 0 }; // Reference the <form> const UI = document.forms.toss; // Prevent normal <form> behavior during a submit event UI.onsubmit = e => e.preventDefault(); // Bind <form> to click event UI.onclick = flipCoin; // Event handler passes Event Object by default function flipCoin(e) { // Get a random number between 0 and 1 let side = Math.random() < 0.5 ? 0 : 1; // 0 or 1 // Reference the element the user clicked const clk = e.target; // Reference all form controls const IO = this.elements; /* If the user clicked input#flip... ...change it's src... ...increment coin = {heads or tails}... ...assign heads/tails value of {coin} to the <output>s */ if (clk.id === 'flip') { clk.src = coin.sides[side]; side === 0 ? coin.heads += 1 : coin.tails += 1; IO.heads.value = coin.heads; IO.tails.value = coin.tails; } }
<form id='toss'> <input id='flip' src='https://i.ibb.co/QvT4L5k/heads.png' type='image'><br> Heads: <output id='heads'></output><br> Tails: <output id='tails'></output> </form>
// Reference <form> const game = document.forms.roshambo; // Collect all <dialog> into an array const dialogs = [...document.querySelectorAll('dialog')]; // Define an object outside of functions to keep track of the score const score = { turn: 0, wins: 0, lost: 0, draw: 0 }; /* Bind the "DOMContentLoaded" event to the document When all DOM content is loaded... ...close all <dialog>s... ...open the first <dialog> */ document.addEventListener('DOMContentLoaded', function() { dialogs.forEach(d => d.close()); dialogs[0].showModal(); }) // Bind "reset" event to <form> game.onreset = phase0; // Bind "click" event to <form> game.onclick = choice; // Event handler passes Event Object by default function choice(event) { // Reference the tag the user clicked const clicked = event.target; // Reference all form controls const IO = this.elements; /* If the user clicked a [name="clear"]... ...reset all of {score}'s properties to 0... ...trigger a "reset" event on <form> */ if (clicked.name === 'clear') { for (let prop in score) { score[prop] = 0; } this.reset(); } /* If the user clicked a [name="rps"]... ...close all <dialog>... ...open the third <dialog>... ...define an array - index 0 is the value of the clicked <button> converted into a number index 1 is the result of rand() [(0-2), (0-2)]... ...call phase2() passing the array and a reference to all form controls */ if (clicked.name === 'rps') { dialogs.forEach(d => d.close()); dialogs[2].showModal(); let RPS = [parseInt(clicked.value), rand()]; phase2(RPS, IO); } } // Event handler passes the Event Object by default function phase0(event) { // Prevent the <form> from clearing out all of the <output> event.preventDefault(); // Reference all form controls const IO = this.elements; // Close all <dialog>s dialogs.forEach(d => d.close()); // Open the second <dialog> dialogs[1].showModal(); // Increment score: {turn} score.turn += 1; // call phase1() passing the reference to all form controls phase1(IO); } // Pass the reference to all form controls function phase1(IO) { // Reference all form controls in fieldset#choices const io = IO.choices.elements; // Update all <output> under fieldset#choices io.round.value = score.turn; io.wins.value = score.wins; io.lost.value = score.lost; io.draw.value = score.draw; } // Pass the array of numbers and the reference to all form controls function phase2(RPS, IO) { // Define an array of strings const text = ['ROCK..., ', 'PAPER..., ', 'SCISSORS... ']; // Define a number that will be the base amount of ms for timeouts let time = 600; // Call animate() passing array, a selector of tag to append to, and time animate(text, '#animation h1', time); // Call phase3() passing what phase2() passed on the calculated time setTimeout(() => { phase3(RPS, IO); }, (text.length + 4) * time); } // Pass array and reference function phase3(RPS, IO) { // Close all <dialog>s dialogs.forEach(d => d.close()); // Open the fourth <dialog> dialogs[3].showModal(); // Call outcome() passing the array and reference outcome(RPS, IO); } // Displays 'ROCK..., ', 'PAPER..., ', 'SCISSORS... ' at timed intervals function delay(array, title, time) { array.forEach((segment, index) => { setTimeout(() => { const tag = document.createElement('b'); tag.textContent = segment; tag.className = 'fadeIn'; title.append(tag); }, index * time); }); } // Runs delay() and animates "GO!" function animate(array, selector, time = 1000) { const title = document.querySelector(selector); delay(array, title, time); setTimeout(() => { title.replaceChildren(); title.insertAdjacentHTML('beforeend', `<b class='zoom'>GO!</b>`); }, (array.length + 1) * time); setTimeout(() => { title.className = 'fadeOut'; title.replaceChildren(); }, (array.length + 3) * time); title.className = ''; } // Returns a random number in the range of 0-2 function rand() { return Math.floor(Math.random() * 2) + 1; } // Pass the numbers derived from choice(e) function play(pick, comp) { // This is a ternary expression - an abbreviated if/else statement return pick === comp // if user's num equals cpu's num ? 0 // return 0 : comp === pick - 1 // if cpu's num is 1 less than user's num ? 1 // return 1 : comp === 2 && pick === 0 // if cpu num is 2 AND user's num is 0 ? 1 // return 1 : -1; // else return -1 } // Pass the array and reference function outcome(RPS, IO) { // Define an array of RPS const played = ['🪨 Rock', '🧻 Paper', '✂️ Scissors']; // Reference all form controls under fieldset#outcome const io = IO.outcome.elements; // Get the return of play() passing the two numbers of the given array let wld = play(RPS[0], RPS[1]); // Assign values to the <output>s io.you.value = played[RPS[0]]; io.cpu.value = played[RPS[1]]; io.round.value = score.turn; io.draw.value = score.draw; io.wins.value = score.wins; io.lost.value = score.lost; // Determine what will be displayed by the return of play() switch (wld) { case 0: score.draw += 1; io.draw.value = score.draw; io.message.value = "It's a Draw"; io.vs.value = "Ties with"; break; case 1: score.wins += 1; io.wins.value = score.wins; io.message.value = "You Win"; io.vs.value = "Beats"; break; case -1: score.lost += 1; io.lost.value = score.lost; io.message.value = "You Lose"; io.vs.value = "is Beaten by"; break; default: break; } }
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@300&family=Raleway:wght@500&display=swap'); @keyframes click { 0% { transform: scale(1.0); } 50% { transform: scale(0.9); } 100% { transform: scale(1.0); } } @keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes fadeOut { 0% { opacity: 1; } 100% { opacity: 0; } } @keyframes zoom { 0% { transform: scale(1); } 100% { transform: scale(4); } } * { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; } html { font: 300 4vmin/1 Oswald; } body { background-color: #333; color: #fff; } form { position: relative; min-height: 100%; } dialog { position: absolute; top: 20%; left: 50%; display: flex; flex-flow: column nowrap; justify-content: center; align-items: center; min-height: 50vh; border-color: transparent; background-color: #333; transform: translate(-50%); overflow: hidden; } dialog::backdrop { background-color: #333; } .phase { display: flex; flex-flow: column nowrap; justify-content: center; align-items: center; gap: 1rem; min-width: 70vw; padding: 1rem; border-color: transparent; color: #fff; } .buttons { display: flex; flex-flow: row nowrap; justify-content: space-around; align-items: center; gap: 1rem; padding: 1rem; border-color: transparent; } legend { display: flex; flex-flow: column nowrap; justify-content: center; align-items: center; gap: 1rem; margin-left: 50%; padding: 1rem; color: #fff; transform: translateX(-50%); } h1, h2, h3 { font-family: Raleway; white-space: nowrap; } h1 { font-size: 2.5rem; } h2 { font-size: 2.25rem; } h3 { font-size: 1.75rem; } .score { display: flex; justify-content: space-evenly; align-items: center; min-width: 100%; } output, b { display: inline-block; } output::after { content: attr(value); } .wins::before { content: 'Won '; } .lost::before { content: 'Lost '; } .draw::before { content: 'Draw '; } button { display: inline-flex; flex-flow: row nowrap; justify-content: center; align-items: center; height: 4rem; width: 10rem; border: 0.2rem solid red; border-radius: 2rem; color: #fff; font: inherit; font-size: 2rem; font-variant: small-caps; background-color: #333; cursor: pointer; } button:hover { background-color: #fff; color: red; } button:active { animation: click 0.3s forwards; } button:focus { outline: 0; } .fadeIn { animation: fadeIn 0.6s ease-out; } .fadeOut { animation: fadeOut 0.6s ease-in; } .zoom { animation: zoom 0.5s ease-out forwards; } .number { font-family: Consolas; }
<form id="roshambo"> <dialog> <fieldset id='start' class='phase'> <button name='continue' type="reset">Play</button> </fieldset> </dialog> <dialog> <fieldset id='choices' class='phase'> <legend> <h1>Rock, Paper, Scissors</h1> <h2>Round <output name='round' class='number'></output> </h2> <h3>Make Your Move</h3> <h3 class='score'> <b class='wins'> <output name='wins' class='number'></output> </b> <b class='lost'> <output name='lost' class='number'></output> </b> <b class='draw'> <output name='draw' class='number'></output> </b> </h3> </legend> <fieldset class='buttons'> <button name='rps' value='0' type='button'>🪨 Rock</button> <button name='rps' value='1' type='button'>🧻 Paper</button> <button name='rps' value='2' type='button'>✂️ Scissors</button> </fieldset> </fieldset> </dialog> <dialog> <fieldset id='animation' class='phase'> <legend> <h1></h1> </legend> </fieldset> </dialog> <dialog> <fieldset id='outcome' class='phase'> <legend> <h1><output id='message'></output></h1> <h2>Round <output name='round' class='number'></output></h2> <h3>Your <output id='you'></output> <output id='vs'></output> Your Opponent's <output id='cpu'></output> </h3> <h3 class='score'> <b class='wins'> <output name='wins' class='number'></output> </b> <b class='lost'> <output name='lost' class='number'></output> </b> <b class='draw'> <output name='draw' class='number'></output> </b> </h3> </legend> <fieldset class='buttons'> <button name='continue' type='reset'>Continue</button> <button name='clear' type='reset'>Clear</button> </fieldset> </fieldset> </dialog> </form>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.