目录
Web APIs
交互效果功能。
DOM
文档:一个页面就是一个文档,DOM中使用 document 表示。
元素:页面中所有的标签都是元素,DOM中使用 element 表示。
节点:网页中所有的内容都是节点(标签、属性、文本、注释等),DOM中使用 node 表示。
1、获取元素
不同获取方法,返回值可能不同,一定要注意其返回的是啥。
1-1.根据ID获取 getElementById(‘id’)
document.getElementById(id) 返回的是一个元素对象;如果当前文档中拥有特定ID的元素不存在则返回null。
HTML:
<div id = 'time'>2020/4/26</div>
JS:
var timer = doucument.getElementById('time');
console.log(timer); // 2020/4/26
console.log(typeof timer); // object
console.dir(timer); // div#time(可展开)
1-2.根据标签名获取 getElementsByTagName()
返回的是 获取的元素对象的集合;以伪数组的形式存储。
如果不存在,依旧返回一个伪数组,只不过这个伪数组为空。
HTML:
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
JS:
var lis = doucument.getElementsByTagName('li');
console.log(lis);
**PS:**获取某个父元素的子元素标签。
element.getElementsByTagName()
HTML:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<ol id = 'ol'>
<li>6</li>
<li>7</li>
</ol>
JS:
var ol = document.getElementById('ol');
var ol-lis = ol.getElementsByTagName('li');
console.log(ol-lis);
1-3.HTML5新增的方法
1、document.getElementsByClassName(‘类名’);
根据类名返回元素对象集合,跟 ID 类似。
2、document.querySelector(‘选择器’);
根据指定选择器返回第一个元素对象。注意选择器的类型。
标签:tagname。
ID:#id。
类:.classname
HTML:
<div class = 'box'>1</div>
<div id = 'nav'>2</div>
<li>3</li>
<li>4</li>
JS:
var box = document.querySelector('.box');
var nav = document.querySelector('#nav');
var li = document.querySelector('li'); // <li>4</li>
3、document.querySelectorAll(‘选择器’);
根据指定选择器返回所有的元素对象集合。
1-4.获取特殊元素 body html
document.body; 返回body元素对象
document.documentElement; 返回html元素对象
2、操作元素
2-1.操作元素内容
element.innerText :不识别 html标签 空格 换行 等。
element.innerHTML :可以识别html标签 空格 换行 等。
<div id="div1"></div>
<div id='div2'></div>
<script>
var div1 = document.getElementById('div1');
div1.innerText = '<strong>今天是:</strong>星期六';
var div2 = document.getElementById('div2');
div2.innerHTML = '<strong>今天是:</strong>星期六';
</script>
2-2.操作元素其他属性
element.src
element.href
element.title
element.alt
element.id
等等。
2-3.操作表单元素属性
type、value、checked、selected、disable
2-4.操作元素样式属性
1、element.style 行内样式操作
注:JS里面的样式采取驼峰命名法,比如 fontSize、backgroundColor
2、element.className 类名样式操作
element.className = ‘change’;
将当前的类名改为change。(我们要先在CSS里写下change的属性,也就是我们想改变的属性和属性值)
这种方法会把原类名覆盖点,要是想保留原类名,可以赋值 多类名 的方法。
element.className = ‘原类名 改的类名’;
<style>
div{
width: 200px;
height: 200px;
background-color: pink;
}
</style>
<body>
<div></div>
<script>
var div = document.querySelector('div');
div.onclik = function() {
this.style.backgroundColor = 'purple';
this.style.width = '250px';
}
</script>
</body>
3、属性操作
3-1.获取元素属性值
1、element.属性
获取的是内置属性值(元素本身自带的属性)
2、element.getAttrubute(‘属性’)
获取自定义属性的属性值(程序员自定义的属性)
3-2.修改元素属性值
1、element.属性 = ‘值’;
设置内置属性值
2、element.setAttribute(‘属性’,‘值’);
自定义属性
3-3.H5自定义属性
以 data- 开头
获取自定义属性
先定义了 data-index = ‘1’;
1、element.getAttribute(‘data-index’);
2、element.dataset.index 或者 element.dataset[‘index’] 不过这个是H5新增,ie11才支持。
在属性名处不再加 data- 了,因为dataset一个集合,存放了所有的自定义属性。
**注:**如果自定义属性的属性名是含有多个-连接而成的,获取时采用驼峰命名法。
data-list-name = ‘1’;
element.dataset.listName
element.dataset[‘listName’]
4、节点操作
节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
元素节点的nodeType为1;
属性节点的nodeType为2;
文本节点的nodeType为3.
在实际开发中,节点操作主要操作的是元素节点。
4-1.节点层次关系(父子兄)
节点操作主要分为父子兄的层次关系。
父节点:
element.parentNode
子节点:(ie9以上支持)
element.children (子元素节点集合,伪数组)
兄弟节点:(ie9才支持)
element.nextElementSibling
element.previousElementSibling
<div class="box">
<span class="erweima">×</span>
</div>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<script>
var erweima = document.querySelector('.erweima'); //得到 .erweima 这个元素节点
// 要想得到的是离元素最近的父级节点(亲爸爸),也就是.box这个元素节点
erweima.parentNode; //就是 == document.querySelector('.box')
//如果找不到父节点就返回为 null
//子节点 element.children IE9以上支持
var ul = document.querySelector('ul');
ul.children; //ul的子元素节点集合(伪数组)
//兄弟节点
element.nextElementSibling
element.previousElementSibling
</script>
5、创建和添加元素节点
1、先创建元素节点
document.creatElement(‘标签’);
2、添加节点
①在元素的子元素节点最后添加,也就是追加子元素。类似于数组中的push
element.appendChild(node); //node为创建的元素节点
②在指定的子元素前添加节点。
element.insertBefore(node,指定节点);
<ul>
<li>123</li>
</ul>
<script>
var ul = document.querySelector('ul');
//创建元素节点
var li = document.createElement('li');
var li2 = document.createElement('li');
//添加节点
//追加子元素
ul.appendChild(li); //<ul><li>123</li><li></li></ul>
//在第一个<li>前添加
ul.insertBefore(li2,ul.children[0]); //<ul><li></li><li>123</li><li></li></ul>
</script>
element.innerHTML 也可以创建节点
因为其可以识别html标签 空格 换行 等。故我们在’'内输入标签及内容即可
6、删除元素节点
node.removeChild(child)
只能删除某个节点的子节点,所以要使用此方法时,先确定child是什么,再确定node。
案例:
<textarea name="" id=""></textarea>
<button>发布</button>
<ul>
</ul>
<script>
// 1. 获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
// 2. 注册事件
btn.onclick = function() {
if (text.value == '') {
alert('您没有输入内容');
return false;
} else {
// console.log(text.value);
// (1) 创建元素
var li = document.createElement('li');
// 先有li 才能赋值
li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
//阻止链接跳转 href='javascript:;'
// a 是 li 的子元素
// (2) 添加元素
// ul.appendChild(li);
ul.insertBefore(li, ul.children[0]);
// (3) 删除元素 删除的是当前链接的li 它的父亲
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
// node.removeChild(child); 删除的是 li 当前a所在的li this.parentNode;
// node 是 child 的父元素,此处的 this 是 a
ul.removeChild(this.parentNode);
}
}
}
}
</script>
7、复制节点(克隆节点)
node.cloneNode(); 或者 node.cloneNode(flase);
括号为空或者里面是false,为浅拷贝,只复制标签不复制里面的内容和子节点;
node.cloneNode(true);
括号为true,为深拷贝,复制标签和里面的内容。
**注:**克隆完成之后,还要将该节点添加到你想添加的地方。
(这步只是复制,你要用还得粘贴(添加))。
8、动态添加删除表单 案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
table {
width: 500px;
margin: 100px auto;
border-collapse: collapse;
text-align: center;
}
td,
th {
border: 1px solid #333;
}
thead tr {
height: 40px;
background-color: #ccc;
}
</style>
</head>
<body>
<table cellspacing="0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 1.先去准备好学生的数据
var datas = [{
name: '魏璎珞',
subject: 'JavaScript',
score: 100
}, {
name: '弘历',
subject: 'JavaScript',
score: 98
}, {
name: '傅恒',
subject: 'JavaScript',
score: 99
}, {
name: '明玉',
subject: 'JavaScript',
score: 88
}, {
name: '大猪蹄子',
subject: 'JavaScript',
score: 0
}];
// 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) { // 外面的for循环管行 tr
// 1. 创建 tr行
var tr = document.createElement('tr');
tbody.appendChild(tr);
// 2. 行里面创建单元格(跟数据有关系的3个单元格) td 单元格的数量取决于每个对象里面的属性个数 for循环遍历对象 datas[i]
for (var k in datas[i]) { // 里面的for循环管列 td
// 创建单元格
var td = document.createElement('td');
// 把对象里面的属性值 datas[i][k] 给 td
// console.log(datas[i][k]);
td.innerHTML = datas[i][k];
tr.appendChild(td);
}
// 3. 创建有删除2个字的单元格
var td = document.createElement('td');
td.innerHTML = '<a href="javascript:;">删除 </a>';
tr.appendChild(td);
}
// 4. 删除操作 开始
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
// 点击a 删除 当前a 所在的行(链接的爸爸的爸爸) node.removeChild(child)
// child = tr = tb.parentNode = a.parentNode.parentNode; node = tboby;
tbody.removeChild(this.parentNode.parentNode)
}
}
// for(var k in obj) {
// k 得到的是属性名
// obj[k] 得到是属性值
// }
</script>
</body>
</html>
9、事件(用户与页面交互)
事件三要素:事件源、事件类型、事件处理程序。
单击鼠标左键:出现 click 事件
加载一个页面:出现 load 事件
卸载一个页面:出现 unload 事件
9-1、注册事件(绑定事件)
①传统方式
利用 on 开头的事件 onclick
<button onclick = 'alert("hi~")'></button>
或者
btn.onclick = function(){}
同一元素同一事件只能注册一个处理函数,就算多注册几个,后面的会覆盖前面的,只处理最后一个函数。
var btn = document.querySelector('button');
// 1. 传统方式注册事件
btn.onclick = function() {
alert('hi');
}
btn.onclick = function() {
alert('你好');
}
按下button后只弹出 你好。
②方法监听注册方式
addEventListener() IE9以上支持
若IE9之前:attachEvent()
同一元素同一事件可以注册多个监听器,并按注册顺序依次执行。
addEventListener(type,linstener,useCapture)
type:时间类型字符串,比如click、mouseover (不能加on,记得加’’,因为是字符串)
listener:事件处理函数
useCapture:不写即为false,还有一个值为true。分别代表冒泡和捕捉。
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
alert(22);
})
btn.addEventListener('click', function() {
alert(33);
})
按下button后,弹出 22,点确定后再弹出 33.
9-2、删除事件(解绑事件)
①传统注册事件的删除
= null; 给其赋值空就行
var btn = document.querySelector('button');
btn.onclick = function() {
alert(11);
// 传统方式删除事件
divs[0].onclick = null;
}
按了一次按钮后,再按就不再弹出 11 了。
②方法监听注册方式的删除
removeEventListener(type,linstener[,useCapture])
删除的是函数,所以不再像之前一样用匿名函数,而是用自定义函数。并且调用函数时不需加()
var btn = document.querySelector('button');
// removeEventListener 删除事件
btn.addEventListener('click', fn) // 里面的fn 不需要调用加小括号
function fn() {
alert(22);
btn.removeEventListener('click', fn);
}
10、DOM事件流
10-1、事件对象
事件对象:是我们事件的一系列相关数据的集合,跟事件相关的。比如鼠标事件里面就包含了鼠标的相关信息,鼠标坐标等;如果是键盘事件里面就包含的键盘事件的信息,比如判断用户按下了哪个键。
event、evt、e (IE9以上)
window.event (IE678)
兼容性写法 e = e || window.event; 然后直接使用 e 就行了。
①事件对象常见的属性方法
事件对象的属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象 |
e.type | 返回事件的类型,比如click、mouseover 不带on |
e.preventDefault() | 阻止默认事件(默认行为) 比如 点击链接不跳转,点击提交按钮不提交 |
e.stopPropagation() | 阻止冒泡 |
②事件委托
对事件对象属性和事件冒泡的整合运用。
**核心原理:**给父节点添加侦听器, 利用事件冒泡影响每一个子节点。(面试可能会问)
详细解析在:
链接: 事件委托.
10-2、鼠标事件
事件 | 事件名称 |
---|---|
☆ 单击 | onclick |
双击 | ondblclick |
☆ 鼠标按下 | onmousedown |
☆ 鼠标抬起 | onmouseup |
☆ 鼠标悬浮 | onmouseover |
☆ 鼠标离开 | onmouseout |
☆ 鼠标移动 | onmousemove |
鼠标进入 | onmouseenter |
鼠标离开 | onmouseleave |
☆ 鼠标获得焦点 | onfocus |
☆ 鼠标失去焦点 | onblur |
①onFocus、onBlur
<!--获得焦点-->
<form>
姓名:<input type="text" onfocus="setStyle(this.id)" id="fname"><br><br>
密码:<input type="password" οnfοcus= "setStyle(this.id)" id="pwd">
</form>
<script>
function setStyle(txt){
document.getElementById(txt).style.background = "yellow";
}
</script>
<p></p>
<!--失去焦点-->
<form id="form1">
姓名:<input type="text" id="fname2" onBlur="upperCase()"><p></p>
密码:<input type="password" id="pwd2" onBlur="alert(this.id)">
</form>
<script>
function upperCase(){
var x = document.getElementById("fname2").value;
document.getElementById("fname2").value = x.toUpperCase();
}
</script>
②禁止鼠标事件
禁止鼠标右键菜单
contextmenu 主要控制应该何时显示上下文菜单,主要用于取消默认的上下文菜单。(也就是禁用鼠标的右键菜单)
// contextmenu 我们可以禁用右键菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault(); // 阻止默认行为
});
禁止鼠标选中
// 禁止选中文字 selectstart
document.addEventListener('selectstart', function(e) {
e.preventDefault();
});
③鼠标事件对象 MouseEvent
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对浏览器窗口可视区的X坐标 |
e.clientY | 返回鼠标相对浏览器窗口可视区的Y坐标 |
e.pageX | 返回鼠标相对文档页面的X坐标 |
e.pageY | 返回鼠标相对文档页面的Y坐标 |
e.screenX | 返回鼠标相对电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对电脑屏幕的Y坐标 |
④mouseover 和 mouseenter 区别
二者均是鼠标进入触发源时触发。
但是mouseover:鼠标经过自身盒子时会触发,经过子盒子还会触发。搭配mouseout,会冒泡。
而mouseenter:只是鼠标经过自身盒子时触发。 搭配mouseleave ,同样不会冒泡
10-3、键盘事件
事件 | 事件名称 |
---|---|
☆ 按键按下 | onkeydown 不能区别大小写 |
按键抬起 | onkeyup 不能区别大小写 |
按键按下抬起 | onkeypress (不识别功能键) ,但是能区别大小写 |
按一个按键并松开,执行顺序为 down -> press -> up。
down press在文本框中,他们触发事件的时候,文字还未落入文本框中;而 up 事件触发时,文字已经落入文本框中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.father {
width: 300px;
height: 300px;
background-color: pink;
margin: 100px auto;
}
.son {
width: 200px;
height: 200px;
background-color: purple;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
var father = document.querySelector('.father');
var son = document.querySelector('.son');
father.addEventListener('mouseenter', function() {
console.log(11);
})
</script>
</body>
</html>
键盘事件属性 keyCode
返回按键的ASCII码值。