JavaScript DOM BOM操作

视频教程:黑马程序员 pink老师 DOM BOM操作

DOM

什么是DOM

文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML、XML)的标准编程接口。
W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的样式、内容和结构。

DOM树

在这里插入图片描述

  • 文档:一个页面就是一个文档,DOM中就是Document
  • 元素:页面中的所有标签就是元素,DOM中就是element
  • 节点:页面中的所有内容都是节点,包括标签、属性href、文本、注释等,DOM中就是node

获取页面中的element元素

有四种方式:

  1. 根据ID获取 var e1 = document.getElementsById('id name')
    返回的结果是一个元素对象,如<div id="id name">this is element content</div>,我们可以使用console.dir(e1)查看这个对象拥有的属性和方法
  2. 根据标签名获取 var e2 = document.getElementsByTagName('div')
    返回的结果是标签对象的集合(伪数组),如没有符合标签对象,则返回空伪数组
  3. 通过HTML5新增方式获取
1.根据类名获得元素
var b1 = document.getElementsByClassName('ClassName');
2.返回指定选择器的第一个元素 类名加. id名加# 标签不加符号
var b2 = document.querySelector('.ClassName');
3.返回指定选择器的全部元素的伪数组 同上
var b3 = document.querySelectorAll('#IdName');
  1. 特殊元素获取(body, html)
    获取body元素:var bodyEle = document.body;
    获取html元素:var htmlELe = document.documentElement;

PS:可以级联获取元素,即e1.getElementByTagName(‘li’)

事件三要素

  1. 事件源(哪个元素)
  2. 事件类型(什么事件才触发)
  3. 事件处理程序(执行什么)

执行事件的步骤:

  1. 获取事件源
  2. 注册事件(绑定事件)
  3. 添加事件处理程序(采用函数赋值的形式)

例子:实现点击按钮后弹出对话框

1.获取事件源(按钮)
var btn = document.querySelector('button');
2.注册事件 + 函数赋值处理程序
btn.onclick = function() {
	alert("点击按钮了");
}

改变元素内容

element.innerTextelement.innerHTML
前者会替换标签内的全部内容,但是去除html标签、空格和换行。
后者会替换标签内的全部内容,且支持html标签和保留空格、换行。

var ele = document.querySelector('div');
ele.innerText = "替换后的内容";

同理,也可以改变标签的各种属性,src,href,id,alt,title等。

改变元素样式

element.style可以改变元素的样式,并作为行内样式
element.className可以对类名进行修改,直接覆盖原有类名

<div>123</div>
    <script>
        var div = document.querySelector("div");
        div.onclick = function () {
            this.style.backgroundColor = this.style.backgroundColor === "pink" ? "purple" : "pink";
        }
    </script>

常用元素api

element.onfocus获得焦点
element.onblur失去焦点
element.onmouseover鼠标经过
element.onmouseout鼠标离开

获取、修改和删除 元素的属性值

  1. 获取属性值:
  • element.属性 用于获取元素本身自带的属性
  • element.getAttribute('属性名') 用于获取自定义属性
  1. 修改属性值:
  • element.属性 用于修改元素本身自带的属性的值
  • element.setAttribute('属性名', 值) 用于修改自定义属性的值
  1. 获取属性值:
  • element.removeAttribute('属性名') 用于删除元素的属性
H5新增方式

H5规定自定义属性需以data-开头
例如:<div data-index="2"></div>
同时也新增了一个获取自定义属性的方式:

<div data-index="2"></div>
---
var ele = document.querySelector("div");
ele.dataset.index // 2
ele.dataset['index'] // 2

节点操作

网页中的所有内容都是节点(标签、属性、文本、注释和空格换行等),在DOM中,节点使用node表示。

节点至少有三个属性:nodeType、nodeName、nodeValue

节点分为三类:

  • 元素节点 nodeType=1
  • 属性节点 nodeType=2
  • 文本节点 nodeType=3 (包含文字、空格和换行)

利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系。

父级节点

node.parentNode 返回node节点的父节点,且仅返回最近的一个父节点,如无父节点,则返回null

