web前端知识总结三(js)

web前端知识总结三(js)

文章目录

js基础

ECMAScript部分

变量

字面量

[]数组字面量

1000数字字面量

{}对象字面量

输入 prompt()

输出 alert document.write console.log

声明变量

let var

变量的本质:是程序在内存中申请的一块用来存放数据的小空间

规则:

​ 不能使用关键字

​ 只能用下划线、字母、数字、$组成,且数字不能开头

​ 字母严格区分大小写

规范:驼峰命名

var声明

可以先赋值,在声明 不合理

var声明过得变量可以重复声明 不合理

变量提示、全局变量、没有块级作用域

let为了解决var的一些问题,统一使用let

数据类型

基本数字类型:

number,string,boolean、undefined、null

js 是弱数据类型,变量到底属于那种类型,只有赋值后才能确认

模板字符串

let age=81
document。write('啊实打实${age-10}');

undefined 表示没有赋值

null表示赋值了内容为空

检查数据类型

typeof

隐式转换

+号两边有一个是字符串,会把另一个转换成字符串

除了+ 其他会把数据转换成数字类型

缺点 转换不明确

+号作为正好转换number

显示转换
数字类型

Number()转换数字类型 失败为NaN 也是数字类型

parseInt()保留整数

parseFloat(数据)保留小数

字符串型

string()

js操作符

算术运算符

±*/%

赋值运算符

= += -= *= /= %=

一元运算符

正负号 只有一个数字

++i 自加后赋值

i++ 先赋值后加1

比较运算符
><   >=  <=  ==   ===  !==

字符串比较,是比较的字符对应的ascll码

逻辑运算符

&& 左边为false就短路

|| 左边为true就短路

运算符优先级

小括号》一元运算符》算术运算符》关系运算符》相等运算符》逻辑运算符 先&&后||》赋值运算符》逗号

流程控制

表达式 3+4

语句 alert()

分支语句
if分支
三元运算符
条件?满足条件执行的代码:不满足执行的代码
switch语句
switch():
	case 1:break;
	case 2:continue;
	default:
while循环

数组

数组添加

arr.push()

arr.unshift() 前面追加元素

数组删除

arr.pop() 删除最后一个

arr.shift() 删除第一个

arr.splice(操作的下标,删除的个数)

document.write(‘<div calss="box">’);

函数

函数的声明

function  getName(x,y){
	如果调用的的时候,没有传递实参,则默认为0
	x=x||0;
	y=y||0;
}
驼峰命名  前缀为动词 
let re = function getResult(){
	return 20;
}

调用

re()

return

在函数体中使用return关键字能将内部的执行结果交给函数外部使用

return后面的代码不会在被执行,会立即结束当前函数

函数可以没有return,这种情况默认返回为undefined

let re = function getResult(x,y){
	return 20,30;
}
document.write(${re[0]},${re[1]})
作用域

程序代码中的所用到的名字不总是有效和可用的,限定这个名字的可用性的代码范围就是作用域。

提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

全局作用域

全局有效

作用与所有代码执行的环境,或者一个独立的js文件

局部作用域

局部有效

作用于函数内的代码环境,也成为函数函数作用域。

块级作用域

由{}包括 if语句和for语句里面的 {}等

变量的作用域

全局变量 全局能用

局部作用域下 局部变量

变量有个坑,特殊情况:如果函数内或者块级作用域,变量没有声明,直接使用,也当全局变量看,强烈不推荐

但有一种情况,函数内部的形参可以看做是局部变量。

function fn(x,y){
	console.log(x,y);
}
fn(1,2)

作用域链

内部函数可以访问外部函数变量的机制,用链式查找决定那些数据能被内部函数访问,就称作作用域链

let num=10
function fn(){
	let num=20 
	console.log(num)
}
fn()

就近原则 输出20

匿名函数
function(){}

将匿名函数赋值给一个变量,并且通过变量名称进行调用,称函数表达式

let fn=function(){}
调用 fn()
立即执行函数
(function(){console.log(111)})();
(function(){console.log(111)}());
不需要调用,立即执行
let num=10;
(function(){
	防止变量污染
	let num=20;
}());

多个立即函数之间加分号;不然会报错

函数传参小技巧
function fn(x=0,y=0){
	console.log(x+y);
}
fn()
fn(3,5)

对象

无序的数据集合

声明对象
let 对象名={
	属性名:属性值;
	方法名:匿名函数
	mtv:function(s){
	console.log(s)}
}

属性访问:person.name person[‘name’]

调用方法:person.mtv(‘无间道’)

对象操作
修改对象属性值
obj.age=81
console.log(obj)
添加属性
obj.sex=‘男’
去对象里找这个值,如果没有则新增这个属性
删除属性

delete obj.name

遍历对象
for (let k in obj){
	console.log(k) 属性名
	console.log(obj[k]) 属性值
}
数组对象
let students=[
	{name:asd,age:13,sad:213},
	{name:asd,age:13,sad:213},
	{name:asd,age:13,sad:213}
]
遍历数组对象
for(let i=0;i<students.length;i++){
	console.log(students[i].name);
	console.log(students[i].age);
	
	
	document.write(
	‘
	<tr>
		<td>${i+1}</td>
		<td>${students[i].name}</td>
		<td>${students[i].age}</td>
	</tr>
	’)
}
内置对象
Math
Math.PI
Math.random()随机数 [0-1)
Math.ceil() 向上取整
Math.floor() 向下取整
Math.round() 四舍五入
Math.max()找最大值
Math.min()找最小值
Math.pow()幂运算
Math.abs()绝对值

封装随机函数

function getRandom(min,max){
	return Math.floor(Math.random()*(max-min+1))+min;
}
术语

关键字

let var function if else switch case break

保留字

int short long char

标识符=变量名 函数名

表达式 10+3 age>=18

值类型 string number boolean undefined null

引用类型 复杂数据类型,在存储时变量中储存的仅仅是地址,因此叫做引用数据类型,通过new 关键字创建的对象 object array date

栈 可以储存简单数据,自动分别存放函数的参数值、局部变量的值

堆 可以储存复杂数据 (对象),程序员不释放,由垃圾回收机制回收

复杂数据,栈里存储地址,根据地址在堆里找数据

数据类型的存储方式
let num1=10
let num2=num1
num2=20
console.log(num1)
输出10
num1和num2不影响
简单数据类型存储的是值
对象引用数据类型  栈里存储的是地址
let obj1={
age:10
}
let obj2=obj1
obj2.age=20
console.log(obj1)
输出20
obj2和obj1指向相同的堆

Web Api

DOM

DOM 文档对象模型 作用:使用js操作html和浏览器 操作网页内容 实现用户交互

BOM浏览器对象模型

DOM树

又称文档树

直观的体现了标签与标签之间的关系

DOM对象

document对象

访问和操作网页内容的 document.write()

元素节点 属性节点 文本节点

元素对象代表着一个 HTML 元素。

document 对象属性
属性描述
body提供对 元素的直接访问。对于定义了框架集的文档,该属性引用最外层的 。
cookie设置或返回与当前文档有关的所有 cookie。
domain返回当前文档的域名。
lastModified返回文档被最后修改的日期和时间。
referrer返回载入当前文档的文档的 URL。
title返回当前文档的标题。
URL返回当前文档的 URL。
element.className设置或返回元素的class属性
Document 对象方法
方法描述
close()关闭用 document.open() 方法打开的输出流,并显示选定的数据。
element.getAttribute()返回指定元素的属性值
element.getAttributeNode()返回指定属性节点
getElementById()返回对拥有指定 id 的第一个对象的引用。
getElementsByName()返回带有指定名称的对象集合。
getElementsByTagName()返回带有指定标签名的对象集合。
element. getElementsByClassName()返回文档中所有指定类名的元素集合,作为 NodeList 对象。
open()打开一个流,以收集来自任何 document.write() 或 document.writeln() 方法的输出。
write()向文档写 HTML 表达式 或 JavaScript 代码。
writeln()等同于 write() 方法,不同的是在每个表达式之后写一个换行符。
element.focus()设置文档或元素获取焦点
element.appendChild()为元素添加一个新的子元素
element.addEventListener()向指定元素添加事件句柄
element.hasAttribute()如果元素中存在指定的属性返回 true,否则返回false。
element.hasChildNodes()返回一个元素是否具有任何子元素
element.hasFocus()返回布尔值,检测文档或元素是否获取焦点
element.toString()一个元素转换成字符串
element.insertBefore()现有的子元素之前插入一个新的子元素
element.isEqualNode()检查两个元素是否相等
element.isSameNode()检查两个元素所有有相同节点。
element.querySelector()返回匹配指定 CSS 选择器元素的第一个子元素
document.querySelectorAll()返回匹配指定 CSS 选择器元素的所有子元素节点列表
element.removeAttribute()从元素中删除指定的属性
element.removeAttributeNode()删除指定属性节点并返回移除后的节点。
element.removeChild()删除一个子元素
element.removeEventListener()移除由 addEventListener() 方法添加的事件句柄
element.replaceChild()替换一个子元素
element.setAttributeNode()设置或者改变指定属性节点。
element.setIdAttribute()
element.setIdAttributeNode()
Document 对象集合
集合描述
[all]提供对文档中所有 HTML 元素的访问。
[anchors]返回对文档中所有 Anchor 对象的引用。
applets返回对文档中所有 Applet 对象的引用。
[forms]返回对文档中所有 Form 对象引用。
[images]返回对文档中所有 Image 对象引用。
[links]返回对文档中所有 Area 和 Link 对象引用。
获取DOM对象
选择匹配的第一个元素
document.querySelector('css选择器');  (ul li:last-child)
参数:包含一个或多个有效的css选择器
返回值:css选择器匹配的第一个元素,一个HTMLELement对象 :<div class="tree"></div>
如果没有匹配到返回null
选择匹配的多个元素
document.querySelectorAll('css选择器');
参数:包含一个或多个有效的css选择器字符串
document.querySelectorAll('ul li');
必须是字符串,也就是必须加引号
设置/修改DOM元素内容
document.write()
将文本内容追加到</body>前面的位置
文本中包含的标签会被解析
对象.innerText属性

