目录
前言
Web APIS和JS基础关联性
DOM
获取DOM元素
事件
事件概述
操作元素
改变元素内容
改变常用元素的属性
改变表单元素的属性
改变元素的样式属性
自定义属性的操作
节点操作
为什么要学习节点操作?
节点概述
节点层级
创建节点?
添加节点
删除节点
复制节点
三种动态创建元素区别
示例
前言
Web APIS和JS基础关联性
????JS为基础阶段:主要学习ECMAScript标准规定的基本语法,但是做不了常用的网页交互效果; ? ? Web APIs阶段:Web APIs是W3C组织的标准,主要学习DOM和BOM,这部分是js独有的部分,主要是学习页面交互功能,但需要JS基础的课程内容做基础。 ?? ??? ??? ?Web APIs是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM),主要针对浏览器提供的接口,用于做交互效果。 ?? ??? ??? ?Web APIs一般都有输入和输出(函数的传参和返回值),Web APIs很多都是方法(函数); ?? ?一句话总结:JS基础学习、ECMAScript基础语法为后面做铺垫,Web APIs是JS的应用,大量使用JS基础语法做交互效果。
DOM
????????DOM(Document ObjectModel,简称DOM),是W3C组织推荐的处理可扩展标记语言(HTML或XML)的标准编程接口; ? ????????W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式; ? DOM树有如下定义: ? 文档:一个页面就是一个文档,DOM中使用document表示; ? 元素:页面中的所有标签都是元素,DOM中使用element表示; ? 节点:网页中的所有内容都是节点(如标签、属性、文本、注释等),DOM中使用node表示; ? 注意:DOM中如上所有内容都看做对象;
获取DOM元素
有四种方式获取DOM元素:根据ID获取、根据标签名获取、通过HTML5新增的方法获取、特殊元素获取。
使用getElementById()方法可获取带有ID的元素对象。
<body>
<div id = 'ids'>今天不上班</div>
</body>
<script>
var ids = document.getElementById('ids')
console.log(ids); // <div id = 'ids'>今天不上班</div>
</script>
使用getElementsByTagName()方法可返回带有指定标签名的对象的集合。
返回的是带有指定标签名的对象的集合(伪数组形式);所以操作里面的元素需要遍历;
<body>
<ul>
<li>好好学习</li>
<li>天天向上</li>
<li>报效祖国</li>
</ul>
</body>
<script>
var tag = document.getElementsByTagName('li')
console.log(tag);
for (var i = 0; i < tag.length; i++) {
console.log(tag[i]);
}
</script>
使用document.getElementsByClassName('类名'),根据类名返回元素对象集合(获取的也是伪数组形式);此处方法参数类名中不用加符号.
<body>
<div class="name">李雷和韩梅梅</div>
</body>
<script>
var nm = document.getElementsByClassName('name');
console.log(nm);
</script>
?使用document.querySelector('选择器'),根据指定选择器返回第一个元素对象;querySelector里面的参数要注意选择器需要加符号,如类选择器为.类选择器
<body>
<div class="name">李雷和韩梅梅</div>
<div class="name">语文和数学</div>
</body>
<script>
var nms = document.querySelector('.name');
console.log(nms); // <div class="name">李雷和韩梅梅</div>
</script>
使用document.querySelectorAll('选择器')返回指定选择器的所有元素对象集合;
<body>
<div class="name">李雷和韩梅梅</div>
<div class="name">语文和数学</div>
</body>
<script>
var nms = document.querySelectorAll('.name'); // 是一个伪数组
console.log(nms);
</script>
?获取body元素:document.body(一切都包含在里面,包括空格、注释等);
<body>
<div class="name">语文和数学</div>
<script>
// 获取body元素
var bodys = document.body;
console.log(bodys);
</script>
</body>
获取html元素:document.documentElement; ?// html标签内的都会包含在里面;
事件
事件概述
? ?JavaScript使得有能力创建动态页面,而事件是可以被JavaScript侦测到的行为(触发---响应机制); ? ?例如:网页中的每个元素都可以产生某些可以触发JavaScript的事件,例如:在用户点击某按钮时产生一个事件,然后去执行某些操作; 事件有三部分组成 事件源 事件类型 事件处理程序,也被称为事件三要素; ? ? 事件源:即事件被触发的对象,一般是按钮; ? ? 事件类型:即通过何种方式触发事件,如鼠标经过还是鼠标点击,或是键盘按下; ? ? 事件处理程序:一般是通过函数赋值的方式完成;
<body>
<!-- 事件源 按钮 -->
<button id='btn'>点我!</button>
</body>
<script>
// 事件源 按钮
var btn = document.getElementById('btn');
// 事件类型及事件处理
btn.onclick = function() {
alert('猜猜我是谁!')
}
</script>
基于此,执行事件的步骤如下: ? ? 1、获取事件源 ? ? 2、注册事件(绑定事件) ? ? 3、添加事件处理程序(采取函数赋值形式);
常见的鼠标事件如下:
鼠标事件?? | 触发条件 | onclick ? ? ? ? ? | 鼠标点击左键触发 | onmouseover ? ? | 鼠标经过触发 | onmouseout ? ? ? | 鼠标离开触发 | onfocus ? ? ? ? ? | 获得鼠标焦点触发 | onblur ? ? ? ? ? | 失去鼠标焦点触发 | onmousemove ? ? ? | 鼠标移动触发 | onmouseup ? ? ? ? | 鼠标弹起触发 | onmousedown ? ? | 鼠标按下触发 |
操作元素
DOM操作可改变网页内容、结构和样式,可以利用DOM操作元素来改变元素里面的内容、属性等。
改变元素内容
可利用elment.innerText或element.innerHTML改变元素中的内容;前者改变从元素起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉;后者也可以改变元素从起始位置到终止的全部内容,但是它可改变标签中的html标签和空格、换行
<body>
<!-- 事件源 按钮 -->
<button id='btn'>点我!</button>
<div>早上好</div>
</body>
<script>
// 事件源 按钮
var btn = document.getElementById('btn');
var divs = document.querySelector('div');
// 事件类型及事件处理
btn.onclick = function() {
// 点击按钮后,使用innerHTML方法 div内容变为晚安~,并加粗显示
divs.innerHTML = '<strong>晚安~</strong>';
// 点击按钮后,使用innerText方法 div内容变为<strong>晚安~</strong>
divs.innerText = '<strong>晚安~</strong>';
}
</script>
改变常用元素的属性
可通过DOM改变元素的属性,如src、href、title等
<body>
<img src="imgs/draw.jpg" alt="">
<div>drawing~</div>
</body>
<script>
// 事件源 按钮
var div = document.querySelector('div');
var img = document.querySelector('img');
// 事件类型及事件处理
img.onclick = function() {
// 点击图片后,div内容变为working~,图片变为work.jpg
img.src = "imgs/work.jpg";
div.innerText = 'working~';
}
</script>
改变表单元素的属性
利用DOM可以改变表单元素的type/value/checked/selected/disabled属性;
注意表单里面的内容是通过value属性改变的~
<body>
<button>点我!</button>
<input type="text" value="请输入内容">
</body>
<script>
var btn = document.querySelector('button');
var ipt = document.querySelector('input');
btn.onclick = function() {
// 按钮点击后 表单文本改变
ipt.value = '起风了~';
// 按钮点击后 按钮被禁用,此处用this替代btn是因为该动作是btn执行的,this即表示btn
// this 指向的是事件函数的调用者
this.disabled = true;
}
</script>
改变元素的样式属性
可通过JS修改元素的大小、颜色、位置等样式;通过element.style改变行内样式,通过element.className改变类名样式;使用element.style方式改变样式时,要注意style里面的属性要改为驼峰命名方式,如之前的背景样式为background-color,此处应该为backgroundColor;如字体为font-size,此时应该为fontSize;由于利用JS修改样式,产生的是行内样式,所以权重较高~
自定义属性的操作
获取属性值的方法有:
- element.属性
- element.getAttribute('属性');
区别:
第一种方法用于获取元素本身自带的属性;后者主要是为了获取自定义的属性(标准),即程序员自定义的属性;
设置属性值的方法有:
element.属性 = “值”? 用于设置内置元素的属性;
element.setAttribute('属性',‘值’)? 用于设置自定义元素的属性;
移除属性:
element.removeAttribute('属性');
H5自定义属性:
自定义属性是为了保D:\fronted\pink\arraytest.html D:\fronted\pink\1209.html存并使用数据,有些数据可以保存到页面中而不用保存到数据库中;
H5规定自定义属性要以data-开头作为属性名并且赋值;
<div data-index='1'></div>
// 或使用JS设置
element.setAttribute('data-index', 2);
获取H5自定义属性:
新增element.dataset.index或者element.dataset['index'], ie11才开始支持;
节点操作
为什么要学习节点操作?
获取元素通常有两种方式:
- 利用DOM提供的方法获取元素,如document.getElementById()、document.getElementsByClassName()、document.querySelector等,但该方式逻辑性不强、且比较繁琐;
- ?利用节点层级关系获取元素,如利用父子兄节点关系获取元素、逻辑性强,但是兼容性较差;
节点概述
? ? 网页中的所有内容都是节点(如标签、属性、文本、注释等),在DOM中,节点使用node表示; ? ? HTML DOM树中的所有节点均可通过JavaScript进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。 ? 一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。 ? 元素节点的nodeType为1;属性节点的nodeType为2;文本节点的nodeType为3(文本节点包含文字、空格、换行等),在实际开发中,节点操作主要操作的是元素节点。
节点层级
? 利用DOM树可把节点划分为不同的层级关系,常见的是父子兄层级关系。
? ?parentNode属性可返回某节点的父节点,注意是最近的一个父节点,若指定的节点无父节点则返回null;
<body>
<div id = 'ids'>今天是个晴朗的日子</div> -->
<ul>
<li>好好学习</li>
<li>天天向上</li>
<li>报效祖国</li>
</ul>
</body>
<script>
var li = document.querySelector('li');
console.log(li);
var ul = li.parentNode;
console.log(ul);
</script>
- 子级节点 parentNode.childNodes(标准)
parentNode.childNodes返回包含指定节点的子节点的集合,该集合为即时更新的集合;子集合包含所有的子节点,如元素节点、文本节点等;
<body>
<div id = 'ids'>今天是个晴朗的日子</div> -->
<ul>
<li>好好学习</li>
<li>天天向上</li>
<li>报效祖国</li>
</ul>
</body>
<script>
var ul = document.querySelector('ul');
console.log(ul);
var li = ul.childNodes;
console.log(li); // 会把换行等一切子元素都查出来
</script>
如果只想要获得里面的元素节点(nodeType为1),则需要专门处理,所以一般不直接使用childNodes;
<body>
<div id = 'ids'>今天是个晴朗的日子</div> -->
<ul>
<li>好好学习</li>
<li>天天向上</li>
<li>报效祖国</li>
</ul>
</body>
<script>
var ul = document.querySelector('ul');
var arr = [];
console.log(ul);
for(var i = 0; i < ul.childNodes.length; i++) {
if(ul.childNodes[i].nodeType === 1) {
// console.log(ul.childNodes[i]);
arr.push(ul.childNodes[i]);
}
}
console.log(arr);
</script>
- 子级元素节点 parentNode.children(非标准)?
? ?parentNode.children是一个只读属性,返回所有的子元素节点。注意:该方法只返回子元素节点,其余节点类型不返回; ? ?虽然该方法是一个非标准,但它得到了各个浏览器的支持,因此可以放心使用;
- 第一个子节点 parentNode.firstChild
? ?parentNode.firstChild返回第一个子节点,找不到子节点则返回null。同样,也是包含所有的节点;
- 最后一个子节点 parentNode.lastChild
? ?parentNode.lastChild返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点;
- 第一个子元素节点 parentNode.firstElementChild
? ?firstElementChild返回第一个子元素节点,找不到则返回null;ie9以上才支持
- 最后一个子元素节点 parentNode.lastElementChild
? ?parentNode.lastElementChild返回最后一个子元素节点,找不到则返回null。ie9以上才支持 ? ?实际开发中,经常使用parentNode.children[索引]方法获得指定位置的子元素节点,如获取第一个子元素节点:parentNode.children[0] ? ?获取最后一个子元素节点:parentNode.children[parentNode.children.length - 1];
- 当前元素的下一个兄弟节点node.nextSibling
node.nextSibling返回当前元素的下一个兄弟节点,找不到则返回null,返回的结果包含所有的节点;
- 当前元素的上一个兄弟节点node.previousSibling
node.previousSibling返回当前元素的上一个兄弟节点,找不到则返回null,返回的结果包含所有的节点;
- 当前元素的下一个兄弟元素节点?node.nextElementSibling
?node.nextElementSibling返回当前元素下一个兄弟元素节点,找不到则返回null;ie9以上才支持
- 当前元素的下一个兄弟元素节点?node.nextElementSibling
? ?node.previousElementSibling返回当前元素上一个兄弟元素节点,找不到则返回null;ie9以上才支持
所以要完美解决上述两种问题,要进行处理:
function getNextElementSibling(element) {
var el = element;
while(el = el.nextSibling) {
if(el.nodeType === 1) {
return el;
}
}
return null;
}
创建节点?
- document.createElement('tagName')
? ?document.createElement()方法创建由tagName指定的HTML元素,因为这些元素原先不存在,是根据我们的需求动态生成的,所以也称为动态创建元素节点;
添加节点
- node.appendChild(child)方法、?node.insertBefore(child,指定元素)
? node.appendChild(child)方法将一个节点添加到指定父节点的子节点列表末尾。node是父节点; ? node.insertBefore(child,指定元素)方法将一个节点添加到父节点的指定子节点前面。node是父节点;
<body>
<div id = 'ids'>今天是个晴朗的日子</div>
<ul>
<li>好好学习</li>
<li>天天向上</li>
<li>报效祖国</li>
</ul>
</body>
<script>
var ul = document.querySelector('ul');
var li = document.createElement('li');
var li1 = document.createElement('li');
// 在ul的最后一个li之后添加li1
ul.appendChild(li1);
// 在ul的第一个li之前添加li
ul.insertBefore(li,ul.children[0]);
console.log(ul);
</script>
删除节点
- ?删除节点?node.removeChild(child)
? node.removeChild(child)删除一个子节点,返回删除的节点。
复制节点
? ?node.cloneNode()方法返回调用该方法的节点的一个副本,也称为克隆节点/拷贝节点; ? ?若参数为空或false,则是浅拷贝,即只克隆节点本身,不克隆里面的子节点; ? ?若参数为true,则是深度拷贝,会复制节点本身及里面所有的子节点;
三种动态创建元素区别
document.write()是直接将内容写入页面的内容流,但是文档流执行完毕,会导致页面全部重绘(重绘是指重新创建一个页面,原先的页面都没了); element.innerHTML是将内容写入某个DOM 节点,不会导致页面全部重绘;该方法创建多个元素效率更高(不要采用拼接字符串方式,采取数组形式拼接),但结构稍复杂; createElement()创建多个元素效率稍低一点点,但是结构更清晰;
<body>
<div id = 'ids'>今天是个晴朗的日子</div>
<ul>
<li>好好学习</li>
<li>天天向上</li>
<li>报效祖国</li>
</ul>
</body>
<script>
var div = document.querySelector('div');
var date = +new Date();
// 采用拼接字符串形式
// for (var i = 0; i<1000;i++) {
// div.innerHTML += '<strong>心情好呀心情好</strong>';
// }
// var date1 = +new Date();
// var time = date1 - date;
// console.log(time); // 510ms
// 用数组形式形式
var arr = [];
for (var i = 0; i < 1000; i++) {
arr.push('<strong>心情好呀心情好</strong>');
}
div.innerHTML += arr.join('')
var date1 = +new Date();
var time = date1 - date;
console.log(time); // 1ms
</script>
示例
示例一:动态生成表格,点击删除按钮则会自动删除所在行
<body>
<!-- 表格应该只有头部,行和列都应该自动生成放在tbody下 -->
<table>
<thead>
<tr>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
<td>籍贯</td>
<td>操作</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
<script>
// 动态生成表格
var datas = [{
name: '小唐',
sexual: '女',
age: '18',
nativePlace: 'SiChuan'
}, {
name: '小吴',
sexual: '男',
age: '20',
nativePlace: 'ShanDong'
}, {
name: '小阳',
sexual: '女',
age: '18',
nativePlace: 'AnHui'
}, {
name: '小曹',
sexual: '男',
age: '19',
nativePlace: 'HeNan'
}];
// 将数据依次放在tbody里面的行
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
var tr = document.createElement('tr');
tbody.appendChild(tr);
for (var k in datas[i]) {
var td = document.createElement('td');
// 单元格存值
td.innerHTML = datas[i][k];
// 将单元格添加到行
tr.appendChild(td);
}
// 删除操作独立创建,使用href="javascript:;方法可以避免页面跳转,并且不会使链接上面加#"
var td1 = document.createElement('td');
td1.innerHTML = '<a href="javascript:;"> 删除 </a>'
tr.appendChild(td1);
}
// 点击删除按钮会删掉该行
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
// as的父节点是td,td的父节点是tr,要删除tr(父亲的父亲)
// this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
tbody.removeChild(this.parentNode.parentNode);
}
}
</script>
示例二:在留言板上输入内容,发布后,自动显示留言列表
<body>
<input type="text"></input>
<button>发布</button>
<ul></ul>
</body>
<script>
// 留言板点击发布后,显示留言内容
var button = document.querySelector('button');
var ul = document.querySelector('ul');
var input = document.querySelector('input');
button.onclick = function() {
console.log(input.value);
if (input.value === '') {
alert('请先输入内容,再发布!');
return
} else {
var li = document.createElement('li');
li.innerHTML = input.value;
// 后发布的在留言板后面
ul.appendChild(li);
}
}
</script>
示例三:鼠标滑过显示下拉框内容
<style>
.nav,
.lili {
list-style: none;
float: left;
}
li {
list-style: none;
}
</style>
<body>
<ul class='nav'>
<li class='lili'>
<a href=" "> QQ</a>
<ul>
<li>
<a href="javascript:;">私信</a>
</li>
<li>
<a href="javascript:;">评论</a>
</li>
<li>
<a href="javascript:;">@我</a>
</li>
</ul>
</li>
<li class='lili'>
<a href="javascript:;"> 微博</a>
<ul>
<li>
<a href="javascript:;">私信</a>
</li>
<li>
<a href="javascript:;">评论</a>
</li>
<li>
<a href="javascript:;">@我</a>
</li>
</ul>
</li>
<li class='lili'>
<a href="javascript:;"> 微信</a>
<ul>
<li>
<a href="javascript:;">私信</a>
</li>
<li>
<a href="javascript:;">评论</a>
</li>
<li>
<a href="javascript:;">@我</a>
</li>
</ul>
</li>
</ul>
</body>
<script>
// 鼠标经过显示下拉菜单
var nav = document.querySelector('.nav');
var lis = nav.children;
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function() {
this.children[1].style.display = 'block';
}
lis[i].onmouseout = function() {
this.children[1].style.display = 'none';
}
}
</script>
?
|