子级节点
查找子节点
  1. 标准方式:node.childNodes 返回node节点的子节点的集合,包括元素节点、文本节点等。
  2. 非标准方式:node.children 是一个只读的属性,返回node节点的所有子元素节点,它只返回元素节点,不返回其他类型节点。
查找首末子节点
  1. 标准方式:
    node.firstChild 返回第一个子节点(所有类型节点),没有则null
    node.lastChild 返回最后一个子节点(所有类型节点)

  2. IE9以上支持的方法:
    node.firstElementChild 返回第一个元素节点,找不到则返回null
    node.lastElementChild 返回最后一个元素节点

兄弟节点
查找兄弟节点
  1. 标准方式:
    node.nextSibling 返回node节点的下一个兄弟节点,包括元素节点、文本节点等,找不到则返回null。
    node.previousSibling 返回node节点的上一个兄弟节点,包括元素节点、文本节点等,找不到则返回null。
  2. 非标准方式(只兼容IE9以上):
    node.nextElementSibling 返回node节点的下一个兄弟节点,仅元素节点,找不到则返回null。
    node.previousElementSibling 返回node节点的上一个兄弟节点,仅元素节点,找不到则返回null。
创建节点
方法一

想要在页面中添加一个节点,需要有两步:1 创建节点,2 添加节点至指定位置

var child = document.createElement('tagName')
创建由tagName指定的标签元素,这一步骤可称为动态创建元素节点

node.appendChild(child)
将一个节点添加到指定父节点下的子节点列表的末尾,类似于CSS中after伪元素

node.insertBefore(child, 指定节点) 指定节点常见写法:node.children[0]
将一个节点添加到指定父节点(node)下指定节点的前面,类似于CSS中before伪元素

方法二

element.innerHTML = '<a>123</a>' 直接对元素内部进行文本的书写

方法三

document.write() 是直接将内容写入页面的内容流,但是当文档流执行完毕后进行这一操作,就会导致页面全部重绘(即原先元素消失,仅存在新写的内容)

方法一与方法二对比

innerHTML创建大量元素的效率更高,注意不能使用循环字符串拼接方式,要用数组集合再join的方式,实现结构相对复杂
createElement() + appendChild()/insertBefore()的效率相对低一点点,但是结构清晰,实现简单。

总结:innerHTML在创建大量元素时效率比createElement

删除节点

node.removeChild(child) 删除一个node下的子节点,返回删除的节点
例:

var el = document.querySelector('ul');
el.removeChild(el.children[0]);	//删除ul中的第一个元素节点
复制节点(克隆)

node.cloneNode() 返回node节点的一个副本
括号参数为空或false,则是浅拷贝,只复制节点本身,不复制里面的子节点;
括号参数为 true,则是深拷贝,会复制节点本身及其里面的所有子节点。

事件高级

注册事件

给元素添加事件,称为注册事件绑定事件
注册事件有两种方式,传统方式和方法监听注册方式。

在这里插入图片描述

addEventListener事件监听方式

使用方法:eventTarget.addEventListener(type, listener[, useCapture])

该方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
该方法接收3个参数:

  1. type:事件类型字符串,如 click, mouseover等,此时不带on
  2. listener:事件处理函数,事件发生时会调用该函数
  3. useCapture:可选参数,是一个布尔值,默认为false,为true时是在事件捕获阶段调用事件处理函数,为false或省略时是事件冒泡阶段调用事件处理函数

例:

var el = document.querySelector('button');
el.addEventListener('click', function() {
	alert('按下了按钮');
})

仅IE9及以后支持该方法

attachEvent事件监听方式

该方法不常用,当需要支持IE8及之前版本浏览器时,使用element.onclick = function() {}更方便。
在这里插入图片描述

删除事件

传统注册方式

eventTarget.onclick = null;

方法监听注册方式

IE9及以上:eventTarget.removeEventListener(type, listener[, useCapture]);
例:

var el = document.querySelector('button');
el.addEventListener('click', fn)

function fn() {
	alert('按下了按钮');
	// 第二次开始不执行
	el.removeEventListener('click', fn)
}

IE8及以下:eventTarget.detachEvent(eventNameWithOn, callback)

DOM事件流

事件流描述的是从页面中接收事件的顺序。

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程就是DOM事件流

