组成
ECMAscript 基础语法
变量 数据类型 运算符 数组 函数 对象
BOM 浏览器对象模型
window对象(获取浏览器宽高)
history对象
location对象
DOM 文档对象模型 轮播图
元素获取 操作属性 操作样式 节点 事件 时间对象
作用:(运营在用户端浏览器)
1. 数据验证
2. 动态创建和删除元素
3. 操作元素的内容和样式
4. 模拟动画
5. 创建cookie
6. ajax 请求数据
。。。。。。
7. JSON格式的数据处理 *
特征:面向对象
1. 基于[对象]和[事件驱动]的松散型 解释型语言
2. 客户端脚本语言,实现用户交互
BOM: 浏览器对象模型
完成窗口与窗口之间的通信,window对象是其核心对象,
history【前进,后退,刷新】 是一个对象 使用【window.history】
location【地址】
DOM【】
screen【屏幕】
frames[真窗口]
navigation
window对象:
属性
1-1:获取浏览器宽高
a.ie8及以上
window.innerWidth [获取浏览器宽度]
window.innerHeight [获取浏览器高度]
b.ie8以下
document.documentElement.ClientWidth [宽度]
document.documentElement.ClientHeight 【高度】
1-2: 重新获取浏览器宽高
window.onreset=function () {
NewW=window.innerWidth;
NewH=window.innerHeight;
}
1-3:重新设置浏览器大小
window.onresize=function(){
}
1-4:浏览器滚动事件
window.onscroll=function (){
}
2.浏览器左上角距离屏幕左上角的偏移量
window.screenTop [垂直偏移量]
window.screenLeft [水平偏移量]
注意:
因为window是核心,可以省略window不写
方法
alert() 弹出框
prompt() 输入框
confirm() 提示框,返回true或flase
close() 关闭页面
open(“url”) 打开页面(“打开的页面的路径【根据本html位置的相对路径】”)
open("url","","width=300,height=200");
setInterval(fn,毫秒数):隔毫秒数重复不断的执行一个函数fn
方法1
let t =setInterval(fn,3000)
function fn(){
}
方法2
setInterval(function(){
},1000)
clearInterval(t):清除setInterval的时间函数
let t =setInterval(fn,3000)
function fn(){
}
clearInterval(t)
setTimeout(fn,1000) 隔一定的时间只执行一次函数
cleanTimeout(t) 清除时间函数 【用法同上】
获取表单的值
对象.value=
清空=“”
history对象
属性:
history.length 用来显示历史记录的长度
方法
history.forward() 前进
history.back()后退
history.go(0) 刷新 【1 前进,-1后退;不常用】
location对象
属性:设计获取当前页面的地址
location.href=“ ” 设置或获取页面地址 设置新值
location.host:主机名+端口号
location.hostname:主机名
location.port:端口号
location.protocol:协议
location.pathname: 路径
location.search: ?后面的查询【搜索】字段
方法
location.reload( ) 重新加载
location.replace("网页.html") 页面替换,不会增加历史记录
location.assign(“网页.html”) 页面替换, 能够增加历史记录
DOM(文档对象模型)document object model
获取元素
获取body:document.body
获取html:document.documentElement
1. 获取id名的元素:
let 变量=document.getElementById("id名")
例子: let box=document.getElementById("id名")
2.获取class名的元素[得到的是集合,可以通过键名访问]
let 对象=document.getElementsByClassName(“class名”)
通过遍历改变样式
集合通过单个下表改变,不能全部用class名同时改变
3. 获取标签名的元素[得到的是集合,可以通过键名访问]
let 对象=document.getElementsByTagName(“标签名”)
4.给对象加类
标签加1个类名
对象.className=“类名”
div加多个类名
对象.className=“类名1 类名2 ”
5.指定范围的多层级获取【集合】
<div class="box">
<div class="box1">
<div class="box2"></div>
</div>
</div>
多楼层获取
let box=document.getElementClassName("box");
let box1=box.getElementClassName("box1");
let box2=box1.getElementClassName("box2")
6.获取选择器选中的元素
let liss=document.querySelector("【选择器】"); 获取选择器选中的第一个元素
let lis=document.querySelectorAll("【选择器】"); 获取选择器选中的全部元素【集合】【下标或者foreach遍历】
7.属性选择器
<textarea name="con" id="text" cols="30" rows="10"></textarea>
let con = document.querySelector("[name=con]")
操作样式
获取样式
获取行内样式
对象.style.样式名
获取通用的样式【css和行内】
getComputedStyle(对象,null).样式名
设置行内样式
对象.style.样式名=“样式值”
对象.style=“background:red;border-radius:50%”
批量操作类名
对象.className="class类名"
对象.className=“ ”;
对象.classList.add(“”) 添加类
对象.classList.remove(“”) 删除类
对象.classList.toggle(“”) 切换类
对象.id="id名"
外部定义一个样式,加到对象身上,参考第四点
操作属性
操作标准属性
已知的,系统自带
对象.属性
例子 : img.src
自定义属性
获取
对象.getAttrbutte("name")
设置
对象.setAttrbutte("name","value")
操作内容
innerText:不能识别html的标签对
innerHTML: 可以识别html的标签对
对象.innerText=“内容”
对象.innerHTML=“内容”
添加事件
对象.对象事件=function(){
}
元素的尺寸和位置
对象.offsetWidth:获取元素的真实宽度
对象.offsetHeight:获取元素的真实高度
对象.offsetTop:对象的上边框距离具有定位的父元素的内边框的垂直距离
对象.offsetLeft:对象的左边框距离具有定位的父元素的内边框的水平距离
对象.scrollTop:有滚动条的元素,浏览器滚动时在垂直方向的拉动距离
body的兼容
document.body.scrollTop || document.documentElement.scrollTop
对象.scrollLeft:有滚动条的元素,浏览器在滚动时在水平方向的拉动距离
动态创建标签
let div=document.createElement(“标签名”)
创建的元素放到也面中:
document.body.appendChild(div)
父元素.appendChild(子元素)
引入JS
1. 外部引入方式
<head>
<script src='路径'></script>
</head>
2. 内部引入方式(在html页面中放入srcipt标签,和body同级)
<script>
</script>
3. 放在事件后
<div onclick="alert(1)">文字等或事件</div>
注意:
~js的几种引入方式是相互关联的,可以相互操作与访问
~外部js中不能添加srcipt标签对
~嵌入式的js中不能添加src属性
引入js的执行
1. 将srcipt标签对放最最后
2.在.js文档中加入
window.onload=function(){
需要执行的js代码块
}
输出工具
弹出框:alter(' '); 数字可加可不加' ';
输出到控制台:console.log('输出到控制台');
输出到html页面中[可以识别html的标签对,即解释为html语言]:document.write('<h1>输出到html页面中 </h1>');
输入工具
弹出框输入:var num=prompt("提示文本",[默认值]);
提示工具
confirm("提示内容");
confirm返回值为true和false
注释
单行注释: ctrl+?或者/ //
块注释: ctrl+shift+/或者? /* 块 */
拼接
1. 用“+”拼接
2. 模板字符串(es6):
`<td>${i}-${j}</td>`; 拼接部分用``括起来,变量用 ${变量}
识别空格,换行等
变量
一个容器,存储数据
变量的声明:
var:
let:
let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在
let命令所在的代码块
内有效
1. 适用于for循环
2. 先声明,在使用
3. 不允许在相同作用域内重复声明同一个变量。
4. let可以识别块级作用域
5. 不存在变量提升(先访问后声明) 报错:没有定义
const
声明一个只读的常量。一旦声明,常量的值就不能改变。
声明常量的
同时
进行赋值,不赋值就会报错可以识别块级作用域
不能重复声明
不存在变量提升【先访问在声明】
PI;
命名规范:
数字。字母。下划线组成
不能以数字开头
区分大小写
不能以关键字(js中已经用到的)命名
不能以保留字(js中将来会用到的)命名
有意义
遵循的规则:首字母大写 (Array String Obiect) ;驼峰命名法 (getElementByld)
赋值
-
先声明再赋值
var num;
num=10; -
声明的同时赋值
var num=10;
-
一次性声明多个变量,再赋值
var a,b,c;
a=1,b=2;
c=3; -
一次性声明多个变量同时复制
var a=1,b=2,c=3;
注意事项:
变量要先声明再访问,变量的默认值是undefined
新值可以覆盖旧值
变量可以用var关键字重新声明
不用var关键字声明时必须给变量赋值,并且为全局变量,先访问后声明变量,值为undefined:js执行时先预解析(即识别var 和function声明的变量,不赋值),在解析,一句一句执行。
数据类型
根据在内存中的存储位置划分。基本数据类型存放在栈中,引用数据类型存放在堆中(指针存放在栈中,内容存放在堆中 )
基本数据类型
undefined
null 【空占位符】
-
string 【也是对象】
模板字符串 字符编码 ASCII utf-8 unicode【万国码】 gb2312
转义字符: \ \n[换行] \r \t[制表符] \' \ ""
let 对象=new String(“ ”);
编码
对象.charCodeAt(2) 返回第2个位置的字符编码
String.fromCharCode(字符编码) 解码
查找元素
对象.charAt(0) 字符串的第0个位置的元素【查找字符】
查找下标
对象.indexOf(“ ”) 查找对应字符的下标,如果有返回下标,如果没有,返回-1【第一个字符开始的下标】
对象.lastIndexOf(“”) 倒着看查找,倒序看如果有返回下标,如果没有,返回-1【第一个字符开始的下标】
对象.search(“”) 正则:有返回0;没有返回-1;
对象.match(“”) 有的话,返回数组【返回值,下标,包含返回值的数组,】
没有 返回null
字符串的截取:【返回新值,不改变原内容】
对象.substr(开始下标,【截取的长度】)
对象.substring(开始下标,结束的下标),从开始下标开始到结束下标之前,不取到结束的下标
对象.slice(开始下标,结束的下标),从开始下标开始到结束下标之前,不取到结束的下标【数组的方法】
字符串大小写【转换】
let str="AbCdEf";
str.toLowerCase() 转换为小写
str.toUpperCase() 转换为大写
替换:
str.replace(“山”,“闪”);
转换【字符串转换数组】
let str=“1,2,3,4,5,6”;
arr2=str.split(“,”); boolean
-
number 2e3=2*10^3
二进制: 0b开头
八进制:以0o{0+字母o}开头,后跟0-7的数
十六进制:以0x开头,后跟0-9或者a-f
NaN:not a number 本来期望返回数值的操作,但并未返回数值的操作
引用数据类型
object(属性与方法的集合)数组,函数,对象
-
深拷贝
let arr=【1,2,3,4】
let arr1;
arr1=arr; :传址
arr1 和 arr具有相同地址 -
浅拷贝:
let arr=【1,2,3,4】
let arr1=【】
arr.foreach(function(value){
arr1.push(value)
})
判断变量的数据类型 ,其结果为字符串
typeof用法:
var num="5555";
typeof num;
数据类型 | 值 | 情况 | typeof 的结果【看返回0 1代码的前三位】 |
---|---|---|---|
undefined | undefined | undefined | |
null | null(空占位符) | object | |
boolean 布尔型 | true false | boolean | |
string 字符串型 | 带" "或者' ' | string | |
number 数值型 | 整数,小数,八进制,十六进制,十进制 | ||
object |
运算符
表达式:能够求值的语句
算术运算符
+ - * / % ++var var++ --var var --
+的特殊性
计算:操作对象是数值型
拼接:操作对象含有字符串,字符串中进行运算时,用()括起来
自增与自减
++var: ++在前,先算++,在执行本行的其他语句
var++:++在后,先执行本行的其他语句,在算++
关系运算符
返回值为布尔值 ,即true或者false
> < >= <= ==[等于] ===[全等于]--> 数值和数据类型相同 !=[不等于] !==[不全等]
如果比较的两个对象都是字符串[数字型,字符],按照ASCII表对应的ASCII码比较,逐位相比
如果比较的两个对象都是数值,直接比大小
如果一个操作对象是字符串,另一个是操作对象是数值,先尝试将字符串转换为数字,如果转换成功,按照数字比较大小;如果转换不成,则返回false
1==true; 0==false ; ==数值相同
=== 数值和数据类型相同
undefined=null
赋值运算符
= +=[num+=10 等价于 num=num+10] -= *= /= %=
逻辑运算符[与或非]
测量值与变量之间的逻辑关系
假:0、false undefined null NaN “ ”【空字符串】
真:其余为真
&&与
||或
-
!非【用来取反】
A B A && B A || B !A true true true true false true false false true false false true false true true false false false false true
返回值:
第一步:先看与或非两边的真假
第二步:在看返回的真假的内容
&& 同真为真,返回第一个假值 【遵循短路原则:看到假值,后边的不看了】;全为真,返回最后一个真值
|| 同假为假,返回第一个真值 【遵循短路原则:看到真值,后边的不看了】;全为假,返回最后一个假值
! 取反;返回值只有ture或false
运算符的优先级
算术>关系运算符>逻辑运算符
三元运算符:
表达式?为真的执行语句:为假的执行语句 【类似if else】
一元运算符: typeof + - new
特殊运算符: () .
流程控制
代码按照指定条件的执行顺序
顺序结构
分支结构
循环结构
顺序结构
语句按照从上到下的顺序进行执行
循环结构
当满足条件时,重复不断的执行一段代码
for循环:明确知道次数
for(初始条件;终止条件;步进值){
}
swith循环
switch(表达式【能够求值的语句】){
case 值1【表达式能取到的值】:语句1;break;
case 值2【表达式能取到的值】:语句2;break;
...
default: 语句;
}
while循环
while(条件){
满足条件时,执行语句;
}
例子:
var j=0;
while(j<5){
console.log(1);
j++;
}
do while循环
执行顺序先执行循环体,在执行判断语句
do{
循环体;
}while(条件)
例子:
var i=0;
do{
console.log(1);
i++;
}(i<5)
循环结束
continue
满足条件终止本次循环
break
满足条件,终止整个循环
分支结构
当条件成立时执行相应的语句
-
单分支结构
if条件:
if(表达式){
为真的执行语句【返回值为true执行的语句】
} -
双分支
if条件:
if(表达式){
为真的执行语句
}
else{
为假的执行语句
} -
多分支
if条件:
if(表达式1){
表达式1成立时执行语句
}
else if(表达式2){
表达式1不成立 但 表达式2成立时执行语句
}
else if(表达式3){
表达式1不成立且表达式2不成立【但】表达式3成立时执行语句
}
else{
以上表达式都不成立时执行的语句
} -
嵌套分支
if(){
if(){
}
else{
}
}
else{
}
数学方法
取随机数
Math.random() ; (0-1)
取整
向下取整【向左取整】: rgb=Math.floor(Math.random());
向上取整【向右取整】: rgb=Math.ceil(Math.random());
次幂[x的y次幂]
Math.pow(x,y)
一维数组
按照顺序排列的一组相关数据。
特点:每一个数组元素都有一个特定的键名(即俗称的下标)[字符串类型]
数组元素的默认值时undefined
数组的声明[初始化数组]
-
先声明后赋值
var arr=[];
arr[0]=89,arr[0]="adc",....; -
声明的同时赋值
var arr=[90,89,88,76,56];
数组下标的范围
访问数组元素,范围【0,n-1】
数组的长度
数组名.length; 例子: arr.length
注意:
数组的长度可变
arr=[90,89,88,76,56];
可以随时添加元素,可跳着添加。如:
arr[6]="aaa";
数组元素可以时任意的数据类型
arr=[true,null,{name:},[1,2,3]]
遍历数组元素
访问数组的每一个元素
1. 用for循环遍历数组
for(var i=0;i<arr.length;i++){
arr.[i]; 即可访问arr的每个元素
}
2. 用for in循环遍历数组
for(var i in arr){
i; //代表arr的键名(下标)
arr[i]; //元素
}
3.for of遍历元素
for(item of arr1){
arr2.push(item)
}
4.foreach遍历数组
用法:
arr.forEach(function (value,index){
})
value[名字随便起]:数组中的当前元素【必须有】
index[名字随便起]:数组当前元素的下标【键名】【可选】
清空数组
arr.length=0
二维数组
声明:
var arr=[[1,2.3],["a","b"],[78,89];
访问:
arr[行][列]
遍历
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr[i].length;j++){
arr[i][j]
}
}
数组身上的方法
向数组的后面插入一个或多个元素(.push)
arr.push(需要插入的内容);
删除数组最后一位:.pop
arr.pop()
在数组之前插入: .unshift
arr.unshift("")
在数组之前删除一位:.shift
arr.shift()
万能的插入和删除:.splice()
arr.splice(开始的位置,长度,“再删除的位置加入的元素1”,“再删除的位置加入的元素2”,...);
不想删除,让其长度为0;
可以返回删除的值:arr.splice()
是否包含某个元素: .includes
arr.includes(“被包含的内容”);
截取元素: .slice
arr.slice(2,5):截取第2位开始的。第5位之前的
连接多个数组:.concat
arr.concat([数组1],[数组2])
数组的取反:.reverse
arr.reverse()
把数组转换为字符串: .join
arr.join(“连接符(-/,/;/..)”)
排序:.sort
arr.sort((x,y)=> x-y); 升序
arr.sort((x,y)=> y-x); 降序
arr.sort(function(x,y){
return x-y
})
查找: .find()
arr.find(item=>item>7) 找到第一个比7大的数
arr.find(item=>item%2==0) 找第一个偶数
arr.find(function(item){
return item%2==0;
})
查找第一个符合条件的下标: .findIndex()
let index= arr.findIndex(function(item){
return item > top //返回布尔值,为真时返回下标
})
返回符合条件的真假值:.some()
arr.some(item=>item>8);
返回每一个符合条件的元素:.every()
arr.every(item=>item<10);
筛选符合条件的:.filter()
arr.filter(item=>item%2==0); 返回新数组
遍历数组(.forEach)
arr.forEach
用法:
arr.forEach(function (value,index){
})
value[名字随便起]:数组中的当前元素【必须有】
index[名字随便起]:数组当前元素的下标【键名】【可选】
处理每个元素:.map
arr.map(item=>{return item*10}) //让数组中的每个元素都执行一个函数,返回一个新数组
全部方法
concat() | 连接两个或更多的数组,并返回结果。 |
---|---|
copyWithin() | 从数组的指定位置拷贝元素到数组的另一个指定位置中。 |
every() | 检测数值元素的每个元素是否都符合条件。 |
fill() | 使用一个固定值来填充数组。 |
filter() | 检测数值元素,并返回符合条件所有元素的数组。 |
find() | 返回符合传入测试(函数)条件的数组元素。 |
findIndex() | 返回符合传入测试(函数)条件的数组元素索引。 |
forEach() | 数组每个元素都执行一次回调函数。 |
indexOf() | 搜索数组中的元素,并返回它所在的位置。 |
join() | 把数组的所有元素放入一个字符串。 |
lastIndexOf() | 返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。 |
map() | 通过指定函数处理数组的每个元素,并返回处理后的数组。 |
pop() | 删除数组的最后一个元素并返回删除的元素。 |
push() | 向数组的末尾添加一个或更多元素,并返回新的长度。 |
reduce() | 将数组元素计算为一个值(从左到右)。 |
reduceRight() | 将数组元素计算为一个值(从右到左)。 |
reverse() | 反转数组的元素顺序。 |
shift() | 删除并返回数组的第一个元素。 |
slice() | 选取数组的的一部分,并返回一个新数组。 |
some() | 检测数组元素中是否有元素符合指定条件。 |
sort() | 对数组的元素进行排序。 |
splice() | 从数组中添加或删除元素。 |
toString() | 把数组转换为字符串,并返回结果。 |
unshift() | 向数组的开头添加一个或更多元素,并返回新的长度。 |
valueOf() | 返回数组对象的原始值。 |
函数
把实现某一特定功能的代码块封装起来,并能够重复调用
定义函数
1. 基本语法(function关键字)【调用可以在声明前,也可以在声明后】
function 函数名(形参1,形参2,....){
函数体;
return 返回值;【可有可无】 《并不向用户显示,仅是调用的数的值》
}
2. 字面量,自变量【必须先声明在调用】【预解析】
var 变量=function (参数){
函数体;
}
调用 变量()
3. 对象的方式【实例化对象】
let aa=new Function(“a”,“b”,“alter(a+b)”)
调用 aa(10,20)
匿名函数定义与调用
(function (){
})()
定义:(function (){
}
调用【一般在定义的时候就调用】:
(function (){
})()
箭头函数
定义:
let aa=()=>console.log(123);
let aa=(参数)=>{
多行函数体;
}
调用:
aa(实参)
函数的调用
1. 函数名(实参1,实参2,….)
2. 自变量()
3.自变量(参数1,参数2)
参数
能够动态改变函数体的变量,使函数更加灵活
形参:
定义函数使写在括号里的量。其作用为接收实参
形参默认值的传递
1. if else分支结构
if(flag==undefined){ }
else{
}
2. 三元运算符【用的多】
flag=flag==underfined?"<":flag
3. 逻辑或||返回第一个真值【用的多】
flag=flag||"<"
4. 定义形参的时候直接赋值:当形参为undefined时给形参默认值
flag=25555;
实参:
函数调用时写在括号中的值。其作用为给形参传值
全部的实参由arguments接收
参数传递
参数可以是任意的数据类型
参数的传递按顺序传递:从左到右
形参=实参 :一一对应的传递
形参>实参:多余的形参赋值为undefined
形参<实参:实参由
arguments
对象来接收
剩余参数
声明: ...rest【为数组】
function 函数名(形参1,...rest){
函数体;
}
rest和arguments对象的区别
1. rest接收多余的参数,arguments接收全部的实参
2. rest是数组,能够使用数组的方法,键名从0开始;
arguments对象类似数组,不能使用数组的方法
函数的返回值:return
return 终止函数。遇到return,后面都不执行
返回值可以是任意的数据类型
一个函数内部可以有多条return分支语句,但最终只执行一条return语句
只能返回一个值
回调函数
把一个函数的指针(函数名)作为参数传递给另一个函数,当指针调用函数时,这个函数叫做回调函数【高阶函数】:形参高阶函数和 返回值高阶函数
指针类型
function math(num1,num2,callback) {
return callback(num1,num2);
}
function add(num1,num2) {
return num1+num2;
}
function sub(num1,num2) {
return num1-num2;
}
function mult(num1,num2) {
return num1*num2;
}
function div(num1,num2) {
return num1/num2;
}
document.write(math(1,2,div));
函数类型
foreach
arguments对象
用来接收参数的详细信息
每声明一个函数,在其内部自动生成arguments对象
arguments对象只在函数内部起作用
不是数组类似数组,可以用键名遍历数组(arguments[i]),其长度为arguments.length
不能用数组身上的方法
闭包函数
内部的函数调用外部的函数的【变量】;
function fn1(){
let a="456";
function fn2(){
console.log(a)
}
return fn2;
}
let fn2=fn1();
fn2()
// js中没有函数的重载:传的参数不同,执行不同的函数
作用域
变量起作用的范围
局部作用域优先于全局作用域[作用域链]
-
全局作用域
1. 在整个js中都能访问的变量,凡是进行修改,变量的值就会改变
2. 类型【情况】
在函数外部用var声明的变量,即拥有全局作用域
不用var声明,但是赋值的变量就是全局变量,即拥有全局作用域; -
局部作用域
类型【情况】
形参是局部变量,即拥有局部作用域
在函数内部用var关键字声明的变量,也是局部变量,即拥有局部的作用域。 -
块级作用域
{
括起来的就是块级作用域;
}
内置顶层函数
内置:ECMAscript自带的函数,本身就有;只要求知道如何让使用,不用关心如何封装
顶层:在js代码中的任何位置都可以使用;
escape():将传进来的字符串进行编码
escape("编码的内容"); 编码内容一般为中文
unescape():对编码的字符串进行解码
unescape("字符串的编码")
Boolean():将其余数据类型转换为布尔型
String():将任意数据类型转换为字符串型
Number():将其余数据类型转换为数值型
情况
1. null:0 “”:0 “ ”:0
2. false:0 true:1
3. undefined:NaN
4. 进制数转换为十进制
5. 去掉没有意义的后导0和前导0
6. 字符串: 规范的浮点数,数值型字符串
parseInt():将字符串转换为整数
第一个位置为字母 (+、-)号 空格
转换不成功,转换为NaN
parseFloat():将字符串转换为小数
只能转换规范的浮点数
转换不成功,返回NaN
isNaN():值是否够转换为数值型
能转换为数值型返回false
不能转换为数值型返回true
作用:数据类型转换
强制类型转换
隐式数据类型转换:算数运算符,逻辑运算符,条件语句(if,while等)
对象 类
概念
类:一群具有相同特征的对象集合的描述
对象:具体存在的类个体
属性:对象基础信息的描述
方法:对象功能的描述
定义对象
构造函数(类),实例化对象
1. 构造类
function 类名(color,price等其他形参){
this.color=color;
this.price=price; //实例化时,this指向实例化的对象
this.play=function(){
}
}
2. 实例化对象
let 对象=new 类名(实参);
3. 对象的属性【对象属性的添加】
对象.属性名=“属性值”; 访问:对象.属性名 / 对象【‘属性名’】
4. 对象的方法【对象方法的添加】【方法是特殊的属性】
对象.方法名=function(){}; 访问:对象.方法名()
5. 遍历【i代表的是属性名】
for(let i in 对象){
i;//属性名,方法
对象【i】;//属性值
}
6. 对象属性的增删改查:
增加: 对象.属性名=“属性值”;
删除: delete 对象.属性名
修改: 对象.属性名=“属性值”
查讯: 对象.属性名 ; 对象【‘属性名’】
JSON [注意格式] 【可直接定义对象】
1.定义
let 对象={
属性名:属性值, //属性名可以加引号,也可以不加引号
属性名:属性值,
方法名:function(){
},
方法名:function(){
}
}
2.增删改查
增加: 对象.属性名=“属性值”;
删除: delete 对象.属性名
修改: 对象.属性名=“属性值”
查找: 对象.属性名 ; 对象【‘属性名’】
3.遍历
for(let i in 对象){
i;//属性名,方法
对象【i】;//属性值
}
4.对象.constructor 返回 object
class定义类,实例化对象
重要的关键字[方法]
constructor: 返回该对象的构造函数
使用: 对象.constructor
instanceof:判断函数是否为对象的构造函数?true:false;
使用 : 对象 instanceof 构造函数
原型,原型链
最大的类:object:[prototype proto]
生成人类:person:【proto prototype】 proto继承父类的prototype
生成对象:xb【proto,prototype】 proto继承人类的prototype
sing改变函数的指针
sing.call(xb,10,20)
sing.apply(sb,【10,20】)
sing.
将小白的say方法传给小红
say=xh.say
say.call(xh)
递归
函数自己调用自己,必须有一个 出口
function fn(num){
if(num==0){
return 1;
}
else{
return num*fn(num-1)
}
}
function fnn(arr){
let arr1=[]
for(let i=0;i<arr.length;i++){
if(typeof arr[i]=="object"){
arr1.push(fnn(arr[i]))
}
else{
arr1.push(arr[i])
}
}
return arr1;
}
console.log(fnn([0,[1,2],[2,3]]))
节点:
整个文档 元素【标签】 属性 文本 注释【节点】
文档的节点
document.nodeName #document
document.nodeValue null
document.nodeType 9
元素的节点
let box=documentquerySelector("box")
box.nodeName 大写的标签名
box.nodeValue null
box.nodeType 1
节点 | nodeName(名字) | nodeValue(值) | nodeType(节点类型) |
---|---|---|---|
文档节点 | #document | null | 9 |
元素节点 | 大写的标签名 | null | 1 |
属性节点 | 大写的属性名 | 属性值 | 2 |
文本节点 | #text | 文本 | 3 |
注释节点 | #comment | 注释内容 | 8 |
节点的获取
1.childNodes:子节点
document.childNodes[1].childNodes
2.parendNode:父节点
let box=document.querySelector("box") ;
3.上一个兄弟节点:previousSibling
box.previousSibling
3.下一个兄弟节点:nextSibling
box.nextSibling
4.上一个兄弟元素节点:previousElementSibling
box.previousElementSibling
5.下一个兄弟元素节点:nextElementSibling
box.nextElementSibling
节点的方法
创建元素节点
let div=document.createElement("div")
在最后插入节点
let box=document.querySelector(“.box”);
box.appendChild(div)
在之前插入节点.insertBefore(要插入的元素,插入位置之后的元素)
let span=document.querySelector("span")
box.insertBefore(span,div)
创建文本节点
let text=document.createTextNode("必须有参数")
text.nodeValue=“这是span标签”
span.appendChild(text)
创建注释节点
let comment1=document.createComment(“这是注释节点”);
box.appendChild(comment1);
创建属性节点
let attr=document.createAttribute("id");
添加/设置属性节点
.setAttribute("name","value");//添加属性
box.setAttributeNode(attr)
添加:append 删除:remove
删除标签节点 : box.removeChild(div)
删除属性节点: box.removeChild(“属性名”)
DOM(文档对象模型)document object model
获取元素
获取body:document.body
获取html:document.documentElement
Dom对象
1. 获取id名的元素:
let 变量=document.getElementById("id名")
例子: let box=document.getElementById("id名")
2.获取class名的元素[得到的是集合,可以通过键名访问]
let 对象=document.getElementsByClassName(“class名”)
通过遍历改变样式
集合通过单个下表改变,不能全部用class名同时改变
3. 获取标签名的元素[得到的是集合,可以通过键名访问]
let 对象=document.getElementsByTagName(“标签名”)
4.给对象加类
标签加1个类名
对象.className=“类名”
div加多个类名
对象.className=“类名1 类名2 ”
5.指定范围的多层级获取【集合】
<div class="box">
<div class="box1">
<div class="box2"></div>
</div>
</div>
多楼层获取
let box=document.getElementClassName("box");
let box1=box.getElementClassName("box1");
let box2=box1.getElementClassName("box2")
6.获取选择器选中的元素
let liss=document.querySelector("【选择器】"); 获取选择器选中的第一个元素
let lis=document.querySelectorAll("【选择器】"); 获取选择器选中的全部元素【集合】【下标或者foreach遍历】
7.属性选择器
<textarea name="con" id="text" cols="30" rows="10"></textarea>
let con = document.querySelector("[name=con]")
操作样式
获取样式
获取行内样式
对象.style.样式名
获取通用的样式【css和行内】
getComputedStyle(对象,null).样式名
设置行内样式
对象.style.样式名=“样式值”
对象.style=“background:red;border-radius:50%”
批量操作类名
对象.className="class类名"
对象.className=“ ”;
对象.classList.add(“”) 添加类
对象.classList.remove(“”) 删除类
对象.classList.toggle(“”) 切换类
对象.id="id名"
外部定义一个样式,加到对象身上,参考第四点
操作属性
操作标准属性
已知的,系统自带
对象.属性
例子 : img.src
自定义属性
获取
对象.getAttrbutte("name")
设置
对象.setAttrbutte("name","value")
操作内容
innerText:不能识别html的标签对
innerHTML: 可以识别html的标签对
对象.innerText=“内容”
对象.innerHTML=“内容”
添加事件
对象.对象事件=function(){
}
元素的尺寸和位置
对象.offsetWidth:获取元素的真实宽度
对象.offsetHeight:获取元素的真实高度
对象.offsetTop:对象的上边框距离具有定位的父元素的内边框的垂直距离
对象.offsetLeft:对象的左边框距离具有定位的父元素的内边框的水平距离
对象.scrollTop:有滚动条的元素,浏览器滚动时在垂直方向的拉动距离
body的兼容
document.body.scrollTop || document.documentElement.scrollTop
对象.scrollLeft:有滚动条的元素,浏览器在滚动时在水平方向的拉动距离
动态创建标签
let div=document.createElement(“标签名”)
创建的元素放到也面中:
document.body.appendChild(div)
父元素.appendChild(子元素)
BOM: 浏览器对象模型
完成窗口与窗口之间的通信,window对象是其核心对象,
history【前进,后退,刷新】 是一个对象 使用【window.history】
location【地址】
DOM【】
screen【屏幕】
frames[真窗口]
navigation
window对象:
属性
1-1:获取浏览器宽高
a.ie8及以上
window.innerWidth [获取浏览器宽度]
window.innerHeight [获取浏览器高度]
b.ie8以下
document.documentElement.ClientWidth [宽度]
document.documentElement.ClientHeight 【高度】
1-2: 重新获取浏览器宽高
window.onreset=function () {
NewW=window.innerWidth;
NewH=window.innerHeight;
}
1-3:重新设置浏览器大小
window.onresize=function(){ }
1-4:浏览器滚动事件
window.onscroll=function (){ }
2.浏览器左上角距离屏幕左上角的偏移量
window.screenTop [垂直偏移量]
window.screenLeft [水平偏移量]
注意:
因为window是核心,可以省略window不写
方法
alert() 弹出框
prompt() 输入框
confirm() 提示框,返回true或flase
close() 关闭页面
open(“url”) 打开页面(“打开的页面的路径【根据本html位置的相对路径】”)
open("url","","width=300,height=200");
setInterval(fn,毫秒数):隔毫秒数重复不断的执行一个函数fn
方法1
let t =setInterval(fn,3000)
function fn(){
}
方法2
setInterval(function(){
},1000)
clearInterval(t):清除setInterval的时间函数
let t =setInterval(fn,3000)
function fn(){
}
clearInterval(t)
setTimeout(fn,1000) 隔一定的时间只执行一次函数
cleanTimeout(t) 清除时间函数 【用法同上】
获取表单的值
对象.value=
清空=“”
history对象
属性:
history.length 用来显示历史记录的长度
方法
history.forward() 前进
history.back()后退
history.go(0) 刷新 【1 前进,-1后退;不常用】
location对象
属性:设计获取当前页面的地址
location.href=“ ” 设置或获取页面地址 设置新值
location.host:主机名+端口号
location.hostname:主机名
location.port:端口号
location.protocol:协议
location.pathname: 路径
location.search: ?后面的查询【搜索】字段
方法
location.reload( ) 重新加载
location.replace("网页.html") 页面替换,不会增加历史记录
location.assign(“网页.html”) 页面替换, 能够增加历史记录
事件
事件的添加方式
节点.onclick=function(e){
}
只能添加一个
节点.addEventListener("事件【click】",事件处理程序,事件类型【布尔值】【可以不给】)
可以添加多个事件
将事件加在元素身上, 在js中定义事件的函数
<body>
<div class="son" onclick="事件函数()"></div>
</body>
<script>
function 事件函数(){
函数体
}
</script>
事件的构成
事件源:谁去触发事件谁就是事件源
事件:鼠标事件/键盘事件
事件处理程序:
常用的web端事件
onclick:单击
ondblclick:双击
onmousedown:按下
onmouseup:抬起
onmousemove:鼠标移动
onmouseover:移入
onmouseout:移出
onmouseenter:移入
onmouseleave:移出
oncontextmenu:右击事件【默认事件】
对象.oncontextmenu=function(e){
e.preventDefault() //阻止浏览器默认右击行为
}
onmousewheel 滚轮滚动事件
移动端事件
ontouchstart:按下
ontouchmove:移动
ontouchend:抬起
事件对象:
用来保存事件触发时的信息
w3c : 在事件处理程序的形参中
ie : 在window.event中
解决兼容性:let event=e || window.event
鼠标事件对象常用的属性:
clientX : 距离浏览器 X轴 的偏移量 【client设备】
clientY:距离浏览器 Y 轴 的偏移量
从 浏览器的 哪个位置进来
offsetX:距离事件源 X轴 的偏移量
offsetY:距离事件源 Y轴 的偏移量
从 事件源的 哪个位置进来
screenX:距离屏幕 X轴 的偏移量
screenY:距离屏幕 Y轴 的偏移量
从 屏幕的 哪个位置进来
键盘事件
onkeydown 键盘按下
onkeyup 键盘抬起
onkeypress键盘按下:按下功能键ctrl shift alt delete esc等不会触发
键盘事件对象常用的属性
keyCode:键盘码
ctrlKey:是否按下了ctrl
shiftKey:是否按下了shift
altKey:是否按下了alt
key:键名
表单事件
oninput:输入事件
onchange:内容发生改变,并且失去焦点
onblur:失去焦点
onfocus:获得焦点
onsubmit:提交表单
onselect:文本选中
窗口事件
onscroll:滚动事件
onload:加载
onresize:重新获取浏览器大小
事件流
当触发一个事件时,由这个事件的容器到整个文档都会按照特定的顺序依次进行触发
顺序:子元素 -》 父元素 【具体的到不具体的】
事件分类
捕获型事件:true【大到小,不具体的事件源到具体的事件源】
冒泡型事件:false【小到大,具体的事件源到不具体的事件源】
浏览器执行事件的顺序:doc的捕获 html的捕获 body的捕获 具体元素的捕获 具体元素的冒泡 body的冒 泡html的冒泡 doc的冒泡
阻止事件流
w3c浏览器
box.addeventListener(“click”,function(event){
let event=event|| window.event
event.stopPropagation()
},false)
ie浏览器
box.addeventListener(“click”,function(event){
let event=event|| window.event
event.stopPropagation()
event.returnValue=true;
},false)
事件委派
event.target:目标事件源【记录】获取到的是元素/属性:类型:节点;点谁获取到谁
event.target.className 事件源的类名
正则
定义
用来描述或者匹配一系列符合某种规则的字符串,规则可以自己定义
作用
数据验证
内容检索
内容替换
内容过滤
正则对象
创建正则对象
实例化对象
let reg = new RegExp("正则表达式[即规则]","模式修正符")
必须传入字符串
自变量,字面量
let reg=/正则表达式/模式修正符 ; (//代表定界符)
正则对象常用的方法
test(str) 检测正则对象是否能够匹配str , 返回值 true || false
exec( str ) 检测正则对象是否能够匹配str,如果能够匹配,返回一个拥有特殊属性的数组,如果不能匹配,返回null
let reg = new RegExp("uek","gi");
let bool=reg.test("www.sxuek.com"); //bool=true
正则表达式
原子
原子:正则表达式最小的内容【只能匹配一位】
\d 匹配 0-9 ;
\D 匹配:除了0-9意外的字符
\w 匹配:数字、字母、下划线
\W 匹配:除了数字字母下划线以外的字符
\s 匹配:空白 \n换行 \r回车 \t 制表符
\S 匹配:除了空白以外的字符
\b 单词的边界
\B 非单词边界
let str=“abc1”
let reg=/\w/g;
reg.test(str)
原子表【只匹配一个】
定义: [ ]
匹配a-c
let str=“abcdef1”
let reg=/[a-c]/g;
reg.test(str)
匹配 [a-z] 匹配a-z
匹配 [a-zA-Z] 匹配a-z和A-Z
匹配 [a-zA-Z0-9] 匹配a-z和A-Z和0-9
匹配 [a-zA-Z\s] 匹配a-z和A-Z和空格
元字符
. 代表所有的字符
| 或者
原子组
相当于变量默认保存在内存中;可以使用\1 \2等方式依次引用()中的内容
(?: )可以使原子组不在内存中存储,不可以调用
let str1="山西优逸客"
let str2="陕西优逸客"
let reg=/(山西|陕西)优逸客/g;
reg.exec(str1)
let str="<div>hello</div>"
let reg=/<(div)>hello<\/\1>/g
reg.exec(str);
let str="<div>div</div>" //没有变量名
let reg=/<(div)>\1<\/\1>/g
reg.exec(str);
let str="<div>山西优逸客-山西</div>"
let reg=/<(div)>(山西|陕西)优逸客-\2<\/\1>/g
let reg=/<(div)>(?:山西|陕西)优逸客-\2<\/\1>/g \2不会被引用
数量[手机号/身份证号]
* 0个或者多个 》=0 贪婪
let phone="18335219360";
let reg=/\d*/g
reg.exec(phone)
+ 1个或者多个 》=1
? 0个或者一个 吝啬
{11}限制长度为11
{15,18} 长度为 15-18
{6,} 长度为6以及以上
贪婪吝啬 +? 变成吝啬
*?
+?
{11,}?
{11,20}?
边界判断【限制长度】
^ 以...开始
$ 以...结束
let reg=/^(0351)-\d{7}$/
let str1="hello word"
let reg=/o\b/
模式修正符
可以搭配使用 gi mi mg 先后顺序执行
g 全局 global
记录下标,下一个下标位置开始
i 不区分大小写
m 可以换行
正则的使用场所
正则对象
-
str对象 中的 str.split(正则对象) 拆分
let str="山西有一棵:1,2.3"
str.split(/[: , .]/) -
str对象 中的 str.replace(正则对象) 替换
let str="山西有课山西有了"
str.replace(/(山西)/g,陕西) -
str对象 中的 str.search(正则对象) 查找
let str="山西有课山西有了"
str.search(/(山西|有一颗)/)
常用的正则
用户名 /^[a-z0-9_-]{3,16}$/
密码 /^[a-z0-9_-]{6,18}$/
十六进制值 /^#?([a-f0-9]{6}|[a-f0-9]{3})$/
电子邮箱 /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/
/^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/
URL /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/
IP 地址 /((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
HTML 标签 /^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/
删除代码\\注释 (?<!http:|\S)//.*$
Unicode编码中的汉字范围 /^[\u2E80-\u9FFF]+$/
日期对象/函数
自定义时间
let ay=new Date("2018/8/8 12:00:00")
let ay1=new Date("12:00:00 2018/8/8")
let ay2=new Date("2018,0,8") //月份从0开始
获取当前格林尼治时间
let now=new Date() //获取当前格林尼治时间
now.setFullYear(2020) 设置年份
now.setMonth(5) 6月份
now.setDate(26) 26号
now.setHours(12) 12时
now.setMinutes(0) 分
now.setSeconds(0) 秒
now.setMilliseconds(0) 毫秒
获取世界协调时间【用法同上】
now.setUTCFullYear()
now.setUTCMonth()
now.setUTCDate()
now.setUTCHours(12) 12时
now.setUTCMinutes(0) 分
now.setUTCSeconds(0) 秒
now.setUTCMilliseconds(0) 毫秒
//获取时间
now.getFullYear() //now.getUTCFullYear()
now.getMonth()+1
now.getDate()
now.getDay() 星期
now.getHours()
now.getMinutes()
now.getSeconds()
now.getMilliseconds(0)
//获取毫秒数
now.getTime() 1970.1.1.0的毫秒数
时间案例
倒计时
jishi()
setInterval(jishi,2000);
function jishi(){
let arr=daoJiShi();
span9.forEach(function (value,index) {
value.innerText=arr[index];
})
}
function daoJiShi() {
let arr=[];
let now=new Date();
let future=new Date(2018,6,26,18);
let times=future.getTime(); //未来的毫秒数
let time=now.getTime();//现在的毫秒数
let juXianZai=Math.floor((times-time)/1000); //2018.9.1到现在时间的秒数
let Month=Math.floor(juXianZai/(30*24*60*60));
arr.push(Month);
juXianZai=juXianZai%(30*24*60*60);
let Day=Math.floor(juXianZai/(24*60*60));
arr.push(Day);
juXianZai=juXianZai%(24*60*60);
let shi=Math.floor(juXianZai/(60*60));
if(shi>0 & shi<9){
shi="0"+shi;
}
arr.push(shi);
juXianZai=juXianZai%(60*60);
let fen=Math.floor(juXianZai/(60));
if(fen>0 & fen<9){
fen ="0"+fen;
}
arr.push(fen);
let miao=Math.floor(juXianZai%60);
if(miao>0 & miao<9){
miao="0"+miao;
}
arr.push(miao);
return arr;
}
}
轮播图
双下标
window.onload=function () {
let Box1=document.querySelectorAll("div.box .box1"); //5个小盒子盒子
let box=document.querySelector("div.box"); //大盒子
let Width=parseInt(getComputedStyle(box,null).width); //小盒子的宽度
let Left=document.querySelector("div.box .left"); //左右两个盒子
let Right=document.querySelector("div.box .right");
let circle=document.querySelector("div.box .circle"); //小圆圈
let Son=document.querySelectorAll("div.box .circle .son");//小点
console.log(Box1,Width,Left,Right,Son);
let now=0;
let next=0;
flag=true;
let t=setInterval(move2,2000);
//右向左
function move2() {
next++;
if(next==Box1.length){
next=0;
}
// 就绪
Son[next].classList.add("son1");
Son[now].classList.remove("son1");
Box1[next].style.left=Width+"px";
//动画
animate(Box1[next],{left:0});
animate(Box1[now],{left:-Width},function () {
flag=true;
});
now=next;
}
//左向右
function move3() {
next--;
if(next<0){
next=Box1.length-1;
}
//就绪
Box1[next].style.left=-Width+"px";
Son[next].classList.add("son1");
Son[now].classList.remove("son1");
//动画
animate(Box1[next],{left:0});
animate(Box1[now],{left:Width},function () {
flag=true;
});
now=next;
}
box.onmouseenter=function () {
clearInterval(t);
}
box.onmouseleave=function () {
t=setInterval(move2,2000)
}
Left.onclick=function () {
if(flag==false){
return;
}
if(next==0){
return;
}
flag=false;
move3();
}
Right.onclick=function () {
if(flag==false){
return;
}
if(next==Box1.length-1){
return;
}
flag=false;
move2();
}
Son.forEach(function(value,index){
value.onclick=function(){
if(index==now){
return;
}
else if(index>now){
Son[index].classList.add("son1");
Son[now].classList.remove("son1");
//就绪
Box1[now].style.left=-Width+"px";
Box1[index].style.left=0;
}
else if(index<now){
Son[index].classList.add("son1");
Son[now].classList.remove("son1");
//就绪
Box1[now].style.left=Width+"px";
Box1[index].style.left=0+"px";
}
now=next=index;
}
})
}
单下标
tupian下包含 a a下包含img
tupian x y 同级
let tupian = daohang.getElementsByClassName("tupian")[0];
let a1 = tupian.getElementsByTagName("a");
let img = tupian.getElementsByTagName("img");
let z = daohang.getElementsByClassName("z")[0];
let y = daohang.getElementsByClassName("y")[0];
let x = daohang.getElementsByClassName("x")[0];
let Son = x.getElementsByClassName("son");
num = 0;
let t = setInterval(move, 2000);
function move() {
num++;
if (num == img.length) {
num = 0;
}
for (let i = 0; i < img.length; i++) {
a1[i].style.zIndex = 20;
Son[i].className = "son";
}
Son[num].className = "son son1";
a1[num].style.zIndex = "30"
}
img.onmouseenter = function () {
clearInterval(t)
}
img.onmouseleave = function () {
t = setInterval(move, 2000)
}
tupian.onmouseenter = function () {
clearInterval(t);
}
tupian.onmouseleave = function () {
t = setInterval(move, 2000);
}
z.onclick = function () {
a1[num].style.zIndex = 20;
}
y.onclick = function () {
move();
}
for (let i = 0; i < Son.length; i++) {
Son[i].onclick = function () {
for (let j = 0; j < Son.length; j++) {
Son[j].className = "son";
}
a1[i].style.zIndex = "40";
Son[i].className = "son son1";
num = i;
}
}
function move1() {
num--;
if (num < 0) {
num = a1.length - 1;
}
for (let j = 0; j < a1.length; j++) {
a1[j].style.zIndex = 20;
Son[j].className = "son"
}
Son[num].className = "son son1"
a1[num].style.zIndex = 30;
}
z.onclick = function () {
move1();
}
透明度轮播
<!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">
<title>轮播</title>
<script src="jquery-3.2.1.js"></script>
</head>
<style>
*{
padding:0;
margin:0;
list-style: none;
}
div.box{
height: 250px;
width: 500px;
margin: 0 auto;
position: relative;
}
div.box .imgbox{
height: 100%;
width: 100%;
position: relative;
}
div.box .imgbox div{
height: 100%;
width: 100%;
position: absolute;
top:0;
left:0;
opacity: 0;
}
div.box .imgbox .active{
opacity: 1;
}
div.box .next{
height: 50px;
width: 15px;
position: absolute;
right: 0;
top:50%;
margin-top:-25px;
background: black;
opacity: 0.8;
}
div.box .pre{
height: 50px;
width: 15px;
position: absolute;
left: 0;
top:50%;
margin-top:-25px;
background: black;
opacity: 0.8;
}
div.box ul{
height: 10px;
width: 50px;
position: absolute;
bottom:25px;
right:25px;
display: flex;
justify-content: space-between;
align-items: center;
}
div.box ul li{
height: 10px;
width: 10px;
border-radius: 50%;
background: white;
}
div.box ul .active{
background: #b0b0b0;
}
</style>
<body>
<div class="box">
<div class="imgbox">
<div class="active" style="background: red;"></div>
<div style="background: green;"></div>
<div style="background: yellow;"></div>
</div>
<div class="next"></div>
<div class="pre"></div>
<ul>
<li class="active"></li>
<li class=""></li>
<li class=""></li>
</ul>
</div>
</body>
</html>
<script>
$(function(){
let num=0;
let t=setInterval(move,2000);
function move(type="next"){
if(type=="next"){
num++;
}else if(type=="pre"){
num--;
}
if(num>=$("div.box .imgbox div").length){
num=0
}
if(num<0){
num=$("div.box .imgbox div").length-1
}
$("div.box .imgbox div")
.removeClass("active")
.eq(num).addClass("active")
$("div.box ul li")
.removeClass("active")
.eq(num).addClass("active")
}
$("div.box .pre").click(function(){
move("pre")
})
$("div.box .next").click(function(){
move()
})
$("div.box").hover(function(){
clearInterval(t)
},
function(){
t=setInterval(move,2000);
})
$("li").click(function(){
let a=$(this).index();
$("div.box .imgbox div")
.removeClass("active")
.eq(a).addClass("active")
$("div.box ul li")
.removeClass("active")
.eq(a).addClass("active")
num=a
})
})
</script>