将文本内容添加/更新到任意标签位置

文本内的标签不会被解析

let box=document.querySelectot('div');
box.innerText='<strong>有点意思</strong>'
对象.innerHtml属性

将文本内容添加/更新到任意标签位置

文本内的标签被解析

设置/修改DOM元素属性

对象.属性=值

let pic=document.querySelector('img');
pic.src='./images/${num}.jpg'
pic.title='这是一个图片'
设置/修改DOM元素样式属性
元素.className=’active'

修改元素类名,会覆盖原有类名

通过classList操作控制css

为了解决覆盖类名,使用classlist

let box==document.querySelector('div');
元素.classList.add('类名') 添加类名
元素.classList.remove('类名') 移除类名
元素.classList.toggle('类名') 切换类名:有就删除,没有就添加
修改元素样式属性style
document.body.style.backgroundImage=url('./images/desktop.jpg')
document.body.style+样式属性
设置/修改表单元素属性
let input==document.querySelector('input');
input.value='小米'
input.type=‘password’
let button==document.querySelector('button');
button.disable = false
let checkbox==document.querySelector('checkbox');
checkbox.checked=true
HTML DOM Element 对象
childNodes返回元素的一个子节点的数组attributes 返回一个元素的属性数组
element.children返回元素的子元素的集合
element.classList返回元素的类名,作为 DOMTokenList 对象。
element.className设置或返回元素的class属性
element.clientTop表示一个元素的顶部边框的宽度,以像素表示。
element.clientLeft表示一个元素的左边框的宽度,以像素表示。
element.clientHeight在页面上返回内容的可视高度(高度包含内边距(padding),不包含边框(border),外边距(margin)和滚动条)
element.clientWidth在页面上返回内容的可视宽度(宽度包含内边距(padding),不包含边框(border),外边距(margin)和滚动条)
element.dir设置或返回一个元素中的文本方向
element.firstChild返回元素的第一个子节点
element.id设置或者返回元素的 id。
element.innerHTML设置或者返回元素的内容。
element.contentEditable设置或返回元素的内容是否可编辑
element.classList返回元素的类名,作为 DOMTokenList 对象。
element.lastChild返回最后一个子节点
element.lastElementChild返回指定元素的最后一个子元素
element.nextSibling返回该元素紧跟的一个节点
element.nextElementSibling返回指定元素之后的下一个兄弟元素(相同节点树层中的下一个元素节点)。
element.nodeValue返回元素的节点值
element.offsetHeight返回任何一个元素的高度包括边框(border)和内边距(padding),但不包含外边距(margin)
element.offsetWidth返回元素的宽度,包括边框(border)和内边距(padding),但不包含外边距(margin)
element.offsetLeft返回当前元素的相对水平偏移位置的偏移容器
element.offsetParent返回元素的偏移容器
element.parentNode返回元素的父节点
element.previousSibling返回某个元素紧接之前元素
element.previousElementSibling返回指定元素的前一个兄弟元素(相同节点树层中的前一个元素节点)。
element.scrollLeft返回当前视图中的实际元素的左边缘和左边缘之间的距离
element.scrollTop返回当前视图中的实际元素的顶部边缘和顶部边缘之间的距离
element.scrollWidth返回元素的整个宽度(包括带滚动条的隐蔽的地方)
element.style设置或返回元素的样式属性
element.tabIndex设置或返回元素的标签顺序。
element.tagName作为一个字符串返回某个元素的标记名(大写)
element.textContent设置或返回一个节点和它的文本内容
nodelist.length返回节点列表的节点数目。
element.value元素的内容
查找父节点childNodes
document.getElementById("item1").parentNode;
返回元素子节点的 NodeList childNodes
document.body.childNodes;
兄弟节点nextSibling 、previousSibling
document.getElementById("item1").nextSibling;

返回位于相同节点树层级的下一个节点。

document.getElementById("item2").previousSibling;

属性返回同一树层级中指定节点的前一个节点。

创建新节点createElement
var node=document.createElement("LI");
var textnode=document.createTextNode("Water");
node.appendChild(textnode);
document.getElementById("myList").appendChild(node);

向元素添加新的子节点,作为最后一个子节点。

var newItem=document.createElement("LI")
var textnode=document.createTextNode("Water")  把文本添加在li标签里,在添加在节点前
newItem.appendChild(textnode)
var list=document.getElementById("myList")
list.insertBefore(newItem,list.childNodes[0]);



var node=document.getElementById("myList2").lastChild;
var list=document.getElementById("myList1");
list.insertBefore(node,list.childNodes[0]);

在指定的已有的子节点之前插入新节点。 添加在开头

克隆节点cloneNode
var node=document.getElementById("myList2").lastChild.cloneNode(true);
document.getElementById("myList1").appendChild(node);

把一个列表项从一个列表复制到另一个:

删除子节点removeChild
var list=document.getElementById("myList");
list.removeChild(list.childNodes[0]);
如不存在父子关系则删除不成功
删除和隐藏有区别,隐藏节点还是存在
返回指定属性名的属性值
document.getElementsByTagName("a")[0].getAttribute("target");

定时器

this指向的window

开启定时器
setInterval(函数,间隔时间);
作用:每隔一段时间调用这个函数
时间单位是毫秒
function re(){
	console.log("赛道年"):
}
setInterval(re,1000);
setInterval(function(){
	console.log("赛道年"):
},1000);

关闭定时器

function re(){
	console.log("赛道年"):
}
let timer=setInterval(re,1000);
清除定时器
clearInterval(timer);
倒计时例子

例子一

		// 1. 获取元素 button 
        let btn = document.querySelector('.btn')
        // 2. 计算逻辑
        // 2.1 我们需要一个变量 用来计数  
        let i = 6
        // 2.2 开启定时器 间歇函数  timer 定时器的序号id
        let timer = setInterval(function () {
            i--
            btn.innerHTML = `我已经阅读用户协议(${i})`
            if (i === 0) {
                // 不走了,清除定时器 
                clearInterval(timer)
                // 开启按钮
                btn.disabled = false
                // 更换文字
                btn.innerHTML = '我同意该协议啦'
            }
        }, 1000)

例子二

       et data = [
            {
                imgSrc: 'images/b01.jpg',
                title: '挑战云歌单,欢迎你来'
            },
            {
                imgSrc: 'images/b02.jpg',
                title: '田园日记,上演上京记'
            },];
       // 1. 获取元素  图片  和  h3
        let pic = document.querySelector('.pic')
        let text = document.querySelector('.text')
        // i 记录图片的张数
        let i = 0
        // 2.开启定时器
        setInterval(function () {
            i++
            // 修改图片的src属性
            // console.log(data[i].imgSrc)
            pic.src = data[i].imgSrc
            // 修改文字内容
            text.innerHTML = data[i].title

            // 无缝衔接
            if (i === data.length - 1) {
                i = -1
            }
            // i === 8 ? i = -1 : i
        }, 1000)

事件

元素.addEventlistener(‘事件‘,执行函数)

事件:click mouseover

element.addEventListener(event, function, useCapture);

第一个参数是事件的类型 (如 “click” 或 “mousedown”).

第二个参数是事件触发后调用的函数。