在这里插入图片描述

<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        // dom 事件流 三个阶段
        // 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
        // 2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。
        // 3. 捕获阶段 如果addEventListener 第三个参数是 true 那么则处于捕获阶段  document -> html -> body -> father -> son
        var son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, true);
        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, true);
        
        // 4. 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段  son -> father ->body -> html -> document
        var son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, false);
        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, false);
    </script>
</body>

上述例子中,在捕获阶段,点击内部元素son盒子,会先触发最外部father的点击事件,再触发内部son的点击事件;
在冒泡阶段,点击内部元素son盒子,会先触发最内部son的点击事件,再触发外部father的点击事件。

注意事项:

  • JS代码中只能执行捕获或冒泡二选一,一个阶段
  • 使用attachEvent + onclick,只能得到冒泡阶段
  • 实际开发中事件冒泡更为常用
  • 有些事件没有冒泡过程,如:onblur, onfocus, onmouseenter, onmouseleave

事件对象

事件对象就是事件发生时的各种状态集合,代表着事件的状态
简单理解就是:事件发生后,和事件相关的一系列信息数据的集合都放在这个对象里面,这个对象就是事件对象event,它有很多属性和方法。

使用方法
eventTarget.onclick = function (event) {
	// 此时的event就是事件对象,还可以简写为e
}

eventTarget.addEventListener('click', function (e) {
	// 此时的e就是事件对象,等价于event
})

event 是形参,系统帮我们设定为事件对象,不需要传递实参过去,当我们注册事件时,event 对象会由系统自动创建,并依次传递给事件监听器(事件处理函数)。

兼容性方法

在IE6~IE8中,不兼容上述的event事件对象,需要通过在window.event中获取。
解决方案:
e = e || window.event

事件对象常用属性及方法

在这里插入图片描述

target

e.target 属性,返回的是触发事件的对象(元素),而在事件处理函数中的this则是该事件所绑定的对象(元素)。

<body>
    <div>123</div>
    <ul>
        <li>abc</li>
        <li>abc</li>
        <li>abc</li>
    </ul>
    <script>
        // 常见事件对象的属性和方法
        // 1. e.target 返回的是触发事件的对象(元素)  this 返回的是绑定事件的对象(元素)
        // 区别 : e.target 点击了那个元素,就返回那个元素 this 那个元素绑定了这个点击事件,那么就返回谁
        var div = document.querySelector('div');
        div.addEventListener('click', function(e) {
            console.log(e.target);
            console.log(this);

        })
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
                // 我们给ul 绑定了事件  那么this 就指向ul  
                console.log(this);
                console.log(e.currentTarget);

                // e.target 指向我们点击的那个对象 谁触发了这个事件 我们点击的是li e.target 指向的就是li
                console.log(e.target);

            })
            // 了解兼容性
            // div.onclick = function(e) {
            //     e = e || window.event;
            //     var target = e.target || e.srcElement;
            //     console.log(target);

        // }
        // 2. 了解 跟 this 有个非常相似的属性 currentTarget  ie678不认识
    </script>
</body>
阻止默认行为 e.preventDefault()
<body>
    <div>123</div>
    <a href="http://www.baidu.com">百度</a>
    <form action="http://www.baidu.com">
        <input type="submit" value="提交" name="sub">
    </form>
    <script>
        // 常见事件对象的属性和方法
        // 1. 返回事件类型
        var div = document.querySelector('div');
        div.addEventListener('click', fn);
        div.addEventListener('mouseover', fn);
        div.addEventListener('mouseout', fn);

        function fn(e) {
            console.log(e.type);

        }
        // 2. 阻止默认行为(事件) 让链接不跳转 或者让提交按钮不提交
        var a = document.querySelector('a');
        a.addEventListener('click', function(e) {
                e.preventDefault(); //  dom 标准写法
            })
            // 3. 传统的注册方式
        a.onclick = function(e) {
            // 普通浏览器 e.preventDefault();  方法
            // e.preventDefault();
            // 低版本浏览器 ie678  returnValue  属性
            // e.returnValue;
            // 我们可以利用return false 也能阻止默认行为 没有兼容性问题 特点: return 后面的代码不执行了, 而且只限于传统的注册方式
            return false;
            alert(11);
        }
    </script>
