1. JS原生扫雷
1.1 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>Document</title>
<!--
tile 默认 ba.png
showed 已点击 #C3CEE5
boom 雷 Minesmall.png
tag 小红旗 hq.png
current 移入 baq.png
-->
<link rel="stylesheet" href="sl.css">
<script src="sl.js"></script>
<script>
window.onload = init;
function init() {
document.getElementById("audio").play();
// 行列
var r_cArr = [10, 15, 20];
// 雷的个数
var mineArr = [10, 30, 80];
// 重新加载
document.getElementById('refresh').onclick = function () {
window.location.reload();
}
document.getElementById('start').onclick = function () {
if (document.getElementById('set_num').value == 3) {
var dc = document.getElementById('dc');
dc.innerHTML = '请输入行数:<input type="text" id="r">请输入列数:<input type="text" id="c">请输入雷数:<input type="text" id="mineNum"><br><button id="btn">开始游戏<tton>';
var r = document.getElementById('r');
r.onblur = function () {
r=Number(this.value);
}
var c = document.getElementById('c');
c.onblur = function () {
c=Number(this.value);
}
var mineNum = document.getElementById('mineNum');
mineNum.onblur = function () {
mineNum=Number(this.value);
}
document.getElementById('btn').onclick = function () {
dc.innerHTML = '';
var content = document.getElementById('content');
content.innerHTML = '';
mineClearance(r, c, mineNum);
}
}
// alert('开始游戏');
// 0 判断游戏是否已经开始
var content = document.getElementById('content');
content.innerHTML = '';
// 1 获取选择的难度
var value = document.getElementById('set_num').value;
// console.log(value);
// 2 获取雷的个数还有行和列
var mineNum = mineArr[value];
var r_c = r_cArr[value];
// 执行
mineClearance(r_c, r_c, mineNum);
}
}
</script>
</head>
<body>
<audio id="audio" src="./mp3/a.mp3"></audio>
<audio id="audioGameOver" src="./mp3/gameOver.mp3"></audio>
<audio id="audioClick" src="./mp3/click.mp3"></audio>
<audio id="audioMove" src="./mp3/move.mp3"></audio>
<audio id="audioBoom" src="./mp3/boom.mp3"></audio>
<select name="" id="set_num">
<option value="0">初级</option>
<option value="1">中级</option>
<option value="2">高级</option>
<option value="3">自定义</option>
</select>
<button id="start">确定</button>
<span id='refresh'>重新加载游戏</span>
<div id="dc"></div>
<div id="content">
<!-- <div class="tile">默认</div>
<div class="tile">默认</div>
<div class="tile">默认</div>
<div class="tile">默认</div>
<div class="showed">2</div>
<div class="boom">雷</div>
<div class="tile tag">小红旗</div>
<div class="tile current">鼠标移入</div> -->
</div>
</body>
</html>
1.2 css部分
*{
margin: 0;
padding: 0;
text-align: center;
font-size: 15px;
font-family: '楷体';
}
#content{
margin: 0 auto;
}
/* 重新加载游戏 */
#refresh{
display: inline-block;
height: 30px;
width: 100px;
line-height: 30px;
border: 1px solid gray;
border-radius: 5px;
background-color: hotpink;
color: white;
cursor: pointer;
}
/* 默认 */
.tile,.showed,.boom{
width: 48px;
height: 48px;
border: 1px solid ;
float: left;
cursor: pointer;
}
.tile{
background: url(./img/ba.png);
}
/* 已点击 */
.showed{
background-color: #C3CEE5;
line-height: 49px;
}
/* 雷 */
.boom{
background: #C3CEE5 url(./img/Minesmall.png);
}
.current{
background: url(./img/baq.png);
}
/* 小红旗 */
.tag{
/* 添加多个背景图片,前面的优先 */
background: url(./img/hq.png),url(./img/ba.png);
}
1.3 JS部分
function mineClearance(row, column, mine_num) {
// 属性配置
var settings = {
// 行
row: row,
// 列
column: column,
// 雷
mine_num: mine_num,
// 盒子ID
obj: 'content',
// 生成的每一个小div
tiles: [],
// 表示是否是第一次点击
flag: true,
// 保存某个元素的周边八个元素
arr: []
};
// 创建画板
buildTiles();
// 绑定事件
event();
/**
* 创建画板的函数
*/
function buildTiles() {
// 获取画板对象
var obj = document.getElementById(settings.obj);
// 每个小div大小是51*51
// 所以 画板大小为 51*column , 51*row
obj.style.width = 51 * settings.column + 'px';
obj.style.height = 51 * settings.row + "px";
// 生成小div
// 对div添加索引,0开始,一次递增,方便获取周边八个div
var indexOfdiv = 0;
for (let i = 0; i < settings.row; i++) {
for (let j = 0; j < settings.column; j++) {
// 创建div
var tile = document.createElement('div');
// 设置默认 class
tile.className = 'tile';
// 添加索引
tile.index = indexOfdiv++;
// 添加自定义属性,当mine值为0时,说明不是雷
tile.setAttribute('mine', 0);
// 保存到数组中
settings.tiles.push(tile);
// 添加到画板中
obj.appendChild(tile);
}
}
}
/**
* 绑定事件的函数
*/
function event() {
// 创建画板对象
var obj = document.getElementById(settings.obj);
// 对画板绑定事件,通过事件源找到每一个小div
// 移入
obj.onmousemove = function (e) {
// 判断事件源是否是可以点击的小div
// console.log(e.target.className, e.target.className == 'tile');
playMove();
if (e.target.className == 'tile') {
e.target.className = 'tile current';
}
}
// 移出
obj.onmouseout = function (e) {
// 判断事件源是否是可以点击的小div
if (e.target.classList.contains('current')) {
e.target.className = e.target.className.replace('current', '').trim();
}
}
// 右键标记小红旗
obj.oncontextmenu = function (e) {
// 判断事件源是否是可以点击的小div
if (!e.target.classList.contains('showed') && !e.target.classList.contains('boom')) {
if (e.target.classList.contains('tag')) {
e.target.className = e.target.className.replace('tag', '').trim();
} else {
// 注意空格,多类名以空格隔开
e.target.className += ' tag';
}
}
// 清除浏览器默认右键事件
return false;
}
// 点击事件
obj.onclick = function (e) {
playClick();
// 点击的div索引
var index = e.target.index;
// 点击的div对象
var obj = e.target;
// console.log(index);
// 判断是否添加小红旗
if (e.target.classList.contains('tag')) {
alert('有小红旗不能点击');
return;
}
// 判断是不是第一次点击
if (settings.flag) {
// 设置为false,下次点击不再初始化
settings.flag = false;
// 如果是第一次点击就初始化雷
for (let i = 0; i < settings.mine_num; i++) {
// 随机数 : 0~99之间
// 结果 = 向下取整(随机数*(最大值-最小值+1)+最小值)
var randomNum = Math.floor(Math.random() * settings.tiles.length);
// 保证第一次点击的一定不是雷
// if(randomNum == index){
// i--;
// continue;
// }
// 获取对应索引的div对象,判断mine的值是否是0
var divObj = settings.tiles[randomNum];
// 如果是0 则设置为1
if (divObj.getAttribute('mine') == 0) {
divObj.setAttribute('mine', 1);
} else {
// 如果是1 说明已经设置过了,需要i
i--;
}
}
// 设置周围几个雷
showValue();
}
// 初始化完成,判断点击的是不是雷等
if (obj.getAttribute('mine') == 0) {
// 设置为已点击状态
obj.className = 'showed';
// 设置周围 雷的个数
obj.innerHTML = obj.getAttribute('value') == 0 ? '' : obj.getAttribute('value');
// 显示周围的div,扩散
showAll(index);
}else{
playBoom();
}
// 判断游戏是否结束
// 如果结束了就显示所有 div信息
var isOver = over(obj);
if (isOver) {
// 到这里说明游戏结束
last();
playGameover();
}
}
}
//音效
function playGameover(){
document.getElementById("audioGameOver").play();
}
function playClick(){
document.getElementById("audioClick").play();
}
function playBoom(){
document.getElementById("audioBoom").play();
}
function playMove(){
document.getElementById("audioMove").play();
}
/**
* 判断游戏是否结束,参数为点击的对象
* @param {*} obj
*/
function over(obj) {
// 默认没有结束,true表示结束
var flag = false;
// 获取所有已点击的
var showed = document.getElementsByClassName('showed');
// 失败 : 判断点击的是不是雷
if (obj.getAttribute('mine') == 1) {
flag = true;
alert('很遗憾...啥也不是');
} else if (showed.length + settings.mine_num == settings.tiles.length) {
// 胜利 : 已点击的div+雷的个数 = 总数
flag = true;
alert('一不小心就让你赢了 ');
}
return flag;
}
/**
* 游戏结束后,重置div,把雷和不是雷都显示出来
*/
function last() {
// 遍历所有div , tiles
for (let i = 0; i < settings.tiles.length; i++) {
// 判断mine 是否是1
if (settings.tiles[i].getAttribute('mine') == 1) {
// 如果是1 ,class设置为boom
settings.tiles[i].className = 'boom';
} else {
// 如果不是1 , class设置为 showed
settings.tiles[i].className = 'showed';
}
// 显示周围雷的个数
if (settings.tiles[i].className != 'boom') {
settings.tiles[i].innerHTML = settings.tiles[i].getAttribute('value') == 0 ? '' : settings.tiles[i].getAttribute('value');
}
}
// 取消点击事件
document.getElementById(settings.obj).onclick=null;
}
/**
* 显示周围多少雷,递归扩散
*
* 参数是当前的div索引
*
* @param {*} index
*/
function showAll(index) {
// 1 判断当前是否是雷
// 2 如果周围八个中 有class为showed 说明不是雷
// 3 判断该对象周围是否有雷(value属性是否等于0)
// 4 如果value为0,则获取周围八个元素,然后再递归判断周围八个元素的周围元素是否有雷
if (settings.tiles[index].className == 'showed' && settings.tiles[index].getAttribute('value') == 0) {
// 获取周围八个元素
store(index);
// 把周围八个保存为局部变量,否则获取周围八个元素的时候会重新对settings.arr重新赋值
var arr2 = settings.arr;
for (let i = 0; i < arr2.length; i++) {
// 判断周围元素是否为未点击状态
if (arr2[i].className != 'showed') {
// 判断是否周围没有雷
if (arr2[i].getAttribute('value') == 0) {
// 如果没有 设置为显示状态
arr2[i].className = 'showed';
// 并且递归获取该元素周围八个的情况
showAll(arr2[i].index);
} else {
// 到这里说明周围有雷
// 设置为显示状态
arr2[i].className = 'showed';
// 设置周围雷的个数
arr2[i].innerHTML = arr2[i].getAttribute('value');
}
}
}
}
}
/**
* 设置value属性,保存的是周边八个div中有几个雷
*/
function showValue() {
// 保存周围雷的个数
var count = 0;
// 0 遍历所有元素
for (let i = 0; i < settings.tiles.length; i++) {
// 判断是否是雷,因为雷不需要设置周围雷的个数
if (settings.tiles[i].getAttribute('mine') == 1) {
continue;
}
// 1 获取每一个周边八个元素
store(settings.tiles[i].index);
// 2 判断每个元素的mine属性是否是1
// 遍历周边八个元素有几个雷
for (let j = 0; j < settings.arr.length; j++) {
if (settings.arr[j].getAttribute('mine') == 1) {
// 3 统计有多少个雷
count++;
}
}
// 4 设置到该标签中 value 表示周围雷的个数
settings.tiles[i].setAttribute('value', count);
// 重新把count清除,然后重新计算
count = 0;
}
}
/**
* 获取并存储指定元素周围的八个元素
*
* 一维数组实现方式
*
* index 就是该元素的索引
* @param {*} index
*/
function store(index) {
// 存储列
var column = settings.column;
// 清空原来周边八个的数组
settings.arr = [];
// 上 : index - 列 , 结果如果小于0 说明没有上面的(比如第一排)
if (index - column >= 0) {
settings.arr.push(settings.tiles[index - column]);
}
// 下 : index + 列 , 结果如果大于等于长度,说明没有(比如最后一排)
if (index + column < settings.tiles.length) {
settings.arr.push(settings.tiles[index + column]);
}
// 左 : index % 列 取余,结果为0 说明没有左,比如 最左边一列,如果不是0,则为 index-1
if (index % column != 0) {
settings.arr.push(settings.tiles[index - 1]);
}
// 右 : (index + 1)%列 取余,结果为0,说明没有有,比如最右边一列
if ((index + 1) % column != 0) {
settings.arr.push(settings.tiles[index + 1]);
}
// 右上 : (index-列+1)%列 取余,结果为0说明没有右上(比如最后一列) 并且 index - 列 +1 , 结果如果小于0 说明没有右上面的(比如第一排)
if ((index + 1) % column != 0 && index - column >= 0) {
settings.arr.push(settings.tiles[index - column + 1]);
}
// 左上 : index % 列 取余,结果为0 说明没有左上,比如 最左边一列,并且 index - 列 -1 , 结果如果小于0 说明没有左上面的(比如第一排)
if (index % column != 0 && index - column >= 0) {
settings.arr.push(settings.tiles[index - column - 1]);
}
// 右下 : 右 && 下,通过上面规则,右下,就是符合右的条件也符合下的条件
if ((index + 1) % column != 0 && index + column < settings.tiles.length) {
// index + 列 + 1
settings.arr.push(settings.tiles[index + column + 1]);
}
// 左下 : 左 && 下
// index + 列 - 1
if (index % column != 0 && index + column < settings.tiles.length) {
// index + 列 + 1
settings.arr.push(settings.tiles[index + column - 1]);
}
}
}
2. jQuery
2.1 基础
<script>
// windows.onload JS写法两个onload会覆盖掉前面的
window.onload = function () {
console.log(1111);
}
window.onload = function () {
console.log(2222);
}
//jQuery写法不会覆盖
// var $;
// var jQuery = $;
jQuery(document).ready(
function () {
console.log(3333);
});
jQuery(document).ready(
function () {
console.log(3333);
});
$(document).ready(
function () {
console.log(4444);
});
//简写方式
$(function(){
console.log(5555);
});
</script>
2.2 选择器
2.2.1 什么是jQuery选择器
1、jQuery 选择器允许您对 HTML 元素组或单个元素进行操作。
2、jQuery选择器是jQuery为我们提供的一组方法,让我们更加方便的获取到页面中的元素。注意:jQuery选择器返回的是jQuery对象。
3、jQuery 选择器基于元素的 id、类、类型、属性、属性值等"查找"(或选择)HTML 元素。 它基于已经存在的 CSS 选择器,除此之外,它还有一些自定义的选择器。
4、jQuery 中所有选择器都以美元符号开头:$()。
2.2.2 基本选择器
名称 | 用法 | 描述 |
ID选择器 | $(“#id”); | 获取指定ID的元素 |
类选择器 | $(“.class”); | 获取同一类class的元素 |
标签选择器 | $(“div”); | 获取同一类标签的所有元素 |
并集选择器 | $(“div,p,li”); | 使用逗号分隔,只要符合条件之一就可。获取所有的div、p、li元素 |
交集选择器(标签指定式选择器) | $(“div.redClass”); | 注意选择器1和选择器2之间没有空格,class为redClass的div元素,注意区分后代选择器。 |
2.2.3 层级选择器
名称 | 用法 | 描述 |
子代选择器 | $(“ul>li”); | 使用>号,获取儿子层级的元素,注意,并不会获取孙子层级的元素 |
后代选择器 | $(“ul li”); | 使用空格,代表后代选择器,获取ul下的所有li元素,包括孙子等 |
2.2.4 过滤选择器
用法 | 描述 | |
:eq(index) | $(“li:eq(2)”).css(“color”, ”red”); | 获取到的li元素中,选择索引号为2的元素,索引号index从0开始。 |
:odd | $(“li:odd”).css(“color”, ”red”); | 获取到的li元素中,选择索引号为奇数的元素 |
:even | $(“li:even”).css(“color”, ”red”); | 获取到的li元素中,选择索引号为偶数的元素 |
总结:这类选择器都带冒
2.2.5 筛选选择器(方法)
用法 | 说明 | |
children(selector) | $(“ul”).children(“li”) | 相当于$(“ul>li”),子类选择器 |
find(selector) | $(“ul”).find(“li”); | 相当于$(“ul li”),后代选择器 |
siblings(selector) | $(“#first”).siblings(“li”); | 查找兄弟节点,不包括自己本身。 |
parent() | $(“#first”).parent(); | 查找父亲 |
eq(index) | $(“li”).eq(2); | 相当于$(“li:eq(2)”),index从0开始 |
next() | $(“li”).next() | 找下一个兄弟 |
prev() | $(“li”).prev() | 找上一次兄弟 |
Index() | $(“li”).index() | 获取当前的位置(索引) |
not() | $("p").not(".intro") | 返回不带有类名 "intro" 的所有 <p> 元素 |
<script>
// ID选择器
$("#ID属性值");
$("#btn")
// 类选择器
$(".class属性值");
$(".dv")
// 标签选择器
$("标签名");
$('div')
// 交集选择器
$("标签.class属性值");
$('div.dv')
// 并集选择器
$("选择器,选择器,...");
$("li,a,p")
// 子代
$('选择器>选择器');
$('ul>li')
// 后代
$('选择器 选择器');
$('ul a');
// 属性选择器
// 有type属性的input标签对象
$('input[type]')
// type属性值为password的input标签对象
$('input[type="password"]')
// 有href属性的a标签
$('a[href]')
// ^ 打头 $ 结尾
// 有href属性并且是http开头的a标签
$('a[href^=http]')
// 有href属性并且以com结尾的a标签
$('a[href$=com]')
</script>
2.3 过滤选择器
<script>
$(function(){
// css() : 设置样式
// 1 可以链式调用
// 2 传一个参数,如果是对象,则用来设置多个属性和值
// 3 传两个参数,第一个是属性,第二个是值,用于设置单个属性
// 4 传一个参数,如果是属性名,则返回该属性对应的值,不能链式调用
// 下标 0 开始
// 获取所有的li,然后只要第三个
// $("li:eq(2)").css('color','red');
// odd 奇数 , even 偶数 下标0开始
// 引号中,-可以写,也可以转换为首字母大写,但是不在引号中则必须转换为大写
// $("li:even").css({
// 'background-color': 'red',
// fontSize: '20px'
// });
$("li:lt(2)").css('color','pink');
$('li:gt(3)').css('color','green');
});
</script>
2.4 筛选选择器
<script>
$(function(){
// 获取div所有的子标签
// $("div").children().css('color','red');
// 获取div下指定子标签(不包括后代)
// $("div").children('span').css('color','red');
// 获取div下指定后代标签
// $("div").find('span').css('color','red');
// 获取第二个子标签(下标0开始)
// $("div").children().eq(1).css('color','red');
// 获取h2所有的兄弟(同级别,当前作用域中,非自己)
// $('h2').siblings().css('color','red');
// next 下一个弟弟妹妹, nextAll,所有的弟弟妹妹
// $('h2').nextAll().css('color','red');
// prev : 上一个哥哥 , prevAll : 所有的哥哥
// $('h2').prevAll().css('color','red');
// 父标签
// $('h2').parent().css('color','red');
// not 不要谁
$('div').children().not('.h,span').css('color','red');
// 获取 span标签在div中的索引(是第几个子标签,下标0开始)
// 1
console.log($("div").children('span').index());
});
</script>