DOM模型
DOM:文档对象模型( Document Object Model ),它的作用是将网页转为一个 js
对象
节点 Node
DOM
的最小组成单位叫做节点
节点的类型有七种:
Document
:整个文档节点(包含整个节点树)DocumentType
:文档声明类型<!DOCTYPE html>
Element
:元素节点,网页的各种HTML标签(<body>
、div
、img
等等)Attribute
:网页元素的属性(比如class="right"
)Text
:标签之间或标签包含的文本Comment
:注释DocumentFragment
:文档的片段
根节点
document
根节点,文档的第一层只有一个节点
节点的关系
除了根节点,其他节点都有三种层级关系。
- 父节点关系
<!-- button的直接父节点是div -->
<div>
<button>按钮</button>
</div>
- 子节点关系
<!-- div的直接子节点是button -->
<div>
<button>按钮</button>
</div>
- 同级节点关系
<!-- button的同级节点是h2 -->
<div>
<button>按钮</button>
<h2>标题2</h2>
</div>
Node 接口的属性
所有 DOM
节点都继承了 Node
接口
Node.nodeType
:
返回一个整数值,表示节点的类型,有以下类型:
- document:9 表示 文档
- element: 1 表示 元素
- attr: 2 表示 属性
- text: 3 表示 文本
- DocumentFragment: 11 表示 文档片段
- DocumentType: 10 表示 文档类型
- Comment: 8 表示 注释
<div id="box">你好</div>
<script>
var box = document.getElementById('box');
console.log( box.nodeType ); //1 元素
console.log( box.childNodes[0].nodeType );//3 文本
</script>
Node.nodeName
:
<div id="box">你好</div>
<script>
var box = document.getElementById('box');
console.log( box.nodeName ); //DIV 默认是大写
console.log( box.childNodes[0].nodeName );//#text
</script>
Node.nodeValue
:
nodeValue
属性返回一个字符串,表示当前节点本身的文本值
注意:该属性主要用于文本节点
var box = document.getElementById('box');
console.log( box.nodeValue );//null
console.log( box.childNodes[0].nodeValue );//您好
Node.textContent
:
textContent
属性返回当前节点和它的所有后代节点的文本内容。
自动忽略当前节点内部的HTML标签,提取文本内容,它和innerText功能一样
该属性可读可写
<div id="box">
您好
<p>
张三
</p>
</div>
<script>
var box = document.getElementById('box');
console.log( box.textContent );// 您好 张三
</script>
Node.baseURI
:
返回一个字符串,表示当前网页的绝对路径
会受<base href="#">
基础地址影响,而location.href
不会。
console.log( document.baseURI );
//file:///F:/studyspace/web1905/javascript/dom.html
console.log( window.location.href );
//file:///F:/studyspace/web1905/javascript/dom.html
Node.ownerDocument
:
返回当前节点所在的顶层文档对象,即document
对象。
<div id="box">
</div>
<script>
var box = document.getElementById('box');
console.log( box.ownerDocument == document );//true
</script>
节点关系查找
父节点关系
-
Node.childNodes
:父节点下所有的子节点,注意包含文本、注释、元素节点
-
Node.children
:父节点下所有的子元素节点,只是元素节点
<ul id="box">
<li>一分</li>
<li>二分</li>
<li>三分</li>
<li>四分</li>
<li>五分</li>
</ul>
<script>
var box = document.getElementById('box');
var lis1 = box.childNodes;
var lis2 = box.children;
console.log( lis1, lis2);
</script>
子节点关系
-
parentNode
:当前节点的直接的父节点
-
parentElement
:当前节点的直接的父元素节点
<div>
<span>
<button id="btn">按钮</button>
</span>
</div>
<script>
document.getElementById('btn').onclick = function(){
var THIS = this;
while( THIS.parentElement ){
THIS = THIS.parentElement;
if(THIS.nodeName == 'BODY'){
THIS.style.backgroundColor='red';
}
}
}
</script>
同级节点关系
-
Node.nextSibling
:下一个节点,注意包含文本、注释、元素节点
-
Node.nextElementSibling
:下一个元素节点,只是元素节点。
<button onclick="setBox(this)">按钮</button>
<div></div>
<script>
//单击按钮,给div设置宽200 高200 背景颜色红色
function setBox( btn ){
btn.nextElementSibling.style.cssText = `width:200px;height:200px;background-color:red`;
}
</script>
-
Node.previousSibling
:上一个节点,注意包含文本、注释、元素节点
-
Node.previousElementSibling
:上一个元素节点,只是元素节点。
综合的例子
<ul>
<li>一分</li>
<li>二分</li>
<li>三分</li>
<li>四分</li>
<li>五分</li>
</ul>
<script>
var lis = document.querySelectorAll('li');
lis.forEach( function( item ){
item.onclick = function(){
var THIS1 = this;
var THIS2 = this;
//查找当前元素往上的所有元素
while( THIS1.previousElementSibling ){
THIS1 = THIS1.previousElementSibling;
THIS1.className = 'active'
}
//查找当前元素往下的所有元素
while( THIS2.nextElementSibling ){
THIS2 = THIS2.nextElementSibling;
THIS2.className = 'active'
}
}
})
</script>
经典面试题:请用至少3种办法生成一个随机不重复的字符串
// 方法1
var id = new Date().getTime();
console.log( id );
// 方法2
var str = Math.random().toString(36).slice(2);
console.log(str);
// 方法3
var str = 'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKMNOPQRSTUVWXYZ0123456789';
var arr = str.split('');
var newArr = arr.sort(function(){
return .5 - Math.random();
}).slice(0,20);
console.log( newArr.join('') );
// 方法4
var str = 'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKMNOPQRSTUVWXYZ0123456789';
var arr = str.split('');
var temp = '';
for(var i=0;i<arr.length;i++){
var index = Math.floor(Math.random()*arr.length);
temp += arr[index];
}
console.log( temp );
Node.isConnected
返回一个布尔值,表示当前节点是否在文档之中
<div id="box1"></div>
<script>
//文档本身就存在
var box1 = document.getElementById('box');
console.log( box1.isConnected );//true
//创建了元素,但是并没有插入到文档中
var box2 = document.createElement('div');
console.log( box2.isConnected );//false
</script>
Node 接口的方法
document.createElement
在文档中创建一个元素
语法:
document.createElement('标签名');
示例
var div = document.createElement('div');
console.log( div );//<div></div>
综合示例
//1. 创建一个div元素
var div = document.createElement('div');
//2. 创建一个属性节点
var cls = document.createAttribute('class');
//3. 设置属性节点的值
cls.value = 'red';
//4. 把属性节点应用到目标元素上
div.setAttributeNode( cls );
//5. 创建注释
var zs = document.createComment('新的div');
//6. 将上面的注释添加到div的内部后面
div.appendChild( zs );
//7. 创建一个p标签
var p = document.createElement('p');
//8. 创建一个文本标签
var text = document.createTextNode('今天的天气有点阴沉!');
//9. 将文本节点追加到p标签内部的后面
p.appendChild( text );
//10. 将上面的p标签追加到div内部后面
div.appendChild( p );
//11. 输出新创建的节点
console.log( div );
使用JS标准API创建节点示例
<script>
var data = [
{id:1,name:'首页',url:'#'},
{id:2,name:'关于我们',url:'#', active: true},
{id:3,name:'联系我们',url:'#'},
];
var div = document.createElement('div');
var divClass = document.createAttribute('class');
divClass.value = 'nav';
var divStyle = document.createAttribute('style');
divStyle.value = 'width:100px;';
div.setAttributeNode( divClass );
div.setAttributeNode( divStyle );
var ul = document.createElement('ul');
for(var i=0;i<data.length;i++){
var li = document.createElement('li');
var a = document.createElement('a');
var aHref = document.createAttribute('href');
aHref.value = data[i].url;
a.setAttributeNode( aHref );
if( data[i].active ){
var aClass = document.createAttribute('class');
aClass.value = 'active';
a.setAttributeNode( aClass );
}
var text = document.createTextNode( data[i].name );
a.appendChild( text );
li.appendChild( a );
ul.appendChild( li );
}
div.appendChild( ul );
document.getElementsByTagName('body')[0].appendChild( div );
</script>
示例
<button onclick="createBox()">创建盒子并附加样式</button>
<script>
function createBox(){
var div = document.createElement('div');
// var divClass = document.createAttribute('class');
// divClass.value ='box';
// div.setAttributeNode( divClass );
//等同于上面的写法
div.className = 'box';
// var text = document.createTextNode('段落');
// div.appendChild( text );
//等同于上面的写法
div.innerText = '段落';
var style = document.createElement('style');
style.innerHTML = `
.box{
width: 100px;
height: 100px;
background-color: red;
}`;
document.getElementsByTagName('head')[0].appendChild( style );
document.getElementsByTagName('body')[0].appendChild( div );
}
</script>
页码示例
<div id="box1"></div>
<div id="box2"></div>
<script>
makePage( 'box1', 10, 1 );
makePage( 'box2', 5, 2 );
function makePage( id, totalPage, page=1 ){
var target = document.getElementById( id );
target.innerHTML = '';
for(let p=1;p<=totalPage;p++){
var btn = document.createElement('button');
btn.innerText = p;
if(p==page){
btn.className = 'active';
}
//因为创建的是dom对象,该对象尚未插入到文档中,所以这里可以直接加上事件
btn.onclick = function(){
// console.log( p );
makePage( id, totalPage, p );
}
target.appendChild( btn );
}
}
</script>
Node.appendChild
往目标节点内部的后面插入新节点,返回被插入的新节点
var div = document.createElement('div');
div.innerText = '内容';
var text = document.createTextNode('段落');
div.appendChild( text );
console.log( div );// <div>内容段落</div>
穿梭框效果
<style>
ul{
float: left;
list-style: none;
margin: 0;
padding: 0;
overflow: auto;
height: 200px;
width: 160px;
border: 1px solid #ccc;
margin-right: 20px;
}
.btns{
float: left;
padding-top: 22px;
width: 100px;
}
.btns button{
margin-bottom: 20px;
}
ul li{
line-height: 30px;
font-size: 14px;
padding: 0 10px;
cursor: pointer;
}
ul li:nth-child(even){
background-color: #eee;
}
ul li.active{
background-color: rgb(2, 141, 255);
color: white;
}
</style>
<h1>穿梭框效果</h1>
<ul id="left">
<li>陈旻</li>
<li>李杰</li>
<li>曾崇博</li>
<li>邓聪</li>
<li>钟旺</li>
<li>邓绍志</li>
<li>刘江湖</li>
<li>代晨</li>
</ul>
<div class="btns">
<button onclick="addRightAll()"> 全部追加 </button>
<button onclick="addRight()"> 向右添加 </button>
<button onclick="addLeft()"> 向左添加 </button>
<button onclick="addLeftAll()"> 全部移除 </button>
</div>
<ul id="right">
</ul>
<button onclick="getVal()">取值</button>
<script>
var left = document.getElementById('left');
var leftLis = left.children;
var right = document.getElementById('right');
var rightLis = right.children;
//添加单击选中事件
for(var i=0;i<leftLis.length;i++){
leftLis[i].onclick = function(){
this.classList.toggle('active');
}
}
//向右追加全部
function addRightAll(){
addItem( right, leftLis, 'all' );
}
//向左移除全部
function addLeftAll(){
addItem( left, rightLis, 'all' );
}
//向右追加
function addRight(){
addItem( right, leftLis );
}
//向左追加
function addLeft(){
addItem( left, rightLis );
}
//追加li元素
function addItem( target, lis, flag ){
//倒着删除
for( var i = lis.length-1; i >= 0 ; i-- ){
if( lis[i].classList.contains('active') || flag == 'all' ){
lis[i].classList.remove('active');
target.appendChild( lis[i] );
}
}
}
//取值
function getVal(){
var val = '';
for( var i=0; i < rightLis.length; i++ ){
val += rightLis[i].innerText+',';
}
val = val.slice(0, -1);
alert( val );
}
</script>
代码片段
<div id="box">
</div>
<button onclick="add()">添加</button>
<script>
var box = document.getElementById('box');
function add(){
var p = document.createElement('p');
var span = document.createElement('span');
var a = document.createElement('a');
//创建一个代码片段节点,代码片段节点没有名称
var fragment = document.createDocumentFragment();
fragment.appendChild( p );
fragment.appendChild( span );
fragment.appendChild( a );
box.appendChild( fragment );
}
</script>
Node.hasChildNodes
:
注意:节点包含7种类型
<div id="box">
</div>
<script>
var box = document.getElementById('box');
console.log( box.hasChildNodes() );//true 因为包含文本节点
</script>
Node.cloneNode
:
用于克隆一个节点。它接受一个布尔值作为参数,表示是否同时克隆子节点。它的返回值是一个克隆出来的新节点。
注意事项:
- 克隆一个节点,会拷贝该节点的所有属性,但是会丧失事件方法
- 该方法返回的节点不在文档之中,即没有任何父节点,必须使用诸如
Node.appendChild
这样的方法添加到文档之中。 - 克隆一个节点之后,
DOM
有可能出现两个有相同id
属性
<span id="span">
<b>文本</b>
</span>
<div id="div"></div>
<button onclick="copy()">复制文本</button>
<script>
function copy(){
var span = document.getElementById('span');
var div = document.getElementById('div');
//复制节点,加true表示连同子节点一起复制
var _span = span.cloneNode( true );
div.appendChild( _span );
}
</script>
Node.insertBefore
:
用于将某个节点插入父节点内部的指定位置,给参考节点外部前面插入新节点。
语法:
父节点.insertBefore( 新节点, 参考节点);
示例
<button onclick="before( this )">按钮 </button>
<script>
function before( btn ){
var parent = btn.parentNode;
var p = document.createElement('p');
p.innerText= '文本';
parent.insertBefore( p, btn );
}
</script>
Node.removeChild
:
接受一个子节点作为参数,用于从当前节点移除该子节点。返回值是移除的子节点。
<ul id="nav">
<li>首页 <button>删除</button></li>
<li>关于我们 <button>删除</button></li>
<li>联系我们 <button>删除</button></li>
</ul>
<script>
var nav = document.getElementById('nav');
var lis = nav.children;
for(var i=0;i<lis.length;i++){
lis[i].lastElementChild.onclick = function(){
if(confirm('您确定要删除此行吗?')){
var li = this.parentNode;
li.parentNode.removeChild( li );
}
}
}
</script>
Node.replaceChild()
:
用于将一个新的节点,替换当前节点的某一个子节点
<div>
<button>修改</button>
</div>
<script>
var btn = document.getElementsByTagName('button')[0];
btn.onclick = function(){
var newBtn = document.createElement('a');
newBtn.innerText = '保存';
newBtn.className = 'save';
this.parentNode.replaceChild( newBtn, this);
console.log( this );//button
}
Node.contains()
:
回一个布尔值,表示参数节点是否满足以下三个条件之一
<div id="box">
<span id="span">
<b id="b">文本</b>
</span>
</div>
<h4 id="h4">标题4</h4>
<script>
var box = document.getElementById('box');
var span = document.getElementById('span');
var b = document.getElementById('b');
var h4 = document.getElementById('h4');
console.log( box.contains( box ) );// true 参数节点为当前节点
console.log( box.contains( span ) ); // true 参数节点为当前节点的子节点
console.log( box.contains( b ) ); // true 参数节点为当前节点的后代节点
console.log( box.contains( h4 ) );// false 不符合以上3个条件
</script>
Node.isEqualNode(),Node.isSameNode()
isEqualNode
方法返回一个布尔值,用于检查两个节点是否相等。所谓相等的节点,指的是两个节点的类型相同、属性相同、子节点相同。
<h1>标题1</h1>
<h1>标题1</h1>
<script>
var h1 = document.getElementsByTagName('h1')[0];
var h2 = document.getElementsByTagName('h1')[1];
console.log( h1.isEqualNode( h2 ) );//true
</script>
isSameNode
方法返回一个布尔值,表示两个节点是否为同一个节点。
var p1 = document.createElement('p');
var p2 = document.createElement('p');
console.log( p1.isSameNode(p2) ) // false
console.log( p1.isSameNode(p1) ) // true
console.log( p1.isEqualNode(p2) ) // true
Node.normalize()
:
用于清理当前节点内部的所有文本节点,它会去除空的文本节点,并且将毗邻的文本节点合并成一个,也就是说不存在空的文本节点,以及毗邻的文本节点。
var div = document.createElement('div');
div.appendChild(document.createTextNode('部分1 '));
div.appendChild(document.createTextNode('部分2 '));
console.log( div );
div.normalize();
console.log( div );
Node.getRootNode()
返回当前节点所在文档的根节点。
<div id="nav">
<ul>
<li> <b id="b">首页</b></li>
<li>关于</li>
<li>练习</li>
</ul>
</div>
<script>
var b = document.getElementById('b');
console.log( b.getRootNode() );//document
</script>
NodeList 接口
节点都是单个对象,有时需要一种数据结构,能够容纳多个节点。DOM 提供两种节点集合,用于容纳多个节点:NodeList
和HTMLCollection
。
NodeList
内部有forEach方法,HTMLCollection
没有此方法
NodeList
是类数组,不能使用数组的方法。
通过以下方法可以得到NodeList
实例。
-
Node.childNodes
-
document.querySelectorAll()
等节点搜索方法 -
forEach
forEach
方法的第二个参数,用于绑定回调函数内部的this
,该参数可省略。
<div id="nav">
<ul>
<li>首页</li>
<li>关于</li>
<li>练习</li>
</ul>
</div>
<script>
var lis = document.querySelectorAll('li');
lis.forEach( function( item, ){
console.log( item );
console.log( this );// ['苹果','香蕉']
}, ['苹果','香蕉'] );
</script>
HTMLCollection 接口
:
通过以下方法可以得到HTMLCollection
实例。
document.links
:得到文档中所有的超级链接document.images
:得到文档中所有的图像对象document.forms
:得到文档中所有的表单对象document.scripts
:得到文档中所有的script
对象document.styleSheets
:得到文档中所有的style
对象
获取所有超级链接集合
<a href="#">链接</a>
<p>
<a href="#">链接</a>
</p>
<script>
var links = document.links;
console.log( links );
</script>
获取图像所有集合
<img src="images/a1.png">
<p>
<img src="images/a1.png">
</p>
<script>
var images = document.images;
console.log( images );
</script>
图片预加载
<img src="images/2.png">
<p>
<img src="images/a1.png">
</p>
<div>
<img src="images/4.png">
</div>
<script>
//得到文档中图像集合
var images = document.images;
//循环每一张图像
for(let i=0; i<images.length; i++ ){
//给每一张图像包装一个span标签
var span = document.createElement('span');
span.className = 'img';
images[i].parentNode.insertBefore( span, images[i] );
span.appendChild( images[i] );
//如果图像加载完毕
images[i].onload = function(){
this.style.visibility = 'visible';
var span = this.parentNode;
span.parentNode.replaceChild(this, span);//替换
}
}
卸载外包裹
<div class="box">
<span>
<button id="btn">按钮</button>
</span>
</div>
<script>
document.getElementById('btn').onclick = function(){
var btn = this;
var span = this.parentNode;
span.parentNode.replaceChild( btn, span );
}
</script>
卸载内包裹
<button id="btn">按钮
<i>❤</i>
<b>按钮</b>
</button>
<script>
document.getElementById('btn').onclick = function(){
var b = this.lastElementChild;
var bText = b.firstChild;
b.parentNode.replaceChild( bText, b );
}
</script>
获取表单对象
<form name="form1" action="">
<input type="text" name="username">
<input type="text" name="password">
</form>
<form name="form2" action="">
<input type="text" name="username">
<input type="text" name="password">
</form>
<script>
var form1 = document.forms['form1'];
console.log( form1['username'], form1['password'] );
var form2 = document.forms['form2'];
console.log( form2['username'], form2['password'] );
</script>
批量验证表单示例
<form name="form1" action="http://www.baidu.com" method="post" autocomplete="off">
用户:<input type="text" name="username" reg="^\w{3,10}$" required> <br>
密码:<input type="text" name="password" reg="^\d{6,}$" required> <br>
信息:<textarea name="msg" cols="30" rows="10" reg="" required></textarea> <br>
<button type="button" onclick="submitForm()">提交</button>
</form>
<script>
function submitForm(){
var form1 = document.forms['form1'];
for( var i=0; i<form1.length; i++ ){
if( form1[i].required ){
//必填
if( form1[i].value == '' ){
alert('请输入!');
form1[i].focus();
return false;
}
//验证格式(正则)
var str = form1[i].getAttribute('reg');
var reg = new RegExp( str, 'gi');
if( str && !reg.test( form1[i].value ) ){
alert('格式不对!');
form1[i].focus();
return false;
}
}
}
//提交表达
form1.submit();
// console.log(form1);
}
</script>
ParentNode 接口
有那些节点拥有子节点?
- 文档节点(
document
) - 元素节点(
element
) - 文档片段节点 (
documentFragment
)
因此只有这三类节点会继承ParentNode
<script>
console.log( document.parentNode );//null
console.dir( document.body.parentNode );//html
console.dir( document.documentElement );//html
console.dir( document.documentElement.parentNode );//#document
console.log( document.body.parentNode == document.documentElement );//true
</script>
ParentNode.children
返回一个HTMLCollection实例,成员是当前节点的所有元素子节点。该属性只读。
ParentNode.firstElementChild
返回当前节点的第一个元素子节点。如果没有任何元素子节点,则返回null。
ParentNode.lastElementChild
返回当前节点的最后一个元素子节点,如果不存在任何元素子节点,则返回null。
ParentNode.childElementCount
返回一个整数,表示当前节点的所有元素子节点的数目。如果不包含任何元素子节点,则返回0
。
document.body.childElementCount // 13
ParentNode.append(),ParentNode.prepend()
append:在父节点内部的后面追加
prepend:在父节点内部的前面追加
<div id="box">
</div>
<script>
var box = document.getElementById('box');
var p = document.createElement('p');
var span = document.createElement('span');
box.append( p );//父节点方法
box.appendChild( span );//父节点追加子节点方法
</script>
prepend
和 append
区别
<div id="box">
内容
</div>
<script>
var box = document.getElementById('box');
var p = document.createElement('p');
var span = document.createElement('span');
var a = document.createElement('a');
box.prepend( p );
box.append( span, a );
</script>
ChildNode.remove()
子节点方法
用于从父节点移除当前节点。
<div id="box"></div>
<script>
var box = document.getElementById('box');
box.remove();//删除
box.parentNode.removeChild( box );//删除
</script>
ChildNode.before(),ChildNode.after()
:
<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn');
var p = document.createElement('p');
btn.before( p );//目标节点外部的前面追加
p.append( btn );//目标节点内部的后面追加
</script>
<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function(){
var str = this.innerText;
this.after( str );//外部的后面
}
</script>
ChildNode.replaceWith
:
使用参数节点,替换当前节点。参数可以是元素节点,也可以是文本节点。
<button id="btn">按钮</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function(){
var div = document.createElement('div');
var btn = this.cloneNode(true);
div.append( btn );
this.replaceWith( div );
}
</script>
Document 对象
Document 节点 属性
document.documentElement
返回当前文档的根节点(html
),它通常是document
节点的第二个子节,紧跟在document.doctype
节点后面。
document.body,document.head
这两个属性是可写的,如果改写它们的值,相当于移除所有子节点。
document.activeElement
返回获得当前焦点(focus)的 DOM 元素。通常,这个属性返回的是<input>
、<textarea>
、<select>
等表单元素,如果当前没有焦点元素,返回<body>
元素或null。
<div id="nav">
<ul>
<li tabindex="1" class="home">首页</li>
<li tabindex="4" class="about">关于我们</li>
<li tabindex="2" class="contact">联系我们</li>
<li tabindex="3" class="product">产品中心</li>
</ul>
</div>
<script>
setInterval(function(){
console.log( document.activeElement );
},1000)
</script>
document.domain
属性返回当前文档的域名,不包含协议和接口
我们经常会用获取到当前程序的域名部分,拿域名作为前缀,避免和第三方应用命名冲突
var domain = document.domain; //seecen.com
localStorage.setItem(domain+'_mycart','购物车数据');//seecen.com_mycart
document.location
Location对象是浏览器提供的原生对象,提供 URL 相关的信息和操作方法。
// 标准的URL
var url = 'https://www.baidu.com:80/product/index.html';
// https:// 协议部分
// www 主机部分
// baidu.com 域名部分
// 80 端口部分
// /product/index.html 页面的路径和文件名
location.href
: 返回完整的web地址,可读可写,写的就是网址转向
<button onclick="getUrl()">读取浏览器地址栏地址</button>
<button onclick="goUrl()">网易</button>
<script>
function getUrl(){
console.log( location.href );//http://www.163.com
}
function goUrl(){
location.href='http://www.163.com'
}
</script>
location.hostname
:返回 web 主机的域名location.pathname
:返回当前页面的路径和文件名location.port
: 返回 web 主机的端口 (80 或 443)location.protocol
: 返回所使用的 web 协议(http: 或 https:)
document.lastModified
:
返回一个字符串,表示当前文档最后修改的时间。不同浏览器的返回值,日期格式是不一样的
document.title
返回当前文档的标题。默认情况下,返回<title>
节点的值
<button onclick="getTitle()">得到窗口标题</button>
<button onclick="setTitle()">设置窗口标题</button>
<script>
function getTitle(){
alert(document.title);
}
function setTitle(){
document.title = prompt('请输入窗口标题!');
}
</script>
document.referrer
:
返回一个字符串,表示当前文档的访问者来自哪里
如果无法获取来源,或者用户直接键入网址而不是从其他网页点击进入,document.referrer
返回一个空字符串。
document.hidden
返回一个布尔值,表示当前页面是否可见。如果窗口最小化、浏览器切换了 Tab
,都会导致导致页面不可见,使得document.hidden
返回true
。
setInterval(function(){
console.log( document.hidden );
},1000);
document.readyState
document.readyState
属性返回当前文档的状态,共有三种可能的值。
loading
:加载 HTML 代码阶段interactive
: 加载外部资源阶段complete
: 加载完成
<img src="images/2.png" alt="">
<img src="images/4.png" alt="">
<img src="images/a1.png" alt="">
<script>
setInterval(function(){
console.log( document.readyState );
},500);
</script>
js原生查找元素
document.getElementById
: 通过id
查找,返回单个dom
对象
<div id="box"></div>
<script>
document.getElementById('box').innerText = 'hello';
</script>
document.getElementsByTagName
: 通过标签名查找,返回HTMLCollection
集合对象,是一个类数组,可以使用for
循环。
<h2>标题2</h2>
<h2>标题2</h2>
<h2>标题2</h2>
<script>
var h2 = document.getElementsByTagName('h2');
console.log( h2 );// HTMLCollection(3) [h2, h2, h2]
</script>
示例1
<h2>标题2</h2>
<h2>标题2</h2>
<h2>标题2</h2>
<script>
var h2 = document.getElementsByTagName('h2');
h2[0].style.color = 'red';
h2[1].style.color = 'green';
h2[2].style.color = 'blue';
</script>
即便是只存在一个结果,也要使用中括号引用
<h2>标题2</h2>
<script>
var h2 = document.getElementsByTagName('h2');
h2[0].style.color = 'red';
</script>
document.getElementsByClassName
: 通过类名查找,返回HTMLCollection
集合对象,是一个类数组,可以使用for
循环,用法同上。
<h2 class="bt2">标题2</h2>
<h2 class="bt2">标题2</h2>
<h2 class="bt2">标题2</h2>
<script>
var h2 = document.getElementsByClassName('bt2');
h2[0].style.color = 'red';
h2[1].style.color = 'green';
h2[2].style.color = 'blue';
</script>
document.getElementsByName
: 通过属性名(name='box'
)查找,返回单个NodeList
集合对象,是一个类数组,可以使用forEach
循环,用法同上。
<h2 name="bt2">标题2</h2>
<h2 name="bt2">标题2</h2>
<h2 name="bt2">标题2</h2>
<script>
var h2 = document.getElementsByName('bt2');
console.log( h2 );
h2[0].style.color = 'red';
h2[1].style.color = 'green';
h2[2].style.color = 'blue';
</script>
document.links
: 查找所有的链接document.images
: 查找所有的图像document.forms
: 查找所有的图像document.scripts
: 查找所有的图像document.styleSheets
: 查找所有的图像
采用 CSS 选择器作为参数的api接口
document.querySelector()
查找单个的dom
对象,当有多个符合要求时,返回最近的dom
对象
<h2>标题2</h2>
<h2>标题2</h2>
<h2>标题2</h2>
<script>
var h2 = document.querySelector('h2');
h2.style.color = 'red';
</script>
<h1 name="h2">标题1</h1>
<h2 name="h2">标题2</h2>
<h3 name="h2">标题3</h3>
<script>
var h2 = document.querySelector('h3[name="h2"]');
h2.style.color = 'red';
</script>
<h1 name="gx-icon-del">标题1</h1>
<h2 name="ok gx-icon-right">标题2</h2>
<h3 name="no gx-icon-error">标题3</h3>
<script>
var a = document.querySelectorAll('[name ^="gx-icon-"]');
console.log( a );
var b = document.querySelectorAll('[name *="gx-icon-"]');
console.log( b );
var c = document.querySelectorAll('[name $="gx-icon-right"]');
console.log( c );
</script>
document.querySelectorAll()
查找多个的dom
对象,返回NodeList
对象,可以使用forEach
。
<div class="nav">
<ul>
<li><a href="#">导航1</a></li>
<li><a href="#">导航2</a></li>
<li><a href="#">导航3</a></li>
<li><a href="#">导航4</a></li>
</ul>
</div>
<script>
var lis1 = document.getElementsByClassName('nav')[0].getElementsByTagName('li'); // HTMLCollection(4) [li, li, li, li]
var lis2 = document.querySelectorAll('.nav li');
console.log( lis1, lis2 ); // NodeList(4) [li, li, li, li]
</script>
document.elementFromPoint() 和 document.elementsFromPoint()
document.elementFromPoint
方法返回位于页面指定位置最上层的元素节点。
document.elementsFromPoint()
返回一个数组,成员是位于指定坐标(相对于视口)的所有元素。
<style>
div{
position: fixed;
width: 200px;
height: 100px;
}
div.box1{
background-color: red;
z-index: 10;
}
div.box2{
background-color: green;
top: 60px;
left: 100px;
}
</style>
<div class="box1">
</div>
<div class="box2">
</div>
<script>
document.onclick = function( e){
var elem = document.elementFromPoint( e.clientX, e.clientY );
console.log( elem );
}
</script>
document.createEvent
:
document.createEvent
方法生成一个事件对象(Event实例
),该对象可以被element.dispatchEvent
方法使用,触发指定事件。
var event = document.createEvent(type);
示例
<button onclick="triggle()">按钮</button>
<script>
//创建gongxian事件
var event = document.createEvent('Event');
event.initEvent('gongxian', true, true);
//侦听你创建的事件
document.addEventListener('gongxian', function (e) {
console.log(e.type);
}, false);
function triggle(){
//触发gongxian 事件
document.dispatchEvent(event);
}
</script>
js元素添加事件方法
内联添加事件
<button onclick="add()">按钮</button>
<script>
function add(){
//this 指向 window
alert('hello');
}
</script>
DOM对象API添加事件
<button id="btn">按钮</button>
<script>
document.getElementById('btn').onclick = function() {
//this 指向 button
alert('hello')
}
</script>
标准API添加事件
addEventListener
:添加事件
语法
dom对象.addEventListener( 事件名(不要on), 匿名函数, 事件类型 )
<button id="btn">按钮</button>
<script>
document.getElementById('btn').addEventListener('click',function(){
console.log( this );//指向按钮
alert('hello');
})
</script>
removeEventListener
:删除事件
非标准方法删除事件
<button id="btn" onclick="add()">添加事件</button>
<button onclick="del()">删除事件</button>
<script>
var add = function (){
alert('添加了事件!');
}
function del(){
document.getElementById('btn').onclick = null;//非标准方法删除事件
alert('删除add事件!');
}
</script>
使用标准api
删除事件
<button id="btn1">添加事件</button>
<button id="btn2">删除事件</button>
<script>
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
function fn(){
alert('添加了事件!');
}
btn1.addEventListener('click', fn )
btn2.onclick = function(){
btn1.removeEventListener('click', fn ); //不能删除匿名事件处理器
alert('事件删除成功!');
}
</script>
注意:不能删除匿名事件处理器
使用标准api
触发事件
<button id="btn1">按钮1</button>
<script>
var btn1 = document.getElementById('btn1');
btn1.onclick = function(){
console.log('被单击了!');
}
setInterval(function(){
btn1.click();
},1000)
</script>
<style>
.myfile [type="file"]{
display: none;
}
</style>
<div class="myfile">
<input type="file">
<button id="btn">图片上传</button>
</div>
<script>
document.getElementById('btn').onclick = function(){
this.previousElementSibling.click();
}
</script>
Element 节点
draggable
: 设置元素是否可拖拽
<button draggable="true">按钮</button>
注意:
img
元素默认是可拖拽的
你可以关闭这个行为
<img src="images/a1.png" draggable="false">
Element.tabIndex
:返回一个整数,表示当前元素在 Tab 键遍历时的顺序
<ul>
<li tabindex="3">首页</li>
<li tabindex="1">关于</li>
<li tabindex="2">联系</li>
</ul>
tabIndex属性值如果是负值-1
,则 Tab 键不会遍历到该元素
Element.title
:
用来读写当前元素的 HTML
属性title
,属性通常用来指定,鼠标悬浮时弹出的文字提示框。
<button title="按钮文字">标题</button>
Element.hidden
:
返回一个布尔值,表示当前元素的hidden
属性,用来控制当前元素是否可见。该属性可读写。
<button id="btn">按钮1</button>
<button>按钮2</button>
<script>
document.getElementById('btn').hidden = true;
</script>
Element.contentEditable,Element.isContentEditable
HTML 元素可以设置contentEditable
属性,使得元素的内容可以编辑。
<table>
<tr>
<th>学号</th>
<th>姓名</th>
</tr>
<tr>
<td contenteditable="true">1</td>
<td contenteditable="true">张三</td>
</tr>
<tr>
<td contenteditable="true">2</td>
<td contenteditable="true">李四</td>
</tr>
</table>
Element.isContentEditable
属性返回一个布尔值,同样表示是否设置了contenteditable
属性。
Element.attributes
返回一个类似数组的对象,成员是当前元素节点的所有属性节点
<button id="btn" title="文章" name="anniu" class="red">按钮</button>
<script>
document.getElementById('btn').onclick = function(){
var obj = this.attributes;
console.log( obj['title'].value );
}
</script>
Element.outerHTML
返回一个字符串,表示当前元素节点的所有 HTML 代码,包括该元素本身和所有子元素。
outerHTML
属性是可读写的,对它进行赋值,等于替换掉当前元素。
<button id="btn">按钮</button>
<script>
document.getElementById('btn').onclick = function(){
var html = this.outerHTML;
console.log( html ); //<button id="btn">按钮</button>
}
</script>
获取元素尺寸
window.innerWidth
:
获取窗口可视宽,该可视宽会包含滚动条的宽度( ~15px ),存在兼容性问题(IE9+)。
IE9
以下如何获取可视宽?
document.documentElement.clientWidth; //不包含body的边距、滚动条。
window.innerHeight
:
获取窗口可视高,该可视宽会包含滚动条的宽度( ~15px ),存在兼容性问题(IE9+)。
IE9
以下如何获取可视高?
document.documentElement.clientHeight; //不包含body的边距、滚动条。
<button onclick="getWidth()">窗口可视宽</button>
<button onclick="getHeight()">窗口可视高</button>
<script>
function getWidth(){
console.log( window.innerWidth );
}
function getHeight(){
console.log( window.innerHeight );
}
</script>
Element.clientWidth Element.clientHeight
:
获取元素的宽度,包含padding,但不包含border、margin、滚动条宽度。
<style>
#box{
width: 100px;
height: 100px;
padding: 10px;
border: 10px solid green;
background-color: red;
margin: 10px;
overflow: auto;
}
</style>
<div id="box">
<p>我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本我是文本</p>
</div>
<br>
<button onclick="getWidth()">获取客户端宽度</button>
<script>
function getWidth(){
var box = document.getElementById('box');
console.log( box.clientWidth );
}
</script>
Element.clientLeft,Element.clientTop
Element.clientLeft
:
元素节点左边框(left border
)的宽度,不包括左侧的padding
和margin
。
如果没有设置左边框,或者是行内元素(display: inline
),该属性返回0
。
注意:该属性总是返回整数值,如果是小数,会四舍五入。
Element.clientTop
:
Element.clientTop
属性等于网页元素顶部边框的宽度(单位像素),其他特点都与clientTop相同。
Element.scrollHeight,Element.scrollWidth
Element.scrollWidth
:
返回一个整数值(小数会四舍五入),表示当前元素的总宽度,包括溢出容器、当前不可见的部分,它包括padding,但是不包括border
、margin
、垂直滚动条的高度。
Element.scrollHeight
:
和scrollWidth
要求差不多。
Element.scrollLeft,Element.scrollTop
表示当前元素的水平滚动条向右侧滚动的像素数量,Element.scrollTop
属性表示当前元素的垂直滚动条向下滚动的像素数量。对于那些没有滚动条的网页元素,这两个属性总是等于0。
如果要查看整张网页的水平的和垂直的滚动距离,要从
document.documentElement
这两个属性都可读写,设置该属性的值,会导致浏览器将当前元素自动滚动到相应的位置。
Element.offsetParent
Element.offsetParent
属性返回最靠近当前元素的、并且 CSS
的position
属性不等于static
的上层元素。
Element.offsetHeight,Element.offsetWidth
Element.offsetHeight
属性返回一个整数,表示元素的 CSS
垂直高度(单位像素),包括元素本身的高度、padding 和 border,以及水平滚动条的高度(如果存在滚动条)。
<style>
.box{
position: absolute;
width: 200px;
background-color: red;
visibility: hidden;
}
</style>
<div id="box" class="box">
文本文本文本文本
</div>
<button id="btns">按钮</button>
<script>
document.getElementById('btns').onclick = function(){
console.log( document.getElementById('box').offsetWidth );
}
</script>
Element.className,Element.classList
兼容性IE10+
Element.className
返回一个字符串,多个类用空格风格,该属性可读可写
<div id="box" class="red green blue"></div>
<script>
var str = document.getElementById('box').className;
console.log( str );//red green blue
</script>
Element.classList
返回一个类数组对象,当前元素节点的每个class
就是这个对象的一个成员。
<div id="box" class="red green blue"></div>
<script>
var obj = document.getElementById('box').classList;
console.log( obj );//类数组对象
</script>
Element.classList.add
:追加类Element.classList.remove
:移除类Element.classList.toggle
:切换类(没有此类就加上,有此类就移除)Element.classList.contains
:检测是否包含某类,返回布尔值
<div id="box" class="red green blue"></div>
<script>
var obj = document.getElementById('box').classList;
obj.add('yellow'); //追加类
obj.remove('red'); //移除类
obj.toggle('red'); //切换类
console.log( obj.contains('green') );//true 检测是否包含某类
console.log( obj[2], obj.item(2) );// 读取指定索引值的类名
console.log( obj.toString() );// 文本化类名 green blue yellow red
</script>
Element.dataset
网页元素可以自定义data-
属性,用来添加数据。
返回一个DOMStringMap
对象,对象可以使用中括号或者点的形式调用,该对象可读可写
<div id="box" data-price="100" data-num="46"></div>
<script>
var box = document.getElementById('box');
box.dataset.name = '手机';
console.log( box.dataset.name, box.dataset.price, box.dataset.num );
//手机 100 46
</script>
Element.innerHTML
:
返回一个字符串,等同于该元素包含的所有 HTML
代码。
Element.outerHTML
:
返回一个字符串,表示当前元素节点的所有 HTML
代码,包括该元素本身和所有子元素。
<div id="box">
<span>文本</span>
</div>
<script>
var box = document.getElementById('box');
box.innerHTML;// <span>文本</span>
box.outerHTML;// <div id="box"><span>文本</span></div>
</script>
Element.getAttribute()
:
接受一个字符串作为参数,返回同名属性的值。如果没有该属性,则返回null
。
Element.setAttribute()
:
用于为当前节点设置属性。如果属性已经存在,将更新属性值,否则将添加该属性。该方法没有返回值。
<div id="box" price="2000"></div>
<script>
var box = document.getElementById('box');
box.setAttribute('price', 100);
</script>
Element.hasAttribute()
:
返回一个布尔值,表示当前元素节点是否有指定的属性。
<div id="box" price="2000"></div>
<script>
var box = document.getElementById('box');
console.log( box.hasAttribute('price') );//true
</script>
Element.hasAttribute()
:
<div></div>
<script>
var box = document.getElementsByTagName('div')[0];
console.log( box.hasAttributes() );//false
</script>
Element.removeAttribute()
移除属性
<input id="username" type="text" disabled>
<button id="btn">开启</button>
<script>
document.getElementById('btn').onclick = function(){
document.getElementById('username').setAttribute('disabled','');
document.getElementById('username').disabled = false;
document.getElementById('username').removeAttribute('disabled');
}
</script>
Element.matches()
返回一个布尔值,表示当前元素是否匹配给定的 CSS 选择器。
<div id="box" class="red" name="box">
<ul>
<li class="red">首页</li>
</ul>
</div>
<script>
var box = document.querySelector('#box');
console.log( box.matches('#box') ); //true
console.log( box.matches('#box.red') ); //true
console.log( box.matches('div') ); //true
console.log( box.matches('[name="box"]') ); //true
console.log( box.matches('#box .red') ); //false
</script>
利用offsetParent向上累积求总的偏移值
<div style="position: fixed;left:300px;">
<div style="position: absolute;left:300px;">
<div style="position: absolute;left:100px;">
<div id="two" class="two"></div>
</div>
</div>
</div>
<script>
var two = document.getElementById('two');
var left = two.offsetLeft;
while( two.offsetParent ){
two = two.offsetParent;
left += two.offsetLeft;
}
console.log( left );
</script>
-
Element.getBoundingClientRect()
返回一个对象,提供当前元素节点的大小、位置等信息,基本上就是 CSS 盒状模型的所有信息。
<div id="one" class="one">
<div id="two" class="two"></div>
</div>
<script>
var two = document.getElementById('two');
console.log( two.getBoundingClientRect() )
</script>
返回的rect
对象,具有以下属性(全部为只读)。
x
: x坐标y
: y坐标height
: 高度width
: 宽度left
: 距左值right
: 距右值top
: 距顶值bottom
: 距下值
-
Element.getClientRects()
:返回一个类似数组的对象,里面是当前元素在页面上形成的所有矩形
每个矩形都有bottom、height、left、right、top和width六个属性,表示它们相对于视口的四个坐标,以及本身的高度和宽度。
事件模型
事件各个组成部分之间的一种通信方式,DOM 支持大量的事件
EventTarget 接口
该接口主要提供三个实例方法。
addEventListener
: 绑定事件的监听函数,IE9+
removeEventListener
: 移除事件的监听函数,不能移除匿名函数dispatchEvent
:触发事件
EventTarget.addEventListener()
语法
EventTarget.addEventListener( '不加on的事件名', 事件处理器, 事件类型(默认冒泡) )
什么是冒泡事件?
冒泡事件是指从目标对象一直到根节点的事件触发过程。
<div id="box">
<ul id="ul">
<li id="li">首页 <button id="btn">删除</button></li>
</ul>
</div>
<script>
var box = document.getElementById('box');
var ul = document.getElementById('ul');
var li = document.getElementById('li');
var btn = document.getElementById('btn');
box.addEventListener('click',function(){
console.log('btn被单击了!','-from div');
})
ul.addEventListener('click',function(){
console.log('btn被单击了!','-from ul');
})
li.addEventListener('click',function(){
console.log('btn被单击了!','-from li');
})
btn.addEventListener('click',function(){
console.log('btn被单击了!','-from button');
})
</script>
什么是捕获事件?
从根节点到一直到目标节点的事件触发过程。
<div id="box">
<ul id="ul">
<li id="li">首页 <button id="btn">删除</button></li>
</ul>
</div>
<script>
var box = document.getElementById('box');
var ul = document.getElementById('ul');
var li = document.getElementById('li');
var btn = document.getElementById('btn');
box.addEventListener('click',function(){
console.log('btn被单击了!','-from div');
},true)
ul.addEventListener('click',function(){
console.log('btn被单击了!','-from ul');
},true)
li.addEventListener('click',function(){
console.log('btn被单击了!','-from li');
},true)
btn.addEventListener('click',function(){
console.log('btn被单击了!','-from button');
},true)
</script>
如何阻止事件冒泡?
btn.addEventListener('click',function( event ){
event.stopPropagation();//阻止事件冒泡
// event.stopImmediatePropagation(); //除了可以阻止事件冒泡之外,还可以把这个元素绑定的同类型事件也阻止
console.log('btn被单击了!','-from button');
})
<div>
<p>段落</p>
</div>
<script>
var p = document.querySelector('p');
p.addEventListener('click', function (event) {
// event.stopPropagation(); //会执行下面的click事件
event.stopImmediatePropagation(); //不会执行下面的click事件
console.log(1);
});
p.addEventListener('click', function(event) {
// 会触发
console.log(2);
});
</script>
如何阻止默认动作?
默认动作有那些?
- 右击
- 提交表单
- 超级链接
- 拖拽
btn.addEventListener('click',function( event ){
event.preventDefault();//阻止默认动作
console.log('btn被单击了!','-from button');
})
什么是事件代理(委托)?
由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理。
事件代理可以提高执行效率,属于性能优化的一种手段
<button id="addbtn">添加</button>
<script>
//事件代理
document.getElementById('ul').onclick = function(e){
var target = e.target;
var tag = target.nodeName.toLowerCase();
if(tag == 'button'){
target.parentNode.remove();
}
}
//添加
document.getElementById('addbtn').onclick = function(){
var title = prompt('请输入名称!');
var temp = `<li>${title}<button>删除</button></li>`;
document.querySelector('ul').innerHTML += temp
}
</script>
如何制作一次性事件?
<button id="paybtn">立即支付</button>
<script>
function fn(){
alert('支付成功!');
//删除自己添加的事件
this.removeEventListener('click', fn );
}
document.getElementById('paybtn').addEventListener('click', fn );
</script>
利用addEventListener
第三个参数也可以做单次事件功能
第三个参数:
- capture:true 捕获 false 冒泡
- once:true 单次 false 多次
- passive:true 不允许阻止默认动作 false 允许
<button id="paybtn">立即支付</button>
<script>
document.getElementById('paybtn').addEventListener('click', function(){
alert('支付成功!');
},{
capture: true,
once: true,
passive: true
});
</script>
EventTarget.dispatchEvent()
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
<script>
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
//1.创建自定义事件
var event = new Event('gongxian');
//2.监听自定义事件
btn1.addEventListener('gongxian',function(){
console.log('开饭了!');
})
btn2.onclick = function(){
//3.触发自定义事件
btn1.dispatchEvent( event );
}
</script>
Event.currentTarget,Event.target
Event.currentTarget
属性返回事件当前所在的节点,即正在执行的监听函数所绑定的那个节点。
Event.target
属性返回原始触发事件的那个节点,即事件最初发生的节点。
Event.currentTarget
属性的值是不一样的,前者总是不变的, 后者则是指向监听函数所在的那个节点对象。
<div id="box" style="padding:20px;">
<p>段落 <button>按钮</button></p>
</div>
<script>
var box = document.querySelector('#box');
box.onclick = function( e ){
console.log( '当前目标对象', e.currentTarget );
console.log( '目标对象', e.target );
}
</script>
Event.type
Event.type
属性返回一个字符串,表示事件类型。
<script>
var box = document.querySelector('#box');
box.onclick = function( e ){
console.log( '事件类型', e.type );//click
}
</script>
Event.timeStamp
Event.timeStamp
属性返回一个毫秒时间戳,表示事件发生的时间。它是相对于网页加载成功开始计算的。
实践应用:控制事件触发频率,提高性能
<script>
var box = document.querySelector('#box');
box.onclick = function( e ){
console.log( '事件时间戳', e.timeStamp );
}
</script>
e.clientX,e.screenX
<script>
document.onmousemove = function(e){
console.log( 'client:', e.clientX );//相对浏览器水平平移
console.log( 'screen:', e.screenX );//相对设备屏幕水平偏移
}
</script>
Event.isTrusted
返回一个布尔值,表示该事件是否由真实的用户行为产生。比如,用户点击链接会产生一个click
事件,该事件是用户产生的;Event
构造函数生成的事件,则是脚本产生的。
Event.detail
该属性返回一个数值,表示事件的某种信息,具体含义与事件类型相关。
Event.detail是鼠标按下的次数:
- 1表示单击
- 2表示双击
- 3表示三击
Event 对象的实例方法
Event.preventDefault()
取消浏览器对当前事件的默认行为,比如点击链接后。
<div style="height: 5000px;"></div>
<script>
//按下空格页面会往下走动,以下代码阻止这个行为
document.onkeydown = function(e){
e.preventDefault();
}
</script>
Event.stopPropagation()
阻止事件在 DOM 中继续传播,防止再触发定义在别的节点上的监听函数stopImmediatePropagation
阻止同一个事件的其他监听函数被调用,不管监听函数定义在当前节点还是其他节点。也就是说,该方法阻止事件的传播,比Event.stopPropagation
()更彻底。CustomEvent 接口
用于生成自定义的事件实例。那些浏览器预定义的事件,虽然可以手动生成,但是往往不能在事件上绑定数据。如果需要在触发事件的同时,传入指定的数据,就可以使用 CustomEvent
接口生成的自定义事件对象
<button id="btn">按钮</button>
<script>
//1. 创建自定义事件
var ev = new CustomEvent('gongxian', {
detail: {
name: '张三',
age: 30,
sex: '男'
}
})
//2. 监听自定义事件
document.addEventListener('gongxian',function(e){
console.log(e.detail);
})
document.getElementById('btn').onclick = function(){
//3. 触发自定义事件
document.dispatchEvent( ev );
}
</script>
常用系统事件
click
:单击dblclick
:双击事件contextmenu
:右击事件change
:改变事件input
: 输入事件paste
:粘贴事件selectstart
: 开始选择时触发select
: 选择文本时触发,仅限表单控件(单行文本和多行文本框)copy
: 拷贝后触发mousewheel
:滚动滚动时触发scroll
: 滚动条滚动时触发mouseenter
:鼠标进入触发mouseleave
:鼠标离开触发mouseover
: 鼠标划过触发mouseout
: 鼠标划出触发mousedown
: 鼠标按下mousemove
: 鼠标移动mouseup
: 鼠标松开
mousedown、mousemove、mouseup、click的顺序是?
<div id="box">
<p>段落</p>
<button>按钮</button>
</div>
<script>
document.getElementById('box').onmouseenter = function(e){
console.log(e.target);
}
document.getElementById('box').onmouseover = function(e){
console.log(e.target);
}
</script>
<input type="text" id="prcie">
<script>
//输入的时候替换为空 \D 表示非数字
document.getElementById('prcie').oninput = function(){
this.value = this.value.replace(/\D/g,'');
}
//粘贴的时候替换为空
document.getElementById('prcie').onpaste = function(){
this.value = this.value.replace(/\D/g,'');
}
</script>
oncopy
:拷贝事件