</body>
阻止事件冒泡

共两种方式:

  • 标准写法:e.stopPropagation()
  • 非标准写法(兼容ie6,7,8):e.cancelBubble = true or window.event.cancelBubble = true
// 常见事件对象的属性和方法
// 阻止冒泡  dom 推荐的标准 stopPropagation() 
var son = document.querySelector('.son');
son.addEventListener('click', function(e) {
    alert('son');
    e.stopPropagation(); // stop 停止  Propagation 传播
    e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
}, false);
事件委托(代理、委派)

在这里插入图片描述
事件委托,在jQuery中被称为事件委派。

实现原理:不在每个子节点(li)上分别设置事件监听器,而在父节点(ul)上设置一个事件监听器,利用冒泡原理,每次点击子节点都会结果冒泡行为而触发父节点的事件。

作用:减少了我们对DOM的操作次数,提高代码的性能。

例子:对上述例子实现功能,点击每个小li则改变该li的背景颜色

<body>
    <ul>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
    </ul>
    <script>
        // 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
            // alert('知否知否,点我应有弹框在手!');
            // e.target 这个可以得到我们点击的对象
            // 每次触发ul的事件后,通过e.target得到当前li,再修改其背景颜色
            e.target.style.backgroundColor = 'pink';
        })
    </script>
</body>
常用的鼠标事件

在这里插入图片描述

  1. 禁止鼠标右键菜单
document.addEventListener('contextmenu', function (e) {
	e.preventDefault();	
})
  1. 禁止鼠标选中(文字等)
document.addEventListener('selectstart', function (e) {
	e.preventDefault();	
})
  1. 获取鼠标坐标(三种坐标)
// 鼠标事件对象 MouseEvent
document.addEventListener('click', function(e) {
    // 1. client 鼠标在可视区的x和y坐标
    console.log(e.clientX);
    console.log(e.clientY);
    console.log('---------------------');

    // 2. page 鼠标在页面文档的x和y坐标
    console.log(e.pageX);
    console.log(e.pageY);
    console.log('---------------------');

    // 3. screen 鼠标在电脑屏幕的x和y坐标
    console.log(e.screenX);
    console.log(e.screenY);
})
常用的键盘事件

在这里插入图片描述

注意

  1. 如果使用addEventListener,不需要加on
  2. onleypress不能识别功能键
  3. 假设三个事件都绑定在一个元素上,执行顺序是keydown - keypress - keyup

同样的,键盘事件处理函数中的event就是键盘事件对象,包含属性有按键的值,ASCII码等。

keyup和keydown不区分字母大小写,keypress可以区分大小写(即ASCII码是否区分)
前两者可以区分所有的键盘按键(包含功能键等),而后者keypress不识别功能键,但是keyCode能区分大小写。

BOM

BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window

BOM由一系列相关的对象构成,并且每个对象都提供了很多方法和属性。

BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C,而BOM最初是NetScape网景公司浏览器标准的一部分。

在这里插入图片描述

BOM的构成:
在这里插入图片描述
window对象是浏览器的顶级对象,它具有双重角色:

  1. 它是JS访问浏览器窗口的一个接口
  2. 它是一个全局对象,定义在全局作用域中的变量、函数都会变成window对象的属性和方法
    在调用window的属性和方法时可以省略window,如alert()prompt()都是window的方法。

注意:window有一个特殊的属性:window.name,它的值为空字符串""

window对象的常见事件

窗口加载事件

传统注册方法:window.onload = function () {}
监听事件方法:window.addEventListener('load', function() {})

window.onload是窗口(页面)加载事件,当文档内容完全加载完成后就会触发该事件(包括图像、css、脚本文件等)。

注意

  1. 使用窗口加载事件后,就可以将onload事件处理函数的JS代码写到HTML元素的前面位置,因为onload中的JS代码会在文档全部加载后才执行
  2. window.onload的传统注册方式只可注册一次,如果注册多个则以最后一个为准
  3. 使用addEventListener()可无限制注册

额外方法
document.addEventListener('DOMContentLoaded', function () {})
与上面两种方法不同,该事件仅当DOM加载完成后就会触发,不需要等待CSS、图片、flash等加载完成。