第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。

 // 数据数组
        let arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
        function getRandom(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min
        }
        // 1. 获取元素  两个按钮 + div
        // 一定不要忘记加点  因为里面写css类选择器
        let start = document.querySelector('.start')
        let end = document.querySelector('.end')
        let qs = document.querySelector('.qs')
        // timer 要是全局变量
        let timer = 0
        // random 要是全局变量
        let random = 0
        // 2. 给开始按钮注册事件
        start.admousedEventListener('click', function () {
            // 随机抽数据--- 快速不断的抽取 间歇函数定时器
            timer = setInterval(function () {
                random = getRandom(0, arr.length - 1)
                qs.innerHTML = arr[random]
            }, 25)
            // 如果到了最后一个,就禁用两个按钮
            if (arr.length === 1) {
                // console.log('没了')
                // start.disabled = true
                // end.disabled = true
                start.disabled = end.disabled = true
            }
        })
        // 3. 给结束按钮注册事件  本质是停止定时器
        end.addEventListener('click', function () {
            // 停止定时器
            clearInterval(timer)
            // 删除数组元素
            arr.splice(random, 1)
            // console.log(arr)
        })
事件类型
事件描述
onchangeHTML 元素改变
onclick用户点击 HTML 元素
onmouseover鼠标指针移动到指定的元素上时发生
onmouseout用户从一个 HTML 元素上移开鼠标时发生
onkeydown用户按下键盘按键
onload浏览器已完成页面的加载

原先使用

<button onclick="displayDate()">现在的时间是?</button>
鼠标事件

click mouseenter mouseleave mouseover mouseout

焦点事件

focus blur

键盘事件

keydown keyup

文本事件

input

全选反选案例
   // 1. 获取元素  全选 和   ck 小复选框
    let all = document.querySelector('#checkAll')
    let cks = document.querySelectorAll('.ck')
    let span = document.querySelector('span')
    // 2. 事件监听   全选按钮  
    all.addEventListener('click', function () {
      // console.log(all.checked)  // true  false 
      // 我们需要做的就是把 all.checked 给下面三个小按钮
      // 因为三个按钮在伪数组里面,我们需要遍历的方式,挨着取出来,依次给值
      for (let i = 0; i < cks.length; i++) {
        cks[i].checked = all.checked
      }
      // 当我们的全选按钮处于选中状态,则可以改为取消
      if (all.checked) {
        // console.log('要改')
        span.innerHTML = '取消'
      } else {
        span.innerHTML = '全选'
      }
    })


    // 3. 小按钮的做法 同时给多个元素绑定相同事件
    for (let i = 0; i < cks.length; i++) {
      // 绑定事件
      cks[i].addEventListener('click', function () {
        // console.log(11)
        // 只要点击任何一个小按钮,都要遍历所有的小按钮  
        for (let j = 0; j < cks.length; j++) {
          // 都来看看是不是有人没有选中
          if (cks[j].checked === false) {
            // 如果有false 则退出循环 结束函数
            all.checked = false
            span.innerHTML = '全选'
            return
          }
        }
        // 当我们的循环结束,如果代码走到这里,说明没有false,都被选中了,则全选按钮要选中
        all.checked = true
        span.innerHTML = '取消'
      })
    }
购物车加减案例
 // 1. 获取元素  三个
      let total = document.querySelector('#total')
      let add = document.querySelector('#add')
      let reduce = document.querySelector('#reduce')
      // 2. 点击加号 事件侦听  
      add.addEventListener('click', function () {
        // console.log(typeof total.value)
        // total.value = total.value + 1
        // i++   隐式转换
        // i = i + 1 
        total.value++
        reduce.disabled = false
      })
      // 3. 点击减号 事件侦听  
      reduce.addEventListener('click', function () {

        total.value--
        if (total.value <= 1) {
          reduce.disabled = true
        }
      })

高阶函数

回调函数

如果将函数A做为参数传递给函数B时,我们称函数A为回调函数

本质还是函数,只不过当参数使用

使用匿名函数常见

  		let num = 10
        //函数表达式
        let fn = function () { }
        btn.onclick = function () { }
        // 高阶函数 函数的高级用法,把函数当值来看看

        //  回调函数

        // setInterval(function(){}, 1000)
        function fn() { }
        setInterval(fn, 1000)
        // 此时 fn 就是回调函数   回头去调用的函数

        box.addEventListener('click', fun)
        function fun() {

        }

环境对象

指函数内部特殊的变量this,代表着当前函数运行时所在的环境

  		// 环境对象 this 他就是个对象
        function fn() {
            console.log(this)
        }
        // fn()
        window.fn()
		window调用了这个函数
		
        let btn = document.querySelector('button')
        btn.addEventListener('click', function () {
            console.log(typeof this)
            // 因为btn 调用了这个函数,所以 this 指向btn
        })

函数的调用方式不同,this指代的对象也不同

谁调用,this就是谁

排他思想

<body>
    <button>第1个</button><button>第2个</button><button>第3个</button><button>第4个</button><button>第5个</button>
    <script>
        let btns = document.querySelectorAll('button')
        for (let i = 0; i < btns.length; i++) {
            btns[i].addEventListener('click', function () {
                // this.classList.add('pink')
                // 干掉所有人
                for (let j = 0; j < btns.length; j++) {
                    btns[j].classList.remove('pink')
                }
                // 复活我自己
                this.classList.add('pink')
            })
        }
    </script>
</body>

升级

<body>
    <button class="pink">第1个</button><button>第2个</button><button>第3个</button><button>第4个</button><button>第5个</button>
    <script>
        let btns = document.querySelectorAll('button')
        for (let i = 0; i < btns.length; i++) {
            btns[i].addEventListener('click', function () {
                // this.classList.add('pink')
                // // 干掉所有人
                // for (let j = 0; j < btns.length; j++) {
                //     btns[j].classList.remove('pink')
                // }
                // 我只需要找出那个唯一的 pink类,删除
                document.querySelector('.pink').classList.remove('pink')
                // 我的
                this.classList.add('pink')
            })
        }
    </script>

tab栏案例

<body>
  <div class="wrapper">
    <ul class="tab">
      <li class="tab-item active">国际大牌<span>◆</span></li>
      <li class="tab-item">国妆名牌<span>◆</span></li>
      <li class="tab-item">清洁用品<span>◆</span></li>
      <li class="tab-item">男士精品</li>
    </ul>
    <div class="products">
      <div class="main active">
        <a href="###"><img src="imgs/guojidapai.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/guozhuangmingpin.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/qingjieyongpin.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/nanshijingpin.jpg" alt="" /></a>
      </div>
    </div>
  </div>
  <script>
    // 0. 获取元素
    // 得到所有的小li  
    let lis = document.querySelectorAll('.tab .tab-item') //tab下面的tab-item
    let divs = document.querySelectorAll('.products .main')
    // 1. 头部tab栏切换模块
    // 1.1 先给4个小li添加点击事件
    for (let i = 0; i < lis.length; i++) {
      lis[i].addEventListener('click', function () {
        // console.log(11)
        // 找到以前的active 类,移除掉 
        document.querySelector('.tab .active').classList.remove('active')
        // 当前的元素添加
        this.classList.add('active')

        // 2. 底部显示隐藏模块  一定要写到点击事件的里面
        document.querySelector('.products .active').classList.remove('active')

        // div对应序号的那个加上active 
        divs[i].classList.add('active')
      })
    }
</script>
</body>

节点操作

DOM树里每一个内容都称之为节点

元素节点 body div html

属性节点 href 所有属性

文本节点 所有文本

父节点查找

子元素.parentNode

找不到返回NULL

能返回父节点的class

关闭多个二维码
// 1. 获取元素  关闭按钮
let close_btn = document.querySelectorAll('.close')
// 2. 绑定多个点击事件给close
for (let i = 0; i < close_btn.length; i++) {
  close_btn[i].addEventListener('click', function () {
    // 3. 关闭当前的那个二维码  点击谁,就关闭谁的爸爸
    this.parentNode.style.visibility = 'hidden'
  })
}
获取子节点

父元素.children 返回标签名数组 [li,li,li,li,li]

父元素.childNodes 所有子节点

查找兄弟节点

nextElementSibling 下一个兄弟节点

previousElementSibling 上一个兄弟节点

增加节点
    // 二毛   ul.children[1]
    // 1. 创建新的标签节点
    // let div = document.createElement('div')
    // div.className = 'current'
    let ul = document.querySelector('ul')
    let li = document.createElement('li')

    li.innerHTML = '我是xiao ming'
    // 2. 追加节点  父元素.appendChild(子元素) 后面追加
    // ul.appendChild(li)
    // 3. 追加节点  父元素.insertBefore(子元素, 放到那个元素的前面)   
    ul.insertBefore(li, ul.children[0])
克隆节点
删除节点
 // 需求,点击按钮,删除小li
    let btn = document.querySelector('button')
    let ul = document.querySelector('ul')
    btn.addEventListener('click', function () {
        // 删除的语法 父元素.removeChild(子元素)
        ul.removeChild(ul.children[0])
    })

从父元素删除

时间对象

let date =new date()
let arr=[]
let arr=new Array()
let obj=[]
let obj=new Object()

