bilibili JS 视频链接:https://www.bilibili.com/video/BV1W54y1J7Ed?p=2&spm_id_from=pageDriver
vscode 配置 html:https://blog.csdn.net/caohongxing/article/details/108632859
目录
- JS来源
- JavaScript 核心由三部分组成
- 书写位置:行内式,内嵌式,外链式
- 变量:var 准备一个容器,变量名有规格且区分大小写
- JS中的数据:基本数据类型和引用数据类型
- 数据类型转换
- 运算符
- 分支switch
- 作用域
- 数组常用方法
- 字符串常用方法
- 数字常用方法
- 一个引用数据类型:时间(Date),及常用方法
- BOM操作 操作浏览器相关的内容
- 定时器:每间隔一段时间修改一下文本内容
- DOM 节点操作:创建、插入、删除、替换、克隆节点
- 回到顶部功能
- 多项CheckBox选择卡全选功能
- 选项卡:控制不同叠层的显示与隐藏
- 动态渲染
- 事件绑定的三要素
- 鼠标跟随:一个标记一直跟着鼠标走
- 轮播图
- vs内常用快捷键
JS来源
- 借鉴了C语言的基本语法
- 借鉴了Java语言的数据类型和内存管理
- 借鉴了Scheme语言,将函数提升到第一等公民的地位
- 借鉴了Self 语言,使用基于原型的继承机制
JavaScript 核心由三部分组成
- BOM:操作浏览器部件
- DOM:操作文本流
- ECMAScript:JS的语法规则(这才是核心)
书写位置:行内式,内嵌式,外链式
行内式:(把JS直接写在标签里)
- a标签:写在href属性里
-
<a href="javascript: codecode;">here</a>
- 非a标签:写在行为属性里
-
<div onclick="alert('hello world')">非a标签</div>
<!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></head><body><a href="javascript: alert('hello javascirpt');">a标签</a><div onclick="alert('hello world')">非a标签</div></body></html>
内嵌式:把代码书写在一个script标签对内(这种不需要任何行为会自动执行JS代码)
<!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></head><body><script>alert("hello word");</script></body></html>
外链式:把代码书写在一一个.js 文件内,如:在同目录下新建一个JS文件,写入
alert("hello word");
之后再HTML中引用:
<script src='./test.js'></script>
注:行内式能不用就不用;内嵌式学习的使用;推荐外链式
变量:var 准备一个容器,变量名有规格且区分大小写
// 单行注释/* 多行注释var numb = 100;*/var numb = 100;numb = 200;
输出方式:
// 在浏览器弹窗中显示alert("hello alert");// 在控制台中打印console.log("hello log");// 在页面中打印document.write("hello document");
JS中的数据:基本数据类型和引用数据类型
基本数据类型:
- 数值类型:Number
- 字符串类型:string 由单引号或双引号括起来
- 布尔类型:Boolean false true
- 空类型:有两种(undefined 和 null)
var n1 = 100;var n2 = -10.4;// 科学计数var n3 = 2e5 // 2 * 10^5// 十六进制;八进制;二进制var n4 = 0x100; // 1 * 16^2var n5 = 0o100; // 1 * 8^2var n6 = 0b100; // 1 * 2^2// null:表示有值,值为空var k1 = null;// Undefined:真没有值var k2;// 获取变量类型var type_k1 = typeof k1;
语句需要分号结尾吗?加不加都行
数据类型转换
// 转数值:如果字符不是纯数字,n1的结果为NaN:not a numbervar n1 = Number('1.3');var n2 = parseInt('100ac'); // 从头开始发现数值,到第一个不是数字的地方停止。var n3 = parseFloat('10.56ccc'); // 会解析小数点// 转字符串var s1 = string(true); // :truevar s2 = n1.toString();// 转布尔:有五个内容会转为false(0, NaN, '', undefined, null),其他为truevar b1 = Boolean(0);
运算符
// 算术:+、-、*、/、%// + ==> 两边数字或布尔值可以计算;或字符串拼接var s1 = '10' + 20; // 打印 1020,类型为字符串// 赋值:=、+=、-=、*=、/=、%=s1 += '200';// 比较:得到的结果一定是一个布尔值 >, <, >=, <=, ==(等于), ===(全等于), !=(不等于), !==(不全等于)var b1 = 10 == '10'; // 先做类型变换,再比较,所以是相等的 truevar b2 = 10 === '10'; // 先比较类型,再比较数值,所以是不相等的 faslevar b3 = 10 != '10'; // 只比较值,不看类型,值相等就为真;两个值都是10,所以这个为 falsevar b4 = 10 !== '10'; // 值 或 类型 任意一个不相等时才为真,所以这个为 true// 逻辑: && || !// 自增自减(有前置或后置,同C): ++ --
判断if
-
if(){}
-
if(){} else{}
-
if(){} else if(){}
-
if(){} else if(){} else{}
分支switch
switch(value){case 100:console.log('100');break;case 200:console.log('200');break;default:console.log('no');}
循环:
-
whick(){}
-
do{} while();
-
for(var i = 0; i < 3; i++){}
函数:
function fn(){return;}
调用:
fn();
作用域
作用域:只有函数可以生成私有作用域,那for循环里定义的
var i = 0;
,依旧可以在for循环之后使用。
一个引用数据类型:对象数据类型(object),对应python中的字典类型数据
-
var obj = {1: 1, 'j': 'j', true: true}
,key和value中的值都可以是任意类型
- 中括号中的是字符串
- 增:
obj.'c' = 'c';
,
obj[c] = true;
- 删:
delete obj.'c';
,
delete obj[c];
- 改:和增加的语法一样
- 查:
obj.'c'
,
obj[c]
一个引用数据类型:数组(array)
- 有序的(从0开始)、数据集合,且类型任意
-
var arr = [100, true, 'cha'];
- 获取长度:
arr.length
;设置长度:
arr.length = 4;
(小了会删除,大 了会?)
- 获取数据及赋值:
arr[2] = 400;
数组常用方法
// push 在数组末尾追加数据,返回最新长度// pop 删除数组最后一个数据,返回删除的数据var new_lenght = arr.push('new data');var delete_data = arr.pop();// unshift 在数组开始追加数据,返回最新长度// shift 删除数组最前一个数据,返回删除的数据var new_lenght = arr.unshift("start data");var delete_data = arr.shift();// reverse 数组反转var new_arr = arr.reverse()// splice 删除 数组中若干数据,并选择是否插入新的数据// 参数:开始索引(0),多少个(0), 要插入的数据(没有)// 以新数组的形式返回被删除的那些数据var delete_arr = arr.splice(1, 1); // 索引1开始删除一个数据,无插入var delete_arr = arr.splice(1, 1, 'new data'); // 索引1开始删除一个数据,并在删除位置插入新数据// sort 排序,本身返回按位排序的,非自然序列// 升序:sort(function(a, b){return a-b;});// 降序:sort(function(a, b){return b-a;});// 返回排序的数组var new_arr = arr.sort();// join 使用连接符,将数组的元素连接成一个字符串var strs = arr.join('-');// concat 数据拼接,在前一个数组后面扩展var new_arr = arr1.concat(arr2);// slice 切片// 参数:开始索引(默认0),结束索引(默认数组长度),返回切片数组var new_arr = arr.slive(1);// indexOf 查找数据在数组中第一次出现的位置,没有 就是返回-1// 参数:查找的数据var data_index = arr.indexOf(data);// forEach 遍历数组arr.forEach(function(item, index, arr){// to do})// map 返回新数组var new_arr = arr.map(function(item, index, arr){// 映射条件return item * 10;})// filter 过滤数组var new_arr = arr.filter(function(item, index, arr){// 过滤条件return item > 10;})// every 判断数组是不是每一项都满足条件,返回一个布尔值var is_right = arr.every(function(item, index, arr){// 过滤条件return item > 10;})// some 数组中是不是有某一项满足条件,返回一个布尔值var is_right = arr.some(function(item, index, arr){// 过滤条件return item > 10;})
字符串常用方法
// charAt 获取对应位置字符,数组越界?var str = strs.charAt(3);// toLowerCase 所有大写字母全部转化成小写// toUpperCase 与之相反var strs = strs.toLowerCase();// replace 替换var strs = strs.replace(',', '.');// trim 去除首尾空格var strs = strs.trim()// split 分割var strs_arr = strs.split('-')// 截取字符串 后两个有什么区别// strs.sbustr(开始索引,多少个)// strs.shustring(开始索引,结束索引)// strs.slice(开始索引,结束索引)var new_strs = strs.sbustr(1, 6); // 从索引1开始截取6个字符var new_strs = strs.shustring(1, 6) // [1, 6)var new_strs = strs.slice(1, 6) // [1, 6)
数字常用方法
// random 返回[0, 1)上的一个随机小数,小数点后17位var num = Math.random();// round 四舍五入保留整数// ceil 向上取整// floor 向下取整var num = Math.round(10.5);// pow 乘方运算// sqrt 开平方var num = Math.pow(2, 5); // 2^5// abs 取绝对值var num = Math.abs(-8);// max 获取若干数据的最大值// minvar num = Math.max(-8, 4, 5, 7, 90);// Math.PIvar num = Math.PI()// 返回一个随机数function randomNum(min, max){return Math.floor(Math.random() * (max-min+1)) + min}
一个引用数据类型:时间(Date),及常用方法
// 创建一个时间对象,且是当前终端的时间var time = new Date();// 0表示1月,11表示12月var time = new Date(2021, 10, 15, 19, 45, 59); // 2021年11月15号19时45分59秒// 获取年 月 日 时间var year = time.getFullYear(); // 2021var month = time.getMonth(); // 10var date = time.getDate(); // 15var hours = time.getHours(); // 19var minutes = time.getMinutes(); // 45var seconds = time.getSeconds(); // 59// 获取周几,0表示周日, 3表示周三var day = time.getDay();// 获取时间戳:当前时间与格林威治时间相差的毫秒数称时间戳// 1s = 1000msvar time = time.getTime()function getDiff(start, stop){// 获取时间戳var startTime = start.getTime();var stopTime = stop.getTime();// 获取相差秒数var seconds = Math.ceil((stopTime - startTime) / 1000);// 获取时间var day = Math.floor(seconds / (60*60*24));var hours = Math.floor(seconds % (60*60*24) / (60*60));var minutes = Math.floor(seconds % (60*60) / 60);var seconds = sub % 60;return {day: day, hours: hours, minutes: minutes, seconds: soconds};}
BOM操作 操作浏览器相关的内容
- Browser Object Model
- 滚动条位置、定位刷新、后退、打开新标签等等
// 获取可视窗口尺寸var w = window.innerWidth;var h = window.innerHeight;// 弹出层:提示、询问、输入window.alert('hello');var res = window.confirm("is True?"); // 返回一个布尔值var res = window.prompt("please input"); // 返回字符串或null// 开始或关闭标签页window.open("地址");window.close();
- 关闭和打开新标签
<!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></head><body><div><button id="on"> 打开新标签 </button><button id="off"> 关闭当前页面 </button><script>on.onclick = function(){window.open('https://www.bilibili.com/video/BV1W54y1J7Ed?p=28');}off.onclick = function(){window.close();}</script></div></body></html>
- 浏览器常见事件:由浏览器触发的函数
// 等到页面所有资源加载完毕再执行window.onload = function(){// to do}// 页面大小发生改变时触发window.onresize = function(){// to do}// 滚动条位置发生改变是触发window.onscroll = function(){// to da}
- 浏览器的历史记录操作
// 前进与回退window.history.back();window.history.forward();
- 浏览器卷去尺寸:页面太大,滚动条走过的宽高
window.onscroll = function(){var height = document.documentElement.scrollTop || document.body.scrollTop;var width = document.documentElement.scrollLeft || document.body.scrollLeft;}
- 设置滚动条位置
// 瞬间定位window.scrollTo(left, top); // 参数为卷去得长度// 定位方式 smooth 平滑滚动window.scrollTo({left: 0,top: 0,beharior: 'smooth'})
定时器:每间隔一段时间修改一下文本内容
- 间隔定时器
- 延时定时器,执行一次
- 定时器有返回值,表示是哪个定时器
// 间隔var timer1 = setInterval(function(){// to do}, 1000); // 1秒执行一次// 延时var timer2 = setTimeout(function(){// to do}, 1000); // 1秒后执行// 关闭定时器,都可以互相关闭clearInterval(timer1);cleatTimeout(timer2);
DOM Document Object Model 一套操作文档流相关内容的属性和方法
- 常用五种方式
// 根据id名称获取 返回这个元素或者nullvar element = document.getElementById('');// 根据class名称获取 返回这些元素的伪数组var element = document.getElementsByClassName('');// 根据tag名称获取 返回这些元素的伪数组var element = document.getElementsByTagName('');// 根据选择器称获取 返回符合规则的第一个元素 或 nullvar element = document.querySelector('');// 根据选择器称获取 返回符合规则的所有元素 或 伪数组var element = document.querySelectorAll('');
- 操作元素内容
// 文本 内容:获取、设置var text = element.innerText;element.innerText = "new text";// 超文本 内容:设置是给元素添加新的标签,并可以渲染出来var text = element.innerHTML;element.innerHTML = "<span>new text<span>";
<!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></head><body><div><p> 文本内容 </p><button id="on"> 修改内容 </button></div><script>var but = document.querySelector('button');var p = document.querySelector('p');but.onclick = function(){p.innerText = "设置内容";}p.onclick = function(){p.innerHTML = "<span>new text<span>"}console.log(b.innerText);</script></body></html>
- 操作元素属性
// 原生属性 id src type,一般不用与操作元素的类名和样式console.log(element.id); // 获取element.id = 'cc'; // 设置// 自定义属性 自己定义的记录信息,一般不用与操作元素的类名和样式var value = element.getAttribute('name');element.setAttribute('name', 'value');element.removeAttribute('name');// 操作元素类名var name = element.className;element.className = 'new name';// 操作元素行内样式 改成驼峰法命名 只能是行样式var value = element.style.width;element.style.width = value;// 操作非行内样式,是没有设置非行内样式的var value = window.getComputedStyle(element).width;
DOM 节点操作:创建、插入、删除、替换、克隆节点
// 创建标签var tag = document.createElement('tag name');// 插入标签var fatherTag = document.querySelector('div');fatherTag.appendChild(tag); // 插入标签,放在末尾fatherTag.insertBefore(tag, signTag); // 插在fatherTag内部,signTag之前// 删除节点fatherTag.removeChild(tag);tag.remove();// 替换节点fatherTag.replaceChild(tag, signTag); // tag替换signTag// 克隆节点,参数为 是否克隆后代子节点var tag_clone = tag.cloneNode(false);
获取元素尺寸:元素的宽高
// 获取:内容+padding+bordervar height = element.offsetHeight();var width = element.offsetWidth();// 获取:内容+paddingvar height = element.clientHeight();var width = element.clientWidth();
回到顶部功能
- 滚动条滚动超过临界点,顶部通栏显示,否则隐藏滚动条滚动超过临界点,回
- 到顶部按钮显示,否则隐藏
- 点击回到顶部按钮,滚动条滚动回到顶部
布局结构:
- 需要一个顶部通栏标签和一个回到顶部按钮标签
- 让页面超过浏览器可视窗口高度
- 设置顶部通栏样式,默认是在超出页面的
- 设置回到顶部按钮样式,默认是在隐藏的
代码逻辑:
- 给浏览器绑定滚动事件,实时获取浏览器卷去的高度
- 判断卷去的高度决定隐藏还是显示
- 给回到顶部按钮绑定点击事件
<!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><style>/* 清除样式 */* {margin: 0;padding: 0;}/* 设置body 使出现滑动条*/body {height: 3000px;}/* 设置顶部通知栏样式 */.header {width: 100%;height: 80px;display: flex;justify-content: center;align-items: center;font-size: 30px;color: #fff;background-color: skyblue;/* 添加滚动效果 */transition: top .5s linear;position: fixed;/* 使标签显示在可是窗口之外 */top: -80px;left: 0;}.goTop {width: 50px;height: 50px;background-color: pink;font-size: 20px;text-align: center;line-height: 25px;color: #fff;position: fixed;bottom: 50px;right: 50px;/* 默认不显示 */display: none;}</style></head><body><!-- 添加两个标签 --><div class="header">顶部通知栏</div><div class="goTop">回到顶部</div><!-- 控制逻辑 --><script>// 获取元素var header = document.querySelector('.header');var goTop = document.querySelector('.goTop');// 控制显示标签显示和消失window.onscroll = function () {// 获取卷去高度var height = document.documentElement.scrollTop || document.body.scrollTop;if (height >= 300) {header.style.top = '0px';goTop.style.display = 'block';} else {header.style.top = '-80px';goTop.style.display = 'none';}}// 回到顶部goTop.onclick = function () {window.scrollTo({top: 0,behavior: 'smooth'})}</script></body></html>
多项CheckBox选择卡全选功能
确认需求:
- 全选按钮点击的时候,根据自身状态决定所有选项按钮状态
- 点击每一一个选项按钮的时候,根据所有选项按钮状态决定全选按钮状态
<!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><style>/* 清除样式 */* {margin: 0;padding: 0;}/* 设置顶部通知栏样式 */.box {width: 100px;padding: 20px;border: 1px solid pink;margin: 30px auto;border-radius: 5px;}hr {margin: 10px 0;}</style></head><body><!-- 添加两个标签 --><div class="box">全选:<input type="checkbox"> <br><hr><input type="checkbox"> 选项一 <br><input type="checkbox"> 选项二 <br><input type="checkbox"> 选项三 <br><input type="checkbox"> 选项四 <br></div><!-- 控制逻辑 --><script>var totalInputBtn = document.querySelector('input');var childInputBtn = document.querySelectorAll('input:nth-child(n+2)');// 将总开关的状态赋给子控件totalInputBtn.onclick = function () {var type = totalInputBtn.checked;for (var i = 0; i < childInputBtn.length; i++) {childInputBtn[i].checked = type;}}// 给子控件绑定控制事件for (var i = 0; i < childInputBtn.length; i++) {childInputBtn[i].onclick = function () {var flag = true;for (var j = 0; j < childInputBtn.length; j++) {if (childInputBtn[j].checked === false) {flag = false;break;}}totalInputBtn.checked = flag;}}</script></body></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><style>/* 清除样式 */* {margin: 0;padding: 0;}ul, ol, li {list-style: none;}/* 设置div样式 */.box {width: 600px;height: 400px;border: 3px solid pink;margin: 50px auto;display: flex;flex-direction: column;}/* 设置选项卡样式 */.box > ul {height: 60px;display: flex;}.box > ul > li {flex: 1;color: #fff;background-color: skyblue;font-size: 30px;display: flex;justify-content: center;align-items: center;cursor: pointer;}.box > ul > li.active {/* 默认第一个高亮 */background-color: orange;}.box > ol {flex: 1;position: relative;}.box > ol > li {width: 100%;height: 100%;background-color: purple;display: flex;justify-content: center;align-items: center;color: #fff;font-size: 100px;position: absolute;left: 0;top: 0;display: none;}.box > ol > li.active {display: flex;}</style></head><body><div class="box"><!-- 这三个表示三个选卡项 --><ul><li class="active">1</li><li>2</li><li>3</li></ul><!-- 这三个代表不同的内容板 --><ol><li class="active">1</li><li>2</li><li>3</li></ol></div><!-- 控制逻辑 --><script>var btns = document.querySelectorAll('ul > li');var tabs = document.querySelectorAll('ol > li')// 添加点击事件btns.forEach(function (item, index) {item.onclick = function () {btns.forEach(function (t, i) {t.className = '';tabs[i].className = '';})item.className = 'active';4000tabs[index].className = 'active';}})</script></body></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><style>/* 清除样式 */* {margin: 0;padding: 0;}table {width: 300px;text-align: center;}</style></head><body><!-- 准备一个地方 --><table><thead><tr><th>ID</th><th>Name</th><th>Gender</th></tr></thead><tbody><!-- JS 渲染 --></tbody></table><!-- 控制逻辑 --><script>// datavar users = [{id: 1, name: 'first', age: 18},{id: 2, name: 'second', age: 19},{id: 3, name: 'third', age: 20}];var tbody = document.querySelector('tbody');users.forEach(function (item) {var tr = document.createElement('tr');for (var key in item) {var td = document.createElement('td');td.innerHTML = item[key];tr.appendChild(td);}tbody.appendChild(tr);})</script></body></html>
事件绑定的三要素
- 事件源:和谁做好约定
- 事件类型:约定一个什么行为
- 事件处理函数: 当用户触发该行为的时候,执行什么代码
语法: 事件源. on事件类型 = 事件处理函数
事件类型:
事件对象:管理事件信息的数据结构
- 在绑定事件的时候,在事件函数中用一个 变量 来接收就可以,浏览器会自动传给这个变量
-
div.onclick = function(e){}
,这是e就是事件对象
事件常用信息:
鼠标事件
- offsetX与offsetY,是控件的坐标
- clientX与clientY,是可视窗口的坐标
- pageX与pageY,是文档页面的坐标
键盘事件
- 通过
e.keyCode
获取按下的按键
事件传播:浏览器响应事件机制
当我们点击了inner时(这个inner,可以叫目标),最先知道的是window,依次向内传播给inner(这个过程叫捕获阶段),之后再依次向外传播给window(这个过程叫冒泡阶段)
默认触发事件都是在冒泡阶段!
阻止事件传播:
e.stopPropagation()
事件委托:利用事件冒泡机制,将自己的事件委托给结构父级中的某一层;同时利用事件的target属性来判别是那个对象:
e.target.tagName == "DIV"
,比较是使用大写标签名
鼠标跟随:一个标记一直跟着鼠标走
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible20000" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>/* 清除样式 */* {margin: 0;padding: 0;}.sign {width: 50px;height: 50px;background-color: red;position: fixed;left: 0;top: 0;}</style></head><body><!-- 准备一个地方 --><div class="sign"></div><!-- 控制逻辑 --><script>var divSign = document.querySelector('.sign');// 给 document 绑定一个鼠标移动事件document.onmousemove = function (e) {var x = e.clientX;var y = e.clientY;divSign.style.left = x + 'px';divSign.style.top = y + 'px';}</script></body></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><style>/* 清除样式 */* {margin: 0;padding: 0;}ul, ol, li {list-style: none;}image {width: 100%;height: 100%;display: block;}.banner {width: 100%;height: 500px;position: relative;margin: 50px 0;}/* 图片 */.banner > ul {width: 100%;height: 100%;position: relative;}.banner > ul > li {width: 100%;height: 100%;position: absolute;left: 0;top: 0;/* 默认都是不显示 */opacity: 0;/* 变化效果 */transition: opacity .5s linear;}.banner > ul > li.active {/* 默认显示一个 */opacity: 1;}/* 设置焦点区域 */.banner > ol {width: 200px;height: 30px;position: absolute;left: 30px;bottom: 30px;background-color: rgba(0, 0, 0, .5);display: flex;justify-content: space-around;align-items: center;border-radius: 15px;}.banner > ol > li {width: 20px;height: 20px;background-color: #fff;border-radius: 50%;cursor: pointer;}.banner > ol > li.active {background-color: orange;}/* 左右按钮 */.banner > div{width: 40px;height: 60px;position: absolute;top: 50%;transform: translateY(-50%);background-color: rgba(0, 0, 0, .5);display: flex;justify-content: center;align-items: center;font-size: 30px;color: #fff;}.banner > div.left {left: 0;}.banner > div.right {right: 0;}</style></head><body><div class="banner"><!-- 图片区域 --><ul class="imgBox"><li class="active"><img src="./imgs/01.jpg" alt=""></li><li><img src="./imgs/02.jpg" alt=""></li><li><img src="./imgs/03.jpg" alt=""></li><li><img src="./imgs/04.jpg" alt=""></li></ul><!-- 焦点区域 --><ol><li data-i="0" data-name="point" class="active"></li><li data-i="1" data-name="point"></li><li data-i="2" data-name="point"></li><li data-i="3" data-name="point"></li></ol><!-- 左右切换按钮 --><div class="left"><</div><div class="right">></div></div><!-- 控制逻辑 --><script>// 获取图片和焦点var imgs = document.querySelectorAll('ul > li');console.log(imgs)var points = document.querySelectorAll('ol > li');console.log(points)// 当前第几张var index = 0;// 切换函数: ture/false 切换上下;数字时切换到指定章function changeOne(type) {imgs[index].className = '';points[index].className = '';// 根据参数确定index值if (type === true) {index++;} else if (type === false) {index--;} else {index = type;}// 确定index边界if (index >= imgs.length) {index = 0;}if (index < 0) {index = imgs.length - 1;}// 切换imgs[index].className = 'active';points[index].className = 'active';}// 委托事件var banner = document.querySelector('.banner');banner.onclick = function (e) {if (e.target.className === 'left') {changeOne(false);console.log('left')}if (e.target.className === 'right') {changeOne(true);console.log('right')}if (e.target.dataset.name === 'point') {var i = e.target.dataset.i - 0;changeOne(i);console.log('here')}}// 自动切换setInterval(function () {changeOne(true);}, 3000);</script></body></html>
vs内常用快捷键
- 按css选择器,输入字符,然后回车,对生成对应div标签
- 输入
ul>li*3{$}
接回车,可以生成,表格和表格项
-
ul.imgBox>li*4>img[src=./imgs/0$.jpg]