IE9及以上支持该方法

使用环境:
如果页面的图片较多,那么用前两种方法的话触发事件就会比较慢,需要等图片加载完成,而使用第三种方法就可以在页面基本元素加载完后就触发事件。

调整窗口大小事件

传统注册方法:window.onresize = function () {}
监听事件方法:window.addEventListener('resize', function() {})

当浏览器窗口被调整时,就会触发该事件。

window.innerWidth:当前屏幕的宽度

我们可以利用这个方法来完成响应式布局(根据屏幕大小来调整页面布局)。

定时器

window对象共提供了两种定时器方法:
1: setTimeout()
2: setInterval()

setTimeout()定时器

window.setTimeout(调用function, [延迟毫秒数]);
该方法用于设置一个定时器,在定时器到期后执行调用函数。

注意

  1. window可以省略
  2. 调用函数可以直接定义匿名函数,或填写函数名及采用字符串形式
setTimeout(function () {...}, 2000);
setTimeout(fn, 2000);
setTimeout('fn()', 2000);
  1. 定时器延迟的毫秒数可以不填,默认为0
  2. 这个调用函数也可以称为回调函数,前文讲的element,onclick = function() {}这里的函数也是回调函数

停止定时器
window.clearTimeout(定时器名字)
用于取消指定的定时器。

var timer = setTimeout(function () {...}, 2000);
clearTimeout(timer);
setInterval()定时器

功能和用法与setTimeout()几乎一致,只是它的定时是每隔指定时间就执行一次回调函数,即循环定时
在这里插入图片描述
停止定时器
window.clearInterval(定时器名字)
用于取消指定的定时器。

var timer = setInterval(function () {...}, 2000);
clearInterval(timer);

this的指向

// this 指向问题 一般情况下this的最终指向的是那个调用它的对象

// 1. 全局作用域或者普通函数中this指向全局对象window( 注意定时器里面的this指向window)
console.log(this);

function fn() {
    console.log(this);

}
window.fn();
window.setTimeout(function() {
    console.log(this);

}, 1000);
// 2. 方法调用中谁调用this指向谁
var o = {
    sayHi: function() {
        console.log(this); // this指向的是 o 这个对象

    }
}
o.sayHi();

var btn = document.querySelector('button');
// btn.onclick = function() {
//     console.log(this); // this指向的是btn这个按钮对象

// }
btn.addEventListener('click', function() {
        console.log(this); // this指向的是btn这个按钮对象

    })
    
// 3. 构造函数中this指向构造函数的实例
function Fun() {
    console.log(this); // this 指向的是fun 实例对象

}
var fun = new Fun();

JavaScript执行机制

JavaScript是单线程的,为了解决单线程导致的页面渲染加载阻塞问题,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,于是就有了同步异步

同步和异步

同步任务:
同步任务都在主线程上执行,形成一个执行栈。

异步任务:
JS的异步是通过回调函数实现的,一般而言异步任务有以下三种类型:

  1. 普通事件,如click、resize等
  2. 资源加载,如load、error等
  3. 定时器,包括setTimeout、setInterval等

异步任务的相关回调函数会添加到任务队列中(消息队列)。

执行机制
  1. 先执行执行栈中的同步任务,从上到下按序执行
  2. 将异步任务(回调函数)放入任务队列
  3. 当执行栈中的任务都完成后,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈开始执行
    在这里插入图片描述
    由于主线程不断地重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)

在这里插入图片描述

location对象

什么是location对象

window对象向我们提供了一个location属性,用于获取或设置窗体的URL,并且可以解析URL,因为这个属性返回的值是对象类型,因此也叫location属性为location对象

URL 统一资源定位符

**统一资源定位符(Uniform Resource Locator)**是互联网标准资源的地址,互联网上每个文件(资源)都有其唯一的URL,它包含的信息指出了文件的位置以及告诉浏览器应该如何处理它。

URL的一般格式为:

protocol://host[:port]/path/[?query]#fragment
https://editor.csdn.net/md?articleId=113779983

在这里插入图片描述

location对象的属性

在这里插入图片描述