获取指定时间
let date=new date('1949-10-1 18:30:00')
        // new 实例化 时间对象
        // 小括号为空可以得到当前的时间
        let date = new Date()
        console.log(date.getFullYear())
        console.log(date.getMonth() + 1)
        console.log(date.getDate())
        // 时分秒
        console.log(date.getHours())
        console.log(date.getMinutes())
        console.log(date.getSeconds())
        // 星期几
        console.log(date.getDay())

显示时间

        let arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
        let div = document.querySelector('div')
        // 先调用,就省去了1秒的空白期
        getTime()
        setInterval(getTime, 1000)
        function getTime() {
            // 1. 实例化时间对象 一定写到定时器里面才可以额
            let date = new Date()
            let year = date.getFullYear()
            let month = date.getMonth() + 1
            let date1 = date.getDate()
            let hour = date.getHours()
            let min = date.getMinutes()
            let sec = date.getSeconds()
            let day = date.getDay()
            div.innerHTML = `今天是: ${year}年${month}月${date1}日 ${hour}:${min}:${sec} ${arr[day]}`
        }
时间戳
 		// 时间戳是总的毫秒数  是独一无二的  
        // 计算倒计时: 核心思想:
        // 将来时间 9.1 12:00   有一个时间戳   2000000
        // 现在的时间 8.29 15:00   有一个时间戳   1000000
        // 可以利用将来的时间戳 减去 现在的时间戳 就是剩余的时间毫秒数
        // 转换为时分秒就是剩余的时间了
        // 1. getTime()
        // let date = new Date()
        // console.log(date.getTime())
        // 2. +new Date()
        console.log(+new Date()) // 当前的时间戳
        console.log(+new Date('2021-8-30 12:00:00'))  // 指定时间的时间戳
        // 3. 只能得到当前的
        // console.log(Date.now())
倒计时

    let hour = document.querySelector('#hour')
    let minutes = document.querySelector('#minutes')
    let scond = document.querySelector('#scond')
    time()
    setInterval(time, 1000)
    function time() {
      // 1. 得到现在的时间戳
      let now = +new Date()
      // 2. 得到指定时间的时间戳
      let last = +new Date('2021-8-29 18:30:00')
      // 3. (计算剩余的毫秒数) / 1000 === 剩余的秒数
      let count = (last - now) / 1000
      // console.log(count)
      // 4. 转换为时分秒
      // h = parseInt(总秒数 / 60 / 60 % 24)   //   计算小时
      let h = parseInt(count / 60 / 60 % 24)
      h = h < 10 ? '0' + h : h
      // m = parseInt(总秒数 / 60 % 60);     //   计算分数
      let m = parseInt(count / 60 % 60)
      m = m < 10 ? '0' + m : m
      // s = parseInt(总秒数 % 60); //   计算当前秒数
      let s = parseInt(count % 60);
      s = s < 10 ? '0' + s : s
      // console.log(h, m, s)
      hour.innerHTML = h
      minutes.innerHTML = m
      scond.innerHTML = s
    }

  
