JS练习
轮播图
自动切换图片轮播
<style>
.container {
text-align: center;
margin: 0 auto;
}
.img {
width: 500px;
height: 300px;
}
</style>
<div class="container">
<img class="img">
<div class="switch">
<button class="click" onclick="switchImg(-1)">上一张</button>
<button class="click" onclick="switchImg(1)">下一张</button>
<button class="auto">自动切换</button>
</div>
</div>
<script>
console.log(document.querySelectorAll('.click'));
const imgs = ['../static/img/city-1600*1600.png', '../static/img/风景-1920*1080.jpg', '../static/img/人物-1920*1080.png', '../static/img/city-400*400.png'];
document.querySelector('.img').src = imgs[0];
let size = imgs.length;
let index = 0;
function switchImg(step) {
if (index + step < 0) {
index = size - 1;
} else if (index + step >= size) {
index = 0;
} else {
index += step;
}
document.querySelector('.img').src = imgs[index];
}
let auto = false;
let timer = null;
document.querySelector('.auto').onclick = function () {
if (auto) {
this.innerHTML = '自动切换';
clearInterval(timer);
} else {
this.innerHTML = '停止切换';
timer = setInterval(() => {
switchImg(1);
}, 1000);
}
auto = !auto;
}
</script>
轮播图片存在的问题
切换图片时重新设置图片src,导致图片重新加载网路图片,切换速度慢,因此需要先把所有图片加载到本地,再进行切换
使用定位层级原理实现轮播
<style>
.container {
text-align: center;
}
.img {
width: 500px;
height: 300px;
}
ul {
height: 300px;
width: 500px;
padding-left: 0px;
display: inline-block;
}
li {
position: absolute;
list-style: none;
opacity: 0;
}
.show {
z-index: 1;
opacity: 1;
transition: opacity 1s;
}
</style>
<div class="container">
<ul>
<li class="show"><img class="img" src="../static/img/city-1600*1600.png" alt=""></li>
<li><img class="img" src="../static/img/风景-1920*1080.jpg" alt=""></li>
<li><img class="img" src="../static/img/人物-1920*1080.png" alt=""></li>
<li><img class="img" src="../static/img/city-400*400.png" alt=""></li>
</ul>
<div class="switch">
<button class="click" onclick="switchImg(-1)">上一张</button>
<button class="click" onclick="switchImg(1)">下一张</button>
<button class="auto">自动切换</button>
</div>
</div>
<script>
let lis = document.querySelectorAll('li');
let size = lis.length;
let index = 0;
function switchImg(step) {
lis[index].classList.toggle('show');
if (index + step < 0) {
index = size - 1;
} else if (index + step >= size) {
index = 0;
} else {
index += step;
}
lis[index].classList.toggle('show');
}
let auto = false;
let timer = null;
document.querySelector('.auto').onclick = function () {
if (auto) {
this.innerHTML = '自动切换';
clearInterval(timer);
} else {
this.innerHTML = '停止切换';
timer = setInterval(() => {
switchImg(1);
}, 1000);
}
auto = !auto;
}
</script>
鼠标移动停止自动切换鼠标移出继续自动切换
并使用闭包封装定时器ID
<style>
body {
margin: 0;
}
.container {
margin-top: 60px;
text-align: center;
}
.banner {
position: relative;
width: 500px;
height: 300px;
margin: 0 auto;
}
.img {
width: 500px;
height: 300px;
}
ul {
height: 300px;
width: 500px;
margin: 0;
padding-left: 0px;
position: absolute;
}
li {
position: absolute;
list-style: none;
opacity: 0;
}
.show {
z-index: 1;
opacity: 1;
transition: opacity 1s;
}
.pre {
width: 30px;
height: 300px;
position: absolute;
top: 0;
left: 0;
line-height: 300px;
color: white;
font-size: 40px;
z-index: 2;
opacity: .5;
cursor: pointer;
transition: opacity .3s;
}
.pre:hover {
opacity: 1;
}
.next {
width: 30px;
height: 300px;
position: absolute;
top: 0;
right: 0;
line-height: 300px;
color: white;
font-size: 40px;
z-index: 2;
opacity: .5;
cursor: pointer;
transition: opacity .3s;
}
.next:hover {
opacity: 1;
}
</style>
<div class="container">
<div class="banner">
<div class="pre" onclick="switchImg(-1)"><</div>
<div class="next" onclick="switchImg(1)">></div>
<ul>
<li class="show"><img class="img" src="../static/img/city-1600*1600.png" alt=""></li>
<li><img class="img" src="../static/img/风景-1920*1080.jpg" alt=""></li>
<li><img class="img" src="../static/img/人物-1920*1080.png" alt=""></li>
<li><img class="img" src="../static/img/city-400*400.png" alt=""></li>
</ul>
</div>
</div>
<script>
let lis = document.querySelectorAll('li');
let size = lis.length;
let index = 0;
function switchImg(step) {
lis[index].classList.toggle('show');
if (index + step < 0) {
index = size - 1;
} else if (index + step >= size) {
index = 0;
} else {
index += step;
}
lis[index].classList.toggle('show');
}
let toggleAuto = (
function () {
let timer = null;
return () => {
if (timer) {
clearTimeout(timer);
timer = null;
} else {
timer = setTimeout(function autoSwitch() {
switchImg(1);
timer = setTimeout(autoSwitch, 1000);
}, 1000);
}
}
}
)();
toggleAuto();
document.querySelector('.banner').addEventListener('mouseenter', function () {
toggleAuto();
});
document.querySelector('.banner').addEventListener('mouseleave', function () {
toggleAuto();
});
</script>
轮播图添加当前轮播图索引
<style>
body {
margin: 0;
}
.container {
margin-top: 60px;
text-align: center;
}
.banner {
position: relative;
width: 500px;
height: 300px;
margin: 0 auto;
}
.img {
width: 500px;
height: 300px;
}
ul {
height: 300px;
width: 500px;
margin: 0;
padding-left: 0px;
position: absolute;
}
li {
position: absolute;
list-style: none;
opacity: 0;
}
.show {
z-index: 1;
opacity: 1;
transition: opacity 1s;
}
.pre {
width: 30px;
height: 300px;
position: absolute;
top: 0;
left: 0;
line-height: 300px;
color: white;
font-size: 40px;
z-index: 2;
opacity: .5;
cursor: pointer;
transition: opacity .3s;
}
.pre:hover {
opacity: 1;
}
.next {
width: 30px;
height: 300px;
position: absolute;
top: 0;
right: 0;
line-height: 300px;
color: white;
font-size: 40px;
z-index: 2;
opacity: .5;
cursor: pointer;
transition: opacity .3s;
}
.next:hover {
opacity: 1;
}
.dot {
width: 500px;
height: 20px;
position: absolute;
z-index: 3;
bottom: 10px;
text-align: center;
}
.dot-item {
width: 20px;
height: 20px;
background-color: grey;
border-radius: 50%;
display: inline-block;
font-size: 12px;
line-height: 20px;
opacity: 0.4;
cursor: pointer;
}
.dot-item:hover {
opacity: 1;
}
.dot-item-active {
opacity: 1;
}
</style>
<div class="container">
<div class="banner">
<div class="pre" onclick="switchImg(-1)"><</div>
<div class="next" onclick="switchImg(1)">></div>
<ul>
<li class="show"><img class="img" src="../static/img/1.jpg" alt=""></li>
<li><img class="img" src="../static/img/2.jpeg" alt=""></li>
<li><img class="img" src="../static/img/3.jpeg" alt=""></li>
<li><img class="img" src="../static/img/4.jpg" alt=""></li>
</ul>
<div class="dot">
<span class="dot-item" onclick="switchImg(0,0)">1</span>
<span class="dot-item" onclick="switchImg(0,1)">2</span>
<span class="dot-item" onclick="switchImg(0,2)">3</span>
<span class="dot-item" onclick="switchImg(0,3)">4</span>
</div>
</div>
</div>
<script>
let lis = document.querySelectorAll('li');
let size = lis.length;
let index = 0;
function switchImg(step, showIndex) {
lis[index].classList.remove('show');
document.querySelectorAll('.dot-item')[index].classList.remove('dot-item-active');
if (showIndex !== undefined) {
index = showIndex;
} else {
if (index + step < 0) {
index = size - 1;
} else if (index + step >= size) {
index = 0;
} else {
index += step;
}
}
lis[index].classList.add('show');
document.querySelectorAll('.dot-item')[index].classList.add('dot-item-active');
}
let toggleAuto = (
function () {
let timer = null;
return () => {
if (timer) {
clearTimeout(timer);
timer = null;
} else {
timer = setTimeout(function autoSwitch() {
switchImg(1);
timer = setTimeout(autoSwitch, 1000);
}, 1000);
}
}
}
)();
toggleAuto();
document.querySelector('.banner').addEventListener('mouseenter', function () {
toggleAuto();
});
document.querySelector('.banner').addEventListener('mouseleave', function () {
toggleAuto();
});
</script>
贪吃蛇
1.每个蛇节点使用定位布局
2.蛇的移动方式: 把蛇尾节点位置移动到蛇头节点前面的位置,并把蛇尾节点放到蛇头节点位置
3.撞墙和撞自己:
(1)蛇头下一个位置是否超过了边界
(2)蛇头下一个位置是否和其他蛇节点有重合,除了蛇尾节点(因为蛇头下一步可能会移动到蛇尾节点位置)
4.在没有完成移动前,方向按键不可用
<style>
body {
margin: 0;
}
.container {
margin: 0 auto;
width: 340px;
height: 400px;
border: 10px solid black;
border-radius: 5%;
background-color: #b7d4a8;
}
.border {
width: 300px;
height: 300px;
margin: 0 auto;
margin-top: 15px;
border: 2px solid black;
position: relative;
}
.info {
margin: 0 auto;
margin-top: 30px;
width: 300px;
height: 50px;
text-align: center;
display: flex;
justify-content: space-between;
font-weight: bold;
}
.snake {
position: absolute;
left: 0;
bottom: 0;
}
.food {
width: 10px;
height: 10px;
background-color: red;
position: absolute;
margin: 1px;
}
.snake-node {
position: absolute;
width: 10px;
height: 10px;
margin: 1px;
background-color: black;
left: 0;
bottom: 0;
}
</style>
<div class="container">
<div class="border">
<div class="snake">
</div>
<div class="food"></div>
</div>
<div class="info">
<div class="scoreInfo">
SCORE:
<span class="score">0</span>
</div>
<div class="levelInfo">
LEVEL:
<span class="score">1</span>
</div>
</div>
</div>
<script>
let step = 12;
let defaultLength = 7;
let score = defaultLength;
let moveDirection = 'right';
let speed = 200;
let gameOver = false;
// true时可以控制方向,false时说明正在移动,不能重复设置方向
let setDirection = true;
let snakeNode = document.createElement('div');
snakeNode.classList.add('snake-node');
let snake = document.querySelector('.snake');
let food = document.querySelector('.food');
let scoreNode = document.querySelector('.score');
scoreNode.innerHTML = score;
food.style.left = Math.floor(Math.random() * 25) * step + 'px';
food.style.bottom = Math.floor(Math.random() * 25) * step + 'px';
for (let i = 0; i < defaultLength; i++) {
let node = snakeNode.cloneNode();
left = (defaultLength - 1 - i) * step;
node.style.bottom = 0 + 'px';
node.style.left = 0 + 'px';
snake.appendChild(node);
}
function move() {
if (hit()) {
gameOver = true;
alert('game over');
return;
}
nodeMove();
setDirection = true;
}
let toggleMove = (function () {
let timer = null;
return () => {
if (timer === null) {
timer = setTimeout(function autoMove() {
if (gameOver) {
clearTimeout(timer);
timer = null;
return;
}
move();
timer = setTimeout(autoMove, speed);
}, speed)
} else {
clearTimeout(timer);
timer = null;
}
}
})();
toggleMove();
function nodeMove() {
let { x, y } = headLeftAndBottom();
if (parseInt(food.style.left) === x && parseInt(food.style.bottom) === y) {
let last = snake.lastElementChild;
snake.appendChild(last.cloneNode());
food.style.left = Math.floor(Math.random() * 25) * step + 'px';
food.style.bottom = Math.floor(Math.random() * 25) * step + 'px';
score += 1;
scoreNode.innerHTML = score;
}
// 把蛇尾移动到蛇头前面
snake.lastElementChild.style.left = x + 'px';
snake.lastElementChild.style.bottom = y + 'px';
// 交换结构位置,始终让蛇头节点在元素的第一个位置
snake.insertBefore(snake.lastElementChild, snake.firstElementChild);
}
function hit() {
// 如果蛇头下个位置和每个节点进行位置比较,除了蛇尾节点,如果有重合说明会撞到自己
let { x, y } = headLeftAndBottom();
let nodes = [...snake.children];
for (let index = 1; index < nodes.length - 1; index++) {
let node = nodes[index];
if (parseInt(node.style.left) === x && parseInt(node.style.bottom) === y) {
return true;
}
}
// 不能越过边界
if (x < 0 || x >= 300 || y < 0 || y >= 300) {
return true;
}
}
document.onkeydown = function (e) {
if (e.keyCode === 38 && moveDirection !== 'bottom' && setDirection) {
moveDirection = 'top';
setDirection = false;
} if (e.keyCode === 40 && moveDirection !== 'top' && setDirection) {
moveDirection = 'bottom';
setDirection = false;
}
if (e.keyCode === 37 && moveDirection !== 'right' && setDirection) {
moveDirection = 'left';
setDirection = false;
}
if (e.keyCode === 39 && moveDirection !== 'left' && setDirection) {
moveDirection = 'right';
setDirection = false;
}
}
function headLeftAndBottom() {
let x = parseInt(snake.firstElementChild.style.left);
let y = parseInt(snake.firstElementChild.style.bottom);
if (moveDirection === 'right') {
x += step;
}
if (moveDirection === 'bottom') {
y -= step;
}
if (moveDirection === 'top') {
y += step;
}
if (moveDirection === 'left') {
x -= step;
}
return { x, y };
}
</script>