location对象的常见方法

在这里插入图片描述

navigator 对象

navigator对象包含有关浏览器的信息,最常用的属性是userAgent,该属性返回由客户机发送给服务器的user-agent头部的值。

以下代码可以实现:判断用户是手机端还是电脑端打开页面,并实现跳转。

if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
    window.location.href = "m.jd.com";     //手机
 } else {
    window.location.href = "jd.com";     //电脑
 }

history 对象

window对象给我们提供了一个history对象,用于喝浏览器的历史记录进行交互,该对象包含用户在当前窗口中访问过的url。
在这里插入图片描述

PC端网页特效

元素偏移量 offset

offset就是偏移量,通过它的相关属性可以动态的得到元素的位置、大小等。

  • 获得元素距离带有定位的父元素的偏移量
  • 获得元素自身的大小(width、height)
  • 返回的数值是不包括单位的

在这里插入图片描述

offset系列常用属性:
在这里插入图片描述
offset与style的区别:
在这里插入图片描述

元素可视区 client

使用client的相关属性来获取元素可视区域的相关信息,包括元素大小、边框大小等。
在这里插入图片描述
在这里插入图片描述

立即执行函数

(function() {})()(function() {}())
主要作用:创建一个独立的作用域,避免了不同js文件同时使用时的命名冲突问题。

元素滚动 scroll

使用scroll的相关属性可以动态获得元素的大小、滚动距离等。
在这里插入图片描述
在这里插入图片描述
如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发 onscroll 事件。

三个系列总结

在这里插入图片描述
他们的主要用法区别:

  1. offset系列 经常用于获得元素位置 offsetLeft offsetTop
  2. client 经常用于获取元素大小 clientWidth clientHeight
  3. scroll 经常用于获取滚动距离 scrollTop scrollLeft
  4. 注意页面滚动的距离通过 window.pageXOffset 获得

mouseenter和mouseover的区别

mouseenter鼠标事件:

  • 当鼠标移动到元素上时就会触发 mouseenter 事件
  • 类似 mouseover,它们两者之间的差别是:
    • mouseover 鼠标经过自身盒子会触发,经过子元素盒子还会触发。 mouseenter 只会经过自身盒子触发
    • 之所以这样,是因为mouseenter不会冒泡,而mouseover会冒泡,触发子盒子后冒泡触发自身盒子
  • 跟mouseenter搭配 鼠标离开 mouseleave 同样不会冒泡

动画

实现原理

通过定时器setInterval()不断移动盒子的位置。

实现步骤:

  1. 获得盒子的当前位置
  2. 让盒子在当前位置上加上一个要移动的距离
  3. 利用定时器不断重复 1,2步骤
  4. 设置一个结束定时器的条件
  5. 移动距离element.style.left,需要该元素position: absolute定位
缓动效果原理

缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来。

实现思路:

  1. 让盒子每次移动的距离慢慢变小,这样速度就会慢慢落下来
  2. 核心算法:(目标位置 - 现在位置) / 10 = 每次移动的步长
  3. 停止条件:当前盒子位置 = 目标位置就停止定时器
  4. 当步长为正数时,需要向上取整;步长值为负数时,需要向下取整,不然会到达不了目标位置
回调函数

原理:函数可以作为一个参数,将这个函数作为参数传到另一个函数中,当那个函数执行完成后,再执行传进去的这个函数,整个过程就叫做回调

简单动画实现的样例:

function animate(obj, target, callback) {
    // console.log(callback);  callback = function() {}  调用的时候 callback()

    // 先清除以前的定时器,只保留当前的一个定时器执行
    clearInterval(obj.timer);
    obj.timer = setInterval(function() {
        // 步长值写到定时器的里面
        // 把我们步长值改为整数 不要出现小数的问题
        // var step = Math.ceil((target - obj.offsetLeft) / 10);
        var step = (target - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (obj.offsetLeft == target) {
            // 停止动画 本质是停止定时器
            clearInterval(obj.timer);
            // 回调函数写到定时器结束里面
            // if (callback) {
            //     // 调用函数
            //     callback();
            // }
            callback && callback();
        }
        // 把每次加1 这个步长值改为一个慢慢变小的值  步长公式:(目标值 - 现在的位置) / 10
        obj.style.left = obj.offsetLeft + step + 'px';

    }, 15);
}

移动端网页特效

触屏事件

touch对象代表一个触摸点。触屏事件可响应用户手指(或触控笔)对屏幕的操作。

常见的触屏事件:
在这里插入图片描述

触摸事件对象(TouchEvent)

TouchEvent是一类描述手指在触摸平面的状态变化的事件,可以用于描述一个或多个触点。

touchstart、touchmove、touchend三个事件有各自的事件对象。

常见触摸事件对象的属性:
在这里插入图片描述

移动端拖动元素

  1. touchstart、touchmove、touchend 可以实现拖动元素
  2. 但是拖动元素需要当前手指的坐标值 我们可以使用 targetTouches[0] 里面的pageX 和 pageY
  3. 移动端拖动的原理: 手指移动中,计算出手指移动的距离。然后用盒子原来的位置 + 手指移动的距离
  4. 手指移动的距离: 手指滑动中的位置 减去 手指刚开始触摸的位置

拖动元素三步曲:
(1) 触摸元素 touchstart: 获取手指初始坐标,同时获得盒子原来的位置
(2) 移动手指 touchmove: 计算手指的滑动距离,并且移动盒子
(3) 离开手指 touchend: 无需事件操作

注意: 手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动 e.preventDefault();

classList属性

classList属性是HTML5新增的属性,可以返回元素的类名数组,仅ie10以上版本支持

该属性一般用于在元素中添加、移除及切换CSS类。

该属性有以下方法:

  1. 添加类名:
    element.classList.add('className')
  2. 移除类名:
    element.classList.remove('className')
  3. 切换类:
    element.classList.toggle('className')

本地存储

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。

本地存储具有的特性:

  1. 数据存储在用户浏览器中
  2. 设置、读取方便、甚至页面刷新不丢失数据
  3. 容量较大,sessionStorage约5M、localStorage约20M
  4. 只能存储字符串,可以将对象JSON.stringify() 编码后存储

sessionStorage

sessiongStorage的三大特点:

  1. 生命周期为 当前浏览器窗口(标签页),关闭就结束
  2. 在当前页面(标签页)下可以使用数据
  3. 以键值对的形式存储使用

共有四个方法:

  1. 存储数据 sessionStorage.setItem(key, value)
  2. 获取数据 sessionStorage.getItem(key)
  3. 删除数据 sessionStorage.removeItem(key)
  4. 删除全部数据 sessionStorage.clear()

示例:

<body>
    <input type="text">
    <button class="set">存储数据</button>
    <button class="get">获取数据</button>
    <button class="remove">删除数据</button>
    <button class="del">清空所有数据</button>
    <script>
        console.log(localStorage.getItem('username'));

        var ipt = document.querySelector('input');
        var set = document.querySelector('.set');
        var get = document.querySelector('.get');
        var remove = document.querySelector('.remove');
        var del = document.querySelector('.del');
        set.addEventListener('click', function() {
            // 当我们点击了之后,就可以把表单里面的值存储起来
            var val = ipt.value;
            sessionStorage.setItem('uname', val);
            sessionStorage.setItem('pwd', val);
        });
        get.addEventListener('click', function() {
            // 当我们点击了之后,就可以把表单里面的值获取过来
            console.log(sessionStorage.getItem('uname'));

        });
        remove.addEventListener('click', function() {
            // 点击后,清楚指定key的数据
            sessionStorage.removeItem('uname');

        });
        del.addEventListener('click', function() {
            // 当我们点击了之后,清除所有的数据
            sessionStorage.clear();

        });
    </script>
</body>

localStorage

localStorage的三大特点:

  1. 生命周期为永久生效,关闭浏览器页面后也仍存在,除非手动删除
  2. 同一浏览器下,可以多窗口共享数据
  3. 以键值对的形式存储使用

它的使用方法和sessionStorage类似,共有四个方法:

  1. 存储数据 localStorage.setItem(key, value)
  2. 获取数据 localStorage.getItem(key)
  3. 删除数据 localStorage.removeItem(key)
  4. 删除全部数据 localStorage.clear()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值