li.innerHTML = `
       <div class="info">
      <img class="userpic" src=${dataArr[random].imgSrc}>
      <span class="username">${dataArr[random].uname}</span>
      <p class="send-time"> ${new Date().toLocaleString()} </p>
      </div>
      <div class="content">${textarea.value}</div>
      <span class="the_del">X</span>
’
     let del = li.querySelector('.the_del')
      del.addEventListener('click', function () {
        // 删除操作  点击的是X  删除的小li  父元素.removeChild(子元素)
        ul.removeChild(li)
      })

重绘和回流

浏览器如何进行页面渲染的?

解析html,生成dom树

同时解析css,生成样式规则

根据dom树和样式规则,生成渲染树

进行布局layout(回流/重排):根据生成的渲染树,得到节点的几何信息(位置、大小)——————画盒子,渲染布局

进行绘制panting(重绘):根据计算和获取的信息进行整个页面的绘制

display展示在页面上

回流(重排)

当渲染树中部分或全部元素的尺寸、结构、布局等发生改变时,浏览器就会重新渲染部分或全部文档的过程成文回流

重绘

由于节点的样式的改变并不影响它在文档流中的位置和文档布局(color、background-color、outline)称为重绘

作用域

 // let num = 10
 // {
 //     let num = 20
 //     console.log(num)
 // }
 // console.log(num)

(function () {
let num = 10
}())
let num = 20

事件对象e

<button>点击</button>
<script>
    let btn = document.querySelector('button')
    btn.addEventListener('mouseenter', function (e) {
    console.log(e)
    })
</script>

e、event、ev

常用属性

type 获取当前事件类型

clientx/clienty 获取光标相对于浏览器可见窗口左上角的位置

offsetx/offsety 获取光标相对域当前dom元素左上角的位置

key 用户按下的键盘键的值

不提倡使用keycode

if(e.key=='Enter'){
	send.click()
}

pagex/pagey 跟文档坐标有关系

clientX:触摸目标在视口中的x坐标。
clientY:触摸目标在视口中的y坐标。
identifier:标识触摸的唯一ID。
pageX:触摸目标在页面中的x坐标。
pageY:触摸目标在页面中的y坐标。
screenX:触摸目标在屏幕中的x坐标。
screenY:触摸目标在屏幕中的y坐标。
鼠标跟随移动
<img src="./images/tianshi.gif" alt="">
    <script>
        let img = document.querySelector('img')
        document.addEventListener('mousemove', function (e) {
            // 不断得到当前的鼠标坐标
            // console.log(e.pageX)
            // console.log(e.pageY)
            // 把坐标给图片
            // img.style.left = '100px'
            img.style.left = e.pageX - 50 + 'px'
            img.style.top = e.pageY - 40 + 'px'
        })
    </script>

事件流

指事件完整执行过程中的流动路径

捕获阶段 document—element html—element body— element div 从父到子

冒泡阶段 div—body—html—document 从子到父

触发事件会经历两个阶段 捕获阶段 冒泡阶段

事件冒泡和事件捕获

当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。

当一个元素触发事件后,会依次向上调用所有父级元素的同名事件

        let fa = document.querySelector('.father')
        let son = document.querySelector('.son')
        fa.addEventListener('click', function () {
            alert('我是爸爸')
        }, true)
        son.addEventListener('click', function () {
            alert('我是儿子')
        }, true)
        document.addEventListener('click', function () {
            alert('我是爷爷')
        }, true)

        // btn.onclick = function() {}
DOM.addEventListener(事件类型,函数,是否使用捕获机制)

事件冒泡是默认存在的

false代表冒泡阶段触发,默认就是false

true代表捕获阶段触发

阻止事件流动
事件对象.stopPropagation()
		let fa = document.querySelector('.father')
        let son = document.querySelector('.son')
        fa.addEventListener('click', function (e) {
            alert('我是爸爸')
            e.stopPropagation()
        })
        son.addEventListener('click', function (e) {
            alert('我是儿子')
            // 阻止流动 Propagation 传播
            e.stopPropagation()   只执行自己
        })
        document.addEventListener('click', function () {
            alert('我是爷爷')
        })

mouseover和mouseenter区别

mouseover和mouseout有冒泡

mouseenter 和mouseleave没有冒泡(推荐)

	<div class="father">
        <div class="son"></div>
    </div>
    <script>
        let fa = document.querySelector('.father')
        let son = document.querySelector('.son')
        fa.addEventListener('mouseenter', function () {
            console.log(111)
        })
    </script>
阻止默认行为

如链接点击不跳转,表单域的跳转

e.preventDefault()
 <a href="http://www.baidu.com">跳转到百度</a>
    <script>
        let a = document.querySelector('a')
        a.addEventListener('click', function (e) {
            // 阻止默认行为 方法
            e.preventDefault()
        })
    </script>

两种注册事件的区别

传统on

后面的事件会覆盖前面的同一个事件

直接使用null覆盖就可以实现事件的解绑

都是冒泡执行

事件监听注册

后面注册的事件不会覆盖前面的注册事件 同一个事件

可以通过第三个参数确定冒泡或捕获

解绑必须使用removeEventListener(事件类型,函数,冒泡或捕获)

匿名函数无法被解绑

    <button>点击</button>
    <script>
        let btn = document.querySelector('button')
        // 1.l0 on
        // 多次相同的事件,只执行最后一次
        // btn.onclick = function () {
        //     alert('第一次')
        // }
        // btn.onclick = function () {
        //     alert('第二次')
        // }
        // 解绑事件
        // btn.onclick = null
        // 2. addEventListener
        btn.addEventListener('click', add)
        function add() {
            alert('第一次')
        }
        // btn.addEventListener('click', function () {
        //     alert('第二次')
        // })
        btn.removeEventListener('click', add)

事件委托

jquery封装了事件委托的支持

//直接绑定

$('选择器').on('事件名',function(){})

//事件委托 原理:事件冒泡

$('祖先选择器').on('事件名','后代选择器',function(){})

减少事件注册

解决动态增加后代元素的绑定问题

 		// 不要每个小li注册事件了  而是把事件委托给他的爸爸 
        // 事件委托是给父级添加事件 而不是孩子添加事件
        let ul = document.querySelector('ul')
        ul.addEventListener('click', function (e) {
            // alert('我点击了')
            // 得到当前的元素
            // console.log(e.target)
            e.target.style.color = 'red'
        })		

手风琴案例

<body>
  <div id="box">
    <ul>
      <li>
        <a href="#">
          <img src="./images/1.jpg" alt="">
        </a>
      </li>
      <li>
        <a href="#">
          <img src="./images/2.jpg" alt="">
        </a>
      </li>
      <li>
        <a href="#">
          <img src="./images/3.jpg" alt="">
        </a>
      </li>
      <li>
        <a href="#">
          <img src="./images/4.jpg" alt="">
        </a>
      </li>
      <li>
        <a href="#">
          <img src="./images/5.jpg" alt="">
        </a>
      </li>
    </ul>
  </div>
</body>
  // 获取元素
  let box = document.querySelectorAll('li');// lis = [li, li, li, li, li]
  // 分析:
  // 1、鼠标进入显示图片,
  // 鼠标进入li,让当前li变成800,其他的li变成100
  for (let i = 0; i < box.length; i++) {

    box[i].addEventListener('mouseenter', function () {
      for (let j = 0; j < box.length; j++) {// 事件触发执行,为了让所有li变成240宽的
        box[j].style.width = '100px';
      }
      this.style.width = '800px'
    })

    box[i].addEventListener('mouseleave', function () {
      // 让所有的li变成240
      for (let j = 0; j < box.length; j++) {// 事件触发执行,为了让所有li变成240宽的
        box[j].style.width = '240px';
      }
    })

页面滚动事件

事件名:scroll

<body>
    <div>
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字
        我里面可以放很多的文字

    </div>
    <script>
        let div = document.querySelector('div')
        window.addEventListener('scroll', function () {
            console.log(111)
        })
        // div.addEventListener('scroll', function () {
        //     console.log(111)
        // })
    </script>

页面加载事件

不光可以监听整个页面资源加载完毕,也可以针对某个资源邦迪load事件

<script>
        window.addEventListener('load', function () {
            let div = document.querySelector('div')
            console.log(div)
        })
    </script>

当初始html文被完全加载和解析完成后,DOMcontentLoaded事件被触发,无需等待样式、图像完全加载

事件名:DOMcontentLoaded

给document添加事件

 document.addEventListener('DOMcontentLoaded', function () {
 
        })

Scroll家族

获取宽高:

获取内容总宽高 不含滚动条

scrollwidth和scrollHeight

获取位置:

scrollLeft ScrollTop 可以修改

获取元素内容往左、往上滚出去看不到的距离

		// scrollWidth scrollHeight  内容 宽高 (了解)
        let div = document.querySelector('div')
        console.log(div.scrollWidth)  // 150 不带单位
        console.log(div.scrollHeight)  // 336 不带单位
        // div.addEventListener('scroll', function () {
        //     console.log(document.querySelector('div').scrollTop)
        // })

 div {
            width: 150px;
            height: 150px;
            background-color: pink;
            overflow: auto;
            padding: 10px;
            border: 10px solid red;
            margin: 100px;
        }
检查页面滚动距离
   	console.log(document.documentElement) // 返回 html 元素
        // 可以修改 但是不要带单位

        // 先做页面滚动事件
        window.addEventListener('scroll', function () {
            // console.log(11) 
            // 在得到页面滚动的距离  scrollTop
            console.log(document.documentElement.scrollTop)
            // document.documentElement.scrollTop = 500
        })

Offset家族

获取宽高:

获取元素自身宽高、包含元素自身设置的宽高、padding、border

offsetWidth offsetHeight

内容超出盒子 以内容为准

获取位置:

获取元素距离自己定位父级元素的左、上位置

offsetLeft offsetTop 注意是只读属性

  // offset 盒子元素的大小 = 盒子本身的宽度和高度 + padding + border
        console.log(div.offsetWidth)  // 150 不带单位
        console.log(div.offsetHeight)  // 150 不带单位
        // console.log(div.offsetTop)  //
        // console.log(div.offsetLeft)
京东固定头部
 		let sk = document.querySelector('.sk')
        let header = document.querySelector('.header')
        // 1. 页面滚动事件
        window.addEventListener('scroll', function () {
            // console.log(11)
            // 要检测滚动的距离
            // console.log(document.documentElement.scrollTop)
            // console.log(sk.offsetTop)
            // 2. 要检测滚动的距离 >= 秒杀模块的offsetTop 则滑入
            if (document.documentElement.scrollTop >= sk.offsetTop) {
                // alert('改吃饭了')
                header.style.top = '0'
            } else {
                header.style.top = '-80px'
            }
        })
电梯导航案例
// 1. 获元取素  
        let items = document.querySelectorAll('.item')
        // 内容的盒子获取
        let neirongs = document.querySelectorAll('.neirong')
        // 2. 左侧aside 模块 点击谁,谁高亮
        for (let i = 0; i < items.length; i++) {
            items[i].addEventListener('click', function () {
                // 找到上一个active 移除类
                document.querySelector('.aside .active').classList.remove('active')
                // 点击谁谁添加类
                this.classList.add('active')
                // 3. 右侧内容跟随走动  让页面滚动到对应的offsetTop值位置
                // console.log(neirongs[i].offsetTop) 不用给单位
                document.documentElement.scrollTop = neirongs[i].offsetTop
            })
        }

Client家族

获取宽高:

获取元素的可见部分的宽高 不含边框、滚动条

div.clientWidth clientHeight

获取位置:

clientTop clientLeft 边框的宽度 =border

会在窗口尺寸改变的时候触发事件:resize

        // 当窗口变化的时候触发的事件
        window.addEventListener('resize', function () {
            // console.log(111)
            let w = document.documentElement.clientWidth
            // console.log(document.documentElement.clientWidth)
            if (w >= 1920) {
                document.body.style.backgroundColor = 'pink'
            } else if (w > 540) {
                document.body.style.backgroundColor = 'hotpink'

            } else {
                document.body.style.backgroundColor = 'deeppink'

            }
        })



​ // client 当前可视区域 不包含滚动条 边框等等
​ console.log(‘----------------------------’)
​ console.log(div.clientWidth)
​ console.log(div.clientHeight)
​ console.log(div.clientTop) // 边框的宽度 了解 呵呵
​ console.log(div.clientLeft)

轮播图案例

 <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    li {
      list-style: none;
    }

    .main {
      width: 700px;
      margin: auto;
      background: #000;
    }

    .slides {
      height: 320px;
      position: relative;
    }

    .slides ul li {
      /* display: none; */
      position: absolute;
      top: 0;
      left: 0;
      opacity: 0;
      /* 这里实现淡入淡出的关键 */
      transition: all .3s;
    }


    .slides li.active {
      /* display: block; */
      opacity: 1;
    }

    .slides .extra {
      width: 700px;
      height: 53px;
      line-height: 53px;
      position: absolute;
      bottom: 0px;
      background-color: rgba(0, 0, 0, 0.8);
      z-index: 10;
    }

    .slides .extra h3 {
      width: 82%;
      margin: 0;
      margin-right: 20px;
      padding-left: 20px;
      color: #98E404;
      font-size: 28px;
      float: left;
      font-weight: 500;
      font-family: "Microsoft Yahei", Tahoma, Geneva;
    }

    .slides .extra a {
      width: 30px;
      height: 29px;
      display: block;
      float: left;
      margin-top: 12px;
      margin-right: 3px;
      background-image: url(./assets/icon_focus_switch.png);
    }

    .slides .extra .prev {
      background-position: 0 0;
    }

    .slides .extra .prev:hover {
      background-position: -30px 0;
    }

    .slides .extra .next {
      background-position: -60px 0;
    }

    .slides .extra .next:hover {
      background-position: -90px 0;
    }

    .indicator {
      padding: 10px 0;
    }

    .indicator ul {
      list-style-type: none;
      margin: 0 0 0 4px;
      padding: 0;
      overflow: hidden;
    }

    .indicator ul li {
      position: relative;
      float: left;
      width: 60px;
      margin: 0 4px 0 5px;
      text-align: center;

      cursor: pointer;
    }

    .indicator li img {
      display: block;
      border: 0;
      text-align: center;
      width: 60px;
    }

    .indicator li .mask {
      width: 60px;
      height: 60px;
      position: absolute;
      top: 0;
      left: 0;
      background-color: rgba(0, 0, 0, 0.4);
    }

    .indicator li .border {
      display: none;
      width: 54px;
      position: absolute;
      bottom: 0;
      left: 0;
      z-index: 20;
      border: 3px solid #98E404;
    }

    /* li里面的mask 和 border 刚开始都是显示的 */
    /* 我们写一个样式css */
    .indicator .active .mask {
      display: none;
    }

    .indicator .active .border {
      display: block;
    }
  </style>
<body>
  <div class="main">
    <div class="slides">
      <ul>
        <li class="active"><a href="#"><img src="./assets/b_01.jpg" alt="第1张图的描述信息"></a></li>
        <li><a href="#"><img src="./assets/b_02.jpg" alt="第2张图的描述信息"></a></li>
        <li><a href="#"><img src="./assets/b_03.jpg" alt="第3张图的描述信息"></a></li>
        <li><a href="#"><img src="./assets/b_04.jpg" alt="第4张图的描述信息"></a></li>
        <li><a href="#"><img src="./assets/b_05.jpg" alt="第5张图的描述信息"></a></li>
        <li><a href="#"><img src="./assets/b_06.jpg" alt="第6张图的描述信息"></a></li>
        <li><a href="#"><img src="./assets/b_07.jpg" alt="第7张图的描述信息"></a></li>
        <li><a href="#"><img src="./assets/b_08.jpg" alt="第8张图的描述信息"></a></li>
        <li><a href="#"><img src="./assets/b_09.jpg" alt="第9张图的描述信息"></a></li>
        <li><a href="#"><img src="./assets/b_10.jpg" alt="第9张图的描述信息"></a></li>
      </ul>

      <div class="extra">
        <h3>第1张图的描述信息</h3>
        <a class="prev" href="javascript:;"></a>
        <a class="next" href="javascript:;"></a>
      </div>
    </div>
    <div class="indicator">
      <ul>
        <li class="active">
          <img src="assets/s_01.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
        <li>
          <img src="assets/s_02.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
        <li>
          <img src="assets/s_03.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
        <li>
          <img src="assets/s_04.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
        <li>
          <img src="assets/s_05.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
        <li>
          <img src="assets/s_06.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
        <li>
          <img src="assets/s_07.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
        <li>
          <img src="assets/s_08.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
        <li>
          <img src="assets/s_09.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
        <li>
          <img src="assets/s_10.jpg">
          <span class="mask"></span>
          <span class="border"></span>
        </li>
      </ul>
    </div>
  </div>
  <script>
    // 轮播图开始啦
    // 需求①:小图标鼠标经过事件
    //   鼠标经过小图片,当前高亮,其余兄弟变淡  添加类
    let lis = document.querySelectorAll('.indicator li')
    let piclis = document.querySelectorAll('.slides ul li')
    let text = document.querySelector('.extra h3')
    let next = document.querySelector('.next')
    let prev = document.querySelector('.prev')
    let main = document.querySelector('.main')

    // 给多个小li绑定事件
    for (let i = 0; i < lis.length; i++) {
      lis[i].addEventListener('mouseenter', function () {
        // 选出唯一的那个active ,删除类
        document.querySelector('.indicator .active').classList.remove('active')
        // 鼠标经过谁,谁加上active 这个类
        this.classList.add('active')

        // 需求② :大图片跟随变化  一定要放到鼠标经过事件里面
        // 对应的大图片跟着显示,如果想要过渡效果,可以使用opacity效果,可以利用CSS淡入      淡出的效果,还是添加类
        // 选出唯一的那个active ,删除类
        document.querySelector('.slides ul .active').classList.remove('active')
        // 对应序号的那个 li,谁加上active 这个类
        piclis[i].classList.add('active')
        text.innerHTML = `第${i + 1}张图的描述信息`

        // 需求④:解决一个BUG
        // 点击右侧按钮可以实现播放下一张,但是鼠标经过前面的,播放就会乱序
        // 解决方案:  让变化量 index 重新赋值为 当前鼠标经过的索引号
        // 鼠标经过了那个小li 他的索引号就是 i 
        // 右侧按钮是通过 index 来了控制播放的
        index = i
      })
    }


    // 需求③:右侧按钮播放效果
    //   点击右侧按钮,可以自动播放下一张图片
    //   需要一个变化量  index 不断自增
    //   然后播放下一张图片
    //   如果到了最后一张,必须要还原为第1张图片
    //   教你一招: 索引号 = 索引号 % 数组长度 (放到播放前面)
    let index = 0  // 全局变量  信号量 控制器 为了给 右侧按钮和左侧按钮同时使用
    next.addEventListener('click', function () {
      index++
      // 选出 index 小图片 做操作
      // console.log(index)
      // if (index === lis.length) {
      //   index = 0
      // }
      index = index % lis.length
      common()

    })

    // 需求⑤:左侧按钮播放效果
    //   点击左侧按钮,可以自动播放上一张图片
    //   需要一个变化量  index 不断自减
    //   然后播放上一张图片
    //   如果到了第一张,必须要从最后一张播放
    //   教你一招: 索引号 = (数组长度 + 索引号) % 数组长度
    prev.addEventListener('click', function () {
      index--
      // 选出 index 小图片 做操作
      // console.log(index)
      if (index < 0) {
        index = lis.length - 1
      }
      // index = (lis.length + index) % lis.length
      common()

    })

    // 需求⑥:
    //   因为左侧按钮和右侧按钮里面有大量相同的操作,可以抽取封装一个函数 common
    function common() {
      document.querySelector('.indicator .active').classList.remove('active')
      lis[index].classList.add('active')
      // 选出 index 大图片 做操作
      document.querySelector('.slides ul .active').classList.remove('active')
      piclis[index].classList.add('active')
      text.innerHTML = `第${index + 1}张图的描述信息`
    }



    // 需求⑦:开启定时器
    //   其实定时器自动播放,就相当于点击了右侧按钮,此时只需要, next.click()
    let timer = setInterval(function () {
      // 自动调用右侧按钮的点击事件
      next.click()
    }, 1000)
    // 需求⑧:
    //   鼠标经过停止定时器 (清除定时器)

    main.addEventListener('mouseenter', function () {
      clearInterval(timer)
    })
    //   鼠标离开开启定时器 (开启定时器)
    main.addEventListener('mouseleave', function () {
      timer = setInterval(function () {
        // 自动调用右侧按钮的点击事件
        next.click()
      }, 1000)
    })
  </script>

window对象

BOM浏览器对象模型

document

window是浏览器内置中的全局对象

window对象包含了五个属性 navigator location document history screen 构成了BOM

document是DOM的基础 依附于window的属性

定时器——延时函数
<body>
    <button>解除定时器</button>
    <script>
        let btn = document.querySelector('button')
        let timer = setTimeout(function () {
            console.log(111)
        }, 3000)
        // 仅仅执行一次
        btn.addEventListener('click', function () {
            clearTimeout(timer)
        })
    </script>
</body>

setTimeout只执行一次 把一段代码延迟执行 平时省略window


    <img src="./images/ad.png" alt="">
    <script>
        let img = document.querySelector('img')
        setTimeout(function () {
            img.style.display = 'none'
        }, 3000)
    </script>
递归函数
<script>
    // 递归函数 : 自己调用自己就是递归函数
    // 递归函数容易造成死递归,一定要加退出条件
    let num = 0
    function fn() {
        num++
        console.log(111)
        // 在函数里面,调用自己  
        if (num >= 100) {
            return
        }
        fn()
    }
    fn()
</script>

结合递归函数使用setTimeout 是实现setInterval的功能

<script>
    // 利用递归函数 模拟了 setinterval
    let div = document.querySelector('div')
    function fn() {
        div.innerHTML = new Date().toLocaleString()
        setTimeout(fn, 1000)
    }
    fn()

setInterval由clearInterval 清除

setTimeout 由clearTimeout

js执行的机制

js是单线程的 同一时间只能做一件事

如果js的执行事件过长,就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉

js出现了同步和异步

同步

程序的执行顺序和任务的排列顺序是一致的

同步异步区别:流水线上的各个流程的执行顺序不同

所有的同步任务在主线程执行,形成一个执行栈

异步任务 :js 的异步是通过回调函数实现的

1、普通事件 click resize

2、资源加载 load error

3、定时器 setInterval setITimeout

异步任务添加在任务队列

1、先执行执行栈中的同步任务

2、异步任务放入任务队列中

3、一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待任务,进入执行栈,开始执行。

当有异步任务时,提交给对应的异步进程处理

web API 异步API

1、ajax

2、DOM事件

3、setTImeout,setInterval

任务队列1:onload onclick

任务队列2:setTimeout setinterval

任务队列3:ajax网络请求

事件循环(event loop)

1、主线程执行完毕,查询任务队列,取出一个任务,推入主线程出力

2、重复该动作。————称为事件循环

location.href的使用

href获取完整的url地址 可以赋值 进行页面跳转

search 获取地址中携带的参数,符号?后面的部分

hash 获取地址中的哈希值 符号#后面部分

reload 用来刷新当前页面 传入参数true时表示强制刷新

五秒跳转页面
 <a href="http://www.itcast.cn">支付成功,<span>5</span> 秒之后跳转首页</a>
    <script>
        let a = document.querySelector('a')
        let num = 5
        let timer = setInterval(function () {
            num--
            a.innerHTML = `支付成功,<span>${num}</span> 秒之后跳转首页`
            if (num === 0) {
                clearInterval(timer)
                // 跳转页面
                location.href = 'http://www.itcast.cn'
            }
        }, 1000)
location.search ?

location的数据类型是对象 拆分并保存了url地址的各个组成部分

search获取 的地址中携带的参数 符号?后面的部分

    <form action="target.html">
        <input type="text" name="username">
        <button>提交</button>
    </form>
location.hash

hash 获取地址中的哈希值 符号#后面部分

后期vue路由的铺垫,经常用于不刷新页面,显示不同页面,比如网易云音乐

href=“/#/"
location.reload

刷新

location.reload(true)强制刷新

ctrl+f5强制刷新 直接更新最新内容从网上拉去,不走本地缓存

navigator对象

通过userAgent 检测浏览器的版本及平台

  // 检测 userAgent(浏览器信息)
        !(function () {
            const userAgent = navigator.userAgent
            // 验证是否为Android或iPhone
            const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
            const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
            // 如果是Android或iPhone,则跳转至移动站点
            if (android || iphone) {
                location.href = 'http://m.itcast.cn'
            }
        })()

更换手机或电脑的页面版本

history对象

前进 后台 历史记录

back() forward() go(参数)1前进 -1后退1个页面

 	   let qianjin = document.querySelector('.forward')
        let houtui = document.querySelector('.back')
        qianjin.addEventListener('click', function () {
            // history.forward()
            history.go(1)
        })
        houtui.addEventListener('click', function () {
            // history.back()
            history.go(-1)
        })
    </script>

swiper插件

轮播图

<!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>
    <link rel="stylesheet" href="./css/swiper-bundle.min.css">
    <style>
        .box {
            width: 600px;
            height: 350px;
            background-color: pink;
            margin: 100px auto;
        }

        html,
        body {
            position: relative;
            height: 100%;
        }

        body {
            background: #eee;
            font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
            font-size: 14px;
            color: #000;
            margin: 0;
            padding: 0;
        }

        .swiper-container {
            width: 100%;
            height: 100%;
            margin-left: auto;
            margin-right: auto;
        }

        .swiper-slide {
            text-align: center;
            font-size: 18px;
            background: #fff;

            /* Center slide text vertically */
            display: -webkit-box;
            display: -ms-flexbox;
            display: -webkit-flex;
            display: flex;
            -webkit-box-pack: center;
            -ms-flex-pack: center;
            -webkit-justify-content: center;
            justify-content: center;
            -webkit-box-align: center;
            -ms-flex-align: center;
            -webkit-align-items: center;
            align-items: center;
        }

        .swiper-slide img {
            width: 100%;
            height: 350px;
        }

        .swiper-pagination-bullet {
            width: 12px;
            height: 12px;
        }

        .swiper-pagination-bullet-active {
            background-color: #fff;
        }
    </style>
</head>

<body>
    <div class="box">
        <!-- Swiper -->
        <div class="swiper-container one">
            <div class="swiper-wrapper">
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_01.jpg" alt="">
                    </a>
                </div>
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_02.jpg" alt="">
                    </a>
                </div>
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_03.jpg" alt="">
                    </a>
                </div>
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_04.jpg" alt="">
                    </a>
                </div>
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_05.jpg" alt="">
                    </a>
                </div>


            </div>
            <!-- Add Pagination -->
            <div class="swiper-pagination"></div>
            <!-- Add Arrows -->
            <div class="swiper-button-next"></div>
            <div class="swiper-button-prev"></div>
        </div>

    </div>


    <div class="box">
        <!-- Swiper -->
        <div class="swiper-container two">
            <div class="swiper-wrapper">
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_01.jpg" alt="">
                    </a>
                </div>
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_02.jpg" alt="">
                    </a>
                </div>
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_03.jpg" alt="">
                    </a>
                </div>
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_04.jpg" alt="">
                    </a>
                </div>
                <div class="swiper-slide">
                    <a href="#">
                        <img src="./images/b_05.jpg" alt="">
                    </a>
                </div>


            </div>
            <!-- Add Pagination -->
            <div class="swiper-pagination"></div>
            <!-- Add Arrows -->
            <div class="swiper-button-next"></div>
            <div class="swiper-button-prev"></div>
        </div>

    </div>
    <script src="./js/swiper-bundle.min.js"></script>
    <!-- 要放到插件的下面 -->
    <!-- Initialize Swiper -->
    <script>
        var swiper = new Swiper('.one', {
            slidesPerView: 1,
            autoplay: {
                delay: 3000,
                stopOnLastSlide: false,
                disableOnInteraction: true,
            },
            spaceBetween: 0,
            loop: true,
            pagination: {
                el: '.swiper-pagination',
                clickable: true,
            },
            navigation: {
                nextEl: '.swiper-button-next',
                prevEl: '.swiper-button-prev',
            },
            keyboard: true,
        });
        var swiper = new Swiper('.two', {
            slidesPerView: 1,
            autoplay: {
                delay: 5000,
                stopOnLastSlide: false,
                disableOnInteraction: true,
            },
            spaceBetween: 0,
            loop: true,
            pagination: {
                el: '.swiper-pagination',
                clickable: true,
            },
            navigation: {
                nextEl: '.swiper-button-next',
                prevEl: '.swiper-button-prev',
            },
            keyboard: true,
        });
    </script>
</body>

</html>

本地存储

存储在浏览器中,设置 读取方便 刷新不丢失

sessionStorage

周期永久生效,除非收到删除,关闭页面也会存在

可以多窗口共享(同一浏览器)

以键值对的形式存储使用

用法更localStora相同

localStorage

setItem() getItem()removeItem()

// 存储数据 localStorage.setItem('键', '值')
        // localStorage.setItem('uname', 'pink老师')
        // localStorage.setItem('age', 18)
        // 获取数据
        // localStorage.getItem('键')
        // console.log(localStorage.getItem('uname')) 
        // 删除数据
        // localStorage.removeItem('uname')
        // 1. 存储复杂数据类型(引用数据类型)
        let obj = {
            uname: '刘德华',
            age: 17,
            address: '黑马程序员'
        }
        // console.log(JSON.stringify(obj))
        //(1) 复杂数据类型一定要转换为json字符串在进行存储 (因为本地存储只能存储字符串)
        localStorage.setItem('obj', JSON.stringify(obj))
        // AJAX
        // JSON 属性和值都是双引号进行包含
        // let obj = {
        //     "uname": "刘德华",
        //     "age": "17",
        //     "address": "黑马程序员"
        // }
        // (2) 取数据  可以使用 JSON.parse()  将json字符串转换为对象
        // console.log(typeof localStorage.getItem('obj'))
        console.log(JSON.parse(localStorage.getItem('obj')))

        let object = {
            age: 18
        }

        // 本地存储只能存储字符串 所以我要转换  转换为JSON格式的字符串
        localStorage.setItem('key', JSON.stringify(object))
        // 获取的过来的值是字符串,不是对象了没有办法直接使用,因此我们首先吧字符串转换为对象
        // JSON.parse()
        console.log(JSON.parse(localStorage.getItem('key')))
存储复杂数据类型

本地只能存储字符串,无法存储复杂数据类型,需要将复杂数据类型转换称json字符串,存储在本地

JSON.stringify

将复杂数据(对象)转换称Json字符串 存储在本地

JSON.parse

将JSOn字符串转换称对象 取出时候使用

自定义属性

固有属性:class id title

自定义:setAttribute() getAttribute() removeAttribute()

规范: data-自定义属性 data-开头

dataset 能得到所有自定义属性

不允许删除第一条数据 添加自定义属性

 <div class="box" data-index="0" data-name="andy"></div>
    <script>
        // 设置自定义属性
        let box = document.querySelector('.box')
        // box.setAttribute('myid', 10)
        // console.log(box.getAttribute('myid'))
        console.log(box.dataset)
        console.log(box.dataset.index)
    </script>

正则表达式

用户名:/1{3,16}$/

过滤掉页面的一些敏感词,或从字符串中获取想要的特定部分(提取)

是用于匹配字符串中字符组合的模式

语法
let 变量=/表达式/

/ /是正则表达式的字面量 返回的是对象 正则对象

test()方法 用来查看正则表达式与指定的字符串是否匹配

exec() 检索 可以查找索引 返回的是数组

regObj.test(被检测的字符串)
		// 定义正则表达式   reg 里面存的是对象
        let reg = /前端/
        // 2. 检测是否匹配 test (重点)
        let str = '我们大家都在学前端'
        // console.log(reg.test(str))    reg检测str 
        // 3. 检索 exec()
        console.log(reg.exec(str))  // 返回的是数组
元字符

输入26个英文字母[a-z]

正则测试工具:http://tool.oschina.net/regex

MDN 文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions

1、边界符 表示位置 开头和结尾 必须用什么开头 什么结尾

^ 表示匹配行首的文本

$ 表示匹配行尾的文本

**[]加上^取反符号 比如[^a-z]**匹配除了小写字母以外的字母

. 匹配除了换行符之外的任何单个字符


        // console.log(/哈/.test('哈哈'))   true
        // console.log(/哈/.test('二哈'))	true
        // ^ 开头
        console.log(/^哈/.test('二哈'))  // false 
        console.log(/^哈/.test('我开心的哈哈大笑'))  // false 
        console.log(/^哈$/.test('我开心的哈哈大笑'))  // false 
        console.log(/^哈$/.test('哈哈'))  // false 
        console.log(/^哈$/.test('哈'))  // true  精确匹配

2、量词 表示重复次数

*重复0次或多次
+重复一次或多次
重复0次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次
  // console.log(/a/.test('a'))
        // // * 量词 n >= 0 
        // console.log(/a*/.test(''))
        // console.log(/a*/.test('a'))
        // console.log(/a*/.test('aa'))
        // console.log(/a*/.test('aaaaaaaa'))
        // console.log(/a*/.test('b'))
        // console.log('--------------------------')
        // // + 量词 n >= 1
        // console.log(/a+/.test(''))  false
        // console.log(/a+/.test('a'))
        // console.log(/a+/.test('aa'))
        // console.log(/a+/.test('aaaaaaaa'))
        // console.log(/a+/.test('b')) false
        // console.log('--------------------------')
        // // ? 出现 0 || 1 
        // console.log(/^a?$/.test(''))
        // console.log(/^a?$/.test('a'))
        // console.log(/^a?$/.test('aa')) false

        // {n}   只能出现 n次   符号之间不要加空格
        console.log(/^a{3}$/.test('aa'))  false
        console.log(/^a{3}$/.test('aaa'))
        console.log(/^a{3}$/.test('aaaa')) false

        // {n,}   >= n 
        console.log(/^a{3,}$/.test('aa'))    false
        console.log(/^a{3,}$/.test('aaa'))
        console.log(/^a{3,}$/.test('aaaa'))
        console.log('--------------------------')
        // {n,m}   >= n  <= m 
        console.log(/^a{3,6}$/.test('aa'))  false 
        console.log(/^a{3,6}$/.test('aaa'))
        console.log(/^a{3,6}$/.test('aaaa'))
        console.log(/^a{3,6}$/.test('aaaaa'))
        console.log(/^a{3,6}$/.test('aaaaaaaa'))  false

3、字符类 \d 表示0-9

[]匹配字符 加上-连字符 表示范围

/[abc]/ 后面的字符串只要包含abc中任意一个字符 都返回true

// console.log(/abc/.test('abc'))
        // console.log(/abc/.test('ab'))
        // 字符类 []
        // console.log(/[abc]/.test('abc'))
        // console.log(/[abc]/.test(''))
        // console.log(/[abc]/.test('andy'))
        // console.log(/[abc]/.test('baby'))
        // console.log(/[abc]/.test('cry'))
        // console.log(/[abc]/.test('die'))

        // 字符类 [-] 连字符
        console.log(/^[abc]$/.test('abc'))
        console.log(/^[abc]$/.test('a'))
        console.log(/^[abc]$/.test('b'))
        console.log(/^[abc]$/.test('c'))
        console.log(/^[abc]$/.test('cc'))

        // 26个英文字母选其中的一个
        console.log(/^[a-zA-Z]$/.test('d'))
        console.log(/^[a-zA-Z]$/.test('D'))
        console.log(/^[a-zA-Z]$/.test('DD'))
        console.log(/^[a-zA-Z0-9]$/.test('6'))
        console.log(/^[a-zA-Z0-9-_]$/.test('6'))

        console.log(/^abc+$/.test('cc'))
        
        ^[1-9][0-9]{4,}$   QQ1000从开始
用户名验证案例
     let input = document.querySelector('input')
        let span = input.nextElementSibling
        input.addEventListener('blur', function () {
            if (/^[a-zA-Z0-9-_]{6,16}$/.test(input.value)) {
                span.className = 'right'
                span.innerHTML = '要输正确'
            } else {
                span.className = 'error'
                span.innerHTML = '只能要输6~16位字符'
            }
        })
\d[0-9]
\D[^0-9]
\w[A-Za-z0-9_]
\W[^A-Za-z0-9_]
\s匹配空格(换行符、制表符、空格符)[\t\r\n\v\f]
\S[^\t\r\n\v\f]

日期格式:^\d{4}-\d{1,2}-\d{1-2}

/表达式/修饰符

i 匹配字母不区分大小写

g 匹配所有满足正则表达式的结果

替换 replace

字符串.replace(/正则表达式/,"替换的文本")
过滤敏感词
  <textarea name="" id="" cols="30" rows="10"></textarea>
    <button>发布</button>
    <div></div>
    <script>
        let btn = document.querySelector('button')
        let textarea = document.querySelector('textarea')
        let div = document.querySelector('div')
        btn.addEventListener('click', function () {
            // 过滤用户输入的内容
            div.innerHTML = textarea.value.replace(/激情|基情/g, '**')

            // div.innerHTML = textarea.value
        })
    </script>

change事件

// input 事件 只要输入就会触发

// change 事件 是 离开表单时候才触发 并且值有变化

// 当表单里面的值发生变化的时候触发,和 blur 不一样

	<input type="text">
    <input type="password">
    <script>
        let input = document.querySelector('input')
        // 当表单里面的值发生变化的时候触发,和 blur 不一样 
        // input 事件  只要输入就会触发
        // change 事件 是 离开表单时候才触发  并且值有变化
        input.addEventListener('change', function () {
            console.log(111)
        })
    </script>

属性选择器

input[type=text] {
            background-color: red;
        }

.test(‘abc’))
// console.log(/abc/.test(‘ab’))
// 字符类 []
// console.log(/[abc]/.test(‘abc’))
// console.log(/[abc]/.test(‘’))
// console.log(/[abc]/.test(‘andy’))
// console.log(/[abc]/.test(‘baby’))
// console.log(/[abc]/.test(‘cry’))
// console.log(/[abc]/.test(‘die’))

    // 字符类 [-] 连字符
    console.log(/^[abc]$/.test('abc'))
    console.log(/^[abc]$/.test('a'))
    console.log(/^[abc]$/.test('b'))
    console.log(/^[abc]$/.test('c'))
    console.log(/^[abc]$/.test('cc'))

    // 26个英文字母选其中的一个
    console.log(/^[a-zA-Z]$/.test('d'))
    console.log(/^[a-zA-Z]$/.test('D'))
    console.log(/^[a-zA-Z]$/.test('DD'))
    console.log(/^[a-zA-Z0-9]$/.test('6'))
    console.log(/^[a-zA-Z0-9-_]$/.test('6'))

    console.log(/^abc+$/.test('cc'))
    
    ^[1-9][0-9]{4,}$   QQ1000从开始

#### 用户名验证案例

 let input = document.querySelector('input')
    let span = input.nextElementSibling
    input.addEventListener('blur', function () {
        if (/^[a-zA-Z0-9-_]{6,16}$/.test(input.value)) {
            span.className = 'right'
            span.innerHTML = '要输正确'
        } else {
            span.className = 'error'
            span.innerHTML = '只能要输6~16位字符'
        }
    })

| \d   | [0-9]                                          |
| ---- | ---------------------------------------------- |
| \D   | [^0-9]                                         |
| \w   | [A-Za-z0-9_]                                   |
| \W   | [^A-Za-z0-9_]                                  |
| \s   | 匹配空格(换行符、制表符、空格符)[\t\r\n\v\f] |
| \S   | [^\t\r\n\v\f]                                  |

日期格式:^\d{4}-\d{1,2}-\d{1-2}

/表达式/修饰符

i 匹配字母不区分大小写

g 匹配所有满足正则表达式的结果

**替换** replace   

字符串.replace(/正则表达式/,“替换的文本”)




#### 过滤敏感词

<button>发布</button>
<div></div>
<script>
    let btn = document.querySelector('button')
    let textarea = document.querySelector('textarea')
    let div = document.querySelector('div')
    btn.addEventListener('click', function () {
        // 过滤用户输入的内容
        div.innerHTML = textarea.value.replace(/激情|基情/g, '**')

        // div.innerHTML = textarea.value
    })
</script>

### change事件

// input 事件  只要输入就会触发

 // change 事件 是 离开表单时候才触发  并且值有变化

// 当表单里面的值发生变化的时候触发,和 blur 不一样

<input type="text">
<input type="password">
<script>
    let input = document.querySelector('input')
    // 当表单里面的值发生变化的时候触发,和 blur 不一样 
    // input 事件  只要输入就会触发
    // change 事件 是 离开表单时候才触发  并且值有变化
    input.addEventListener('change', function () {
        console.log(111)
    })
</script>

### 属性选择器

input[type=text] {
background-color: red;
}



  1. a-z0-9_- ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值