DOM
(一)DOM
1.DOM:
文档对象模型,是w3c组织推荐的处理可拓展标记语言(HTML或XML)的标准接口
2.DOM树:
(二)获取页面元素
1.根据id获取:
getElementById()获取带有id的元素对象,
var timer = document.getElementById('timer');
console.log(timer)
console.log(typeof timer)
console.dir(timer)
注意:文档页面从上往下加载,所以先要有标签再有script,script要写在标签下面
id是大小写敏感的字符串,该返回值是一个元素对象
console.dir( );打印返回元素对象,更好的查看里面的属性和方法,更好的查看里面的属性和方法
2.根据标签名获取:
getElementByTagName()返回带有指定标签名的对象集合
(1)返回的是获取过来元素对象的集合,以伪数组形式存在
如果页面中只有一个查找元素,返回的还是伪数组
如果页面中不存在被查找的元素,返回的是一个空的伪数组
var lis = document.getElementByTagName('li');
console.log(lis);
console.log(lis[0]);
//遍历获取的伪数组
for(var i = 0;i < lis.length ; i++){
console.log(lis[i])
}
(2)获取父元素内部的所有指定标签的子元素
注意:父元素必须是单个对象(必须指明是哪一个元素对象),获取的时候不包括父元素自己.
<ol id = 'ol'>
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ol>
<script>
var ol = document.getElementById('ol')
console.log(ol.getElementByTagName('li'))
</script>
3.通过HTML5新增的方法获取
(1)document.getElementByClassName('类名') : 根据类名返回元素对象集合
(2)document.querySelector(''选择器) : 根据指定选择器返回第一个元素对象,只能返第一个
注意:选择器需要添加对应符号 . # 等
<div class = "box">box1</div>
<div class = "box">box2</div>
<div id = "nav">
<li>li1</li>
<li>li2</li>
<li>li3</li>
</div>
类选择器
var firstBox = document.querySelector( " .box " ) console.log(firstBox)
id选择器
var secondBox = document.querySelector( " #nav " ) console.log(secondBox)
标签名选择器
var firstLi = document.querySelector( " li " ) console.log(firstLi)
(3)document.querySelectorAll( '选择器' ) : 根据指定选择器返回所有元素对象集合,以伪数组的形式
类选择器
var boxs = document.querySelectorAll( " .box " ) console.log(boxs)
id选择器
var box = document.querySelectorAll( " #nav " ) console.log(box)
标签名选择器
var lis = document.querySelectorAll( " li " ) console.log(lis)
var btn = document.getElementById('btn')
4.特殊元素获取(body/html):
(1)获取body标签 document.body 返回body元素对象
(2)获取html标签 document.documentElement 返回html元素对象
(三)给元素注册事件
事件:触发响应的一种机制
1.事件三要素:事件源;事件类型;事件处理程序
<button id = 'btn'>点击按钮</button>
(1)事件源:事件被触发的对象
var btn = document.getElementById('btn');
(2)事件类型:如何触发
(3)事件处理程序:通过函数赋值的形式
btn.onclick = function(){
alert('点击按钮弹出对话框')
}
2.执行事件的步骤
获取事件源=>注册事件(绑定事件)=>添加事件处理程序(采用函数赋值的形式)
3.常用的鼠标事件 on+ 触发
click鼠标左键点击 mouseover鼠标经过 mouseout鼠标离开 focus获得鼠标焦点
blur失去鼠标焦点 mousemove鼠标移动 mouseup鼠标弹起 mousedown鼠标按下
(四)操作DOM元素的属性
1.改变元素内容的两种方法
(1)element.innerText :
从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉
(2)element.innerHTML :
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
点击按钮显示当前日期/时间案例:
<button id="btn1">显示日期</button>
<div id="div1">当前日期为</div>
<p id="p1"></p>
<button id="btn2">显示时间</button>
<div id="div2">当前时间为</div>
<p id="p2"></p>
<script>
// 1.获取事件
var btn1 = document.getElementById('btn1')
var div1 = document.getElementById('div1')
// 2.绑定事件
btn1.onclick = function () {
div1.innerText = getDate();
}
function getDate() {
var date = new Date();
var year = date.getFullYear()
var month = date.getMonth()
var dates = date.getDate()
var arr = ["星期1","星期2","星期3","星期4","星期5","星期6","星期日"]
var day = date.getDay();
return year + '年,' + month + '月,' + '星期' + arr[day]
}
var p1 = document.querySelector('#p1');
p1.innerText = getDate()
// 1.获取事件
var btn2 = document.getElementById('btn2')
var div2 = document.getElementById('div2')
// 2.绑定事件
btn2.onclick = function () {
div2.innerText = getTime();
}
function getTime() {
var time = new Date();
var hour = time.getHours();
hour = hour < 10 ? '0' + hour : hour
var minute = time.getMinutes();
minute = minute < 10 ? '0' + minute : minute
var second = time.getSeconds();
second = second < 10 ? '0' + second : second
return hour + ':' + minute + ':' + second
}
var p2 = document.querySelector('#p2');
p2.innerText = getTime()
</script>
=>
(3)innerText和innerHTML的区别:
- innerText是非标准的 ; 会去除空格和换行 ; 不识别html标签
- innerHTML是w3c标准的 ; 不会去除空格和换行 ; 识别html标签
- 这两个属性是可读写的,可以获取元素中的内容
2.常用的属性操作
(1)innerText / innerHTML : 改变元素内容
(2)src / href : src图片属性 ; href a标签属性
(3)id / alt / title
案例:
点击按钮切换图片
<button id="btn1">显示图片1</button>
<button id="btn2">显示图片2</button>
<hr>
<img src="../../1.jpg" title="图片1">
<br>
<script>
//修改图片属性元素
var btn1 = document.querySelector('#btn1')
var btn2 = document.querySelector('#btn2')
var img = document.querySelector('img');
btn2.onclick = function(){
img.src = "../../2.jpg"
img.title = "图片2"
}
btn1.onclick = function(){
img.src = "../../1.jpg";
img.title = "图片1"
}
</script>
经典案例-分时问候:分时显示不同图片,显示不同问候语
思路分析:Date内置对象来判断不同时间 / 利用多分支语句判断不同图片
修改元素不同src属性来修改图片 / div元素显示不同问候语句
<img src="../../3.jpg" title="上午好">
<div>
<strong><em>上午好</em></strong>
</div>
<script>
var img = document.querySelector("img")
// var div = document.querySelector("div")
var em = document.querySelector("em")
var date = new Date();
var hour = date.getHours();
if(hour<9){
img.src = "../../3.jpg"
img.title="上午好"
em.innerHTML = "上午好"
}else if(hour<13){
img.src = "../../4.jpg"
img.title="中午好"
em.innerHTML = "中午好"
}else{
img.src = "../../5.jpg"
img.title="下午好"
em.innerHTML = "下午好"
}
</script>
注意:文字标签当使用div时,strong及em标签不生效,需要嵌套最近的<em>
3.表单元素操作属性
利用DOM可以操作表单元素属性:
type表单类型 / value默认值 / checked / selected / disabled 是否被禁用
<button>button</button>
<input type="text" value="value默认内容">
<script>
var btn = document.querySelector("button")
var inp = document.querySelector("input")
btn.onclick = function(){
inp.value = "修改value默认值"
inp.disabled = true
btn.disabled = true
}
</script>
经典案例:仿京东显示密码案例
需求:点击按钮将密码转为文本明文,可以查看密码明文;
思路:点击按钮,将密码类型改为文本框;
算法:利用flag变量,判断flag的值,如果为1就为文本框,flag = 1;如果为0就为文本框,flag = 0
<style>
body{
background-color: antiquewhite;
}
.box{
position: relative;
width: 400px;
border-bottom: 1px solid green;
margin: 100px auto;
}
.box input{
width: 370px;
height: 30px;
border: 0;
outline: none;
background-color: antiquewhite;
}
.box img{
position: absolute;
width: 24px;
top: 2px;
right: 2px;
}
</style>
<div class="box">
<label for="">
<img src="图片/14.jpg" id="eye" title="closeEye">
</label>
<input type="password" id="pwd">
</div>
<script>
var eye = document.getElementById("eye");
var pwd = document.getElementById("pwd");
var flag = 0;
eye.onclick = function(){
if(flag == 0){
eye.src = '图片/10.jpg'
eye.title = 'openEye'
pwd.type = 'text'
flag = 1
}else{
eye.src = '图片/14.jpg'
eye.title = 'closeEye'
pwd.type = 'password'
flag = 0
}
}
</script>
4.样式属性操作
(1)element.style: 行内样式操作 this.style.width = "300px"
var div = document.querySelector("div")
div.onclick = function(){
this.style.backgroundColor = "pink";
this.style.width = "300px"
}
注意:
- JS里面的样式采取驼峰命名法,比如fontSize/backgroundColor
- JS修改style样式操作,产生的是行内样式,css权重比较高
经典案例:仿淘宝关闭二维码案例
思路:利用样式显示和隐藏,display:none隐藏元素; display:block显示元素
<style>
.box{
width: 74px;
height: 88px;
border: 1px solid #ccc;
margin: 100px auto;
font-size: 12px;
text-align: center;
color: palevioletred;
position: relative;
}
.box img{
width: 60px;
margin-top: 5px;
}
.close-btn{
position: absolute;
top: -1px;
left: -16px;
width: 14px;
height: 14px;
border: 1px solid #ccc;
line-height: 14px;
font-family: Arial, Helvetica, sans-serif;
cursor: pointer;
}
</style>
<div class="box">
淘宝二维码
<img src="图片/12.jpg" alt="">
<i class="close-btn">x</i>
</div>
<script>
var btn = document.querySelector(".close-btn")
var box = document.querySelector(".box");
btn.onclick = function(){
box.style.display = 'none'
}
</script>
(2)element.className: 类名样式操作,适合于样式较多或功能较为复杂的情况
<style>
div{
background-color: purple;
width: 200px;
height: 200px;
font-size: 20px;
text-align: center;
margin:auto 100px ;
}
.change{
background-color: pink;
width: 100px;
height: 100px;
font-size: 10px;
text-align: center;
margin:auto 100px ;
}
</style>
<div class="noChange">文字</div>
<script>
var test = document.querySelector('div')
test.onclick = function(){
if(this.className == 'noChange'){
this.className = 'change'
}else{
this.className = 'noChange'
}
}
</script>
注意:
- 如果样式修改较多,可以采取操作类名方式更改元素样式
- class因为是个保守字,因此使用className来操作元素名属性
- className会直接更改元素的类名,会覆盖原先的类名
经典案例:密码框格式提示错误信息
如果用户离开密码框,里面输入密码个数不是6-16,则提示错误信息,否则提示输入正确信息
<style>
div{
width: 600px;
margin: 100px auto;
}
.message{
display: inline-block;
font-size: 12px;
color: #999;
background-color: pink;
padding-left: 20px;
}
.wrong{
color: red;
background-color: #ccc;
}
.right{
color: green;
background-color: #ccc;
}
</style>
<div class="register">
<input type="password" class="ipt">
<p class="message">请输入6~16位密码</p>
</div>
<script>
var ipt = document.querySelector(".ipt")
var message = document.querySelector(".message")
ipt.onblur = function(){
if(this.value.length<6 || this.value.length>16){
message.className = "message wrong"
message.innerHTML = "密码位数错误"
}else{
message.className = "message right"
message.innerHTML = "密码正确"
}
}
</script>
5.排他思想
如果有同一组元素,我们想要某一元素实现某样式,需要用到循环的排他思想算法:
(1)所有元素全部清除样式
(2)给当前元素设置样式
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
var btns = document.getElementsByTagName('button')
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
for (var j = 0; j < btns.length; j++) {
btns[j].style.backgroundColor = ""
}
this.style.backgroundColor = "mediumorchid"
}
}
</script>
经典案例:百度换肤
案例分析:图片利用循环点击注册事件,把当前图片的src路径取到,赋给body做背景
<style>
*{
margin: 0;
padding: 0;
}
body{
background: url(图片/1.jpg) no-repeat center top;
}
li{
list-style: none;
}
.baidu{
overflow: hidden;
margin: 50px 100px;
background-color: #fff;
width: 410px;
padding-top: 4px;
}
.baidu li{
float: left;
margin: 0 1px;
cursor: pointer;
}
.baidu img{
width: 100px;
}
</style>
<ul class="baidu">
<li><img src="图片/1.jpg"></li>
<li><img src="图片/19.jpg"></li>
<li><img src="图片/18.jpg"></li>
<li><img src="图片/2.jpg"></li>
</ul>
<script>
var imgs = document.querySelector(".baidu").querySelectorAll("img")
for(var i=0;i<imgs.length;i++){
imgs[i].onclick = function(){
document.body.style.backgroundImage = 'url('+ this.src +')'
}
}
</script>
经典案例:全选及取消全选
全选及取消全选:下面复选框的checked属性(选中属性)跟随全选按钮即可
下面复选框需要全部选中,才能上面全选才能选中:给下面所有的复选框绑定点击事件,每次点击,都要循环查看下面所有的复选框是否有没选中的,如果有没选中的,上面全选就不选中
<div class="wrao">
<table>
<thead>
<tr>
<th>
<input type="checkbox" id="j_cbAll">
</th>
<th>商品</th>
<th>价格</th>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<td>
<input type="checkbox">
</td>
<td>商品1</td>
<td>价格1</td>
</tr>
<tr>
<td>
<input type="checkbox">
</td>
<td>商品2</td>
<td>价格2</td>
</tr>
</tbody>
</table>
</div>
<script>
// 1.第一步
var j_cbAll = document.getElementById("j_cbAll")
var j_tbs = document.getElementById("j_tb").getElementsByTagName("input");
j_cbAll.onclick = function(){
// this.checked可以得到当前复选框的选中状态,true就是选中状态;false就是未选中状态
for(var i = 0;i<j_tbs.length; i++){
j_tbs[i].checked = this.checked;
}
}
// 2.第二步
for(var i = 0;i<j_tbs.length;i++){
j_tbs[i].onclick = function(){
// flag控制全选按钮是否选中
var flag = true;
// 每次点击下面的复选框都要循环检查小按钮是否被选中
for(var i = 0;i<j_tbs.length;i++){
if( ! j_tbs[i].checked){
falg = false;
break;
}
}
j_cbAll.checked = flag;
}
}
6.自定义属性操作
(1)获取属性值的两种方法
var div = document.querSelector("div")
- element.属性 console.log(div.id)
- element.getAttribute("属性") console.log(div.getgetAttribute("id"))
获取属性的两种方法区别:
- element.属性:获取内置属性值(元素本身自带的属性)
- element.getAttribute("属性") :主要获得自定义的属性(标准)
(2)设置属性值的两种方法
- element.属性 = " 值 " :设置内置属性值 div.id = " test "
- element.setAttribute( " 属性 " , " 值 ") ;[主要针对自定义属性,也可以设置自带的属性
div.setAttribute(" class " , " footer" ) //设置class为footer
注意:class特殊,这里面class不为className写法
设置属性的两种方法的区别:
- element.属性 = " 值 " : 主要针对设置内置属性
- element.setAttribute( " 属性 " , " 值 ") : 主要设置自定义属性(标准)
(3)移除属性的一种方法
- element.removeAttribute("属性") : div.removeAttribute(" class ")
重点案例:tab栏切换案例(重点案例 )
7.H5自定义属性
自定义属性的目的:是为了保存并使用数据.有些数据可以保存到页面中而不保存到数据中.
自定义属性获取是通过getAttribute( "属性" )获取的
有些自定义属性很容易引起歧义,不容易判断元素的内置属性还是自定义属性
<div getTime = "001"></div>
<script>
var div = document.querSelector("div");
console.log(div.getTime) //输出undefined,因为自定义属性不能通过元素属性来获取
console.log(div.getAttribute("getTime"))
</script>
(1)h5新增了自定义属性
h5新增自定义属性data-作为属性名,并且赋值.如<div data-index = "1">
或者使用JS设置element.setAttribute("data-index",2)
(2)获取h5新增属性值
- 兼容性获取 element.getAttribute("data-index")
- h5新增element.dataset.index 或者 element.dataset[ "index" ] //ie11才开始支持
- dataset是一个集合,里面存放了所有以data开头的自定义属性.
console.log(div.getAttribute("data-index"))
console.log(div.dataset.自定义属性名)
console.log(div.dataset.["自定义属性名"])
注意:自定义属性名由两个 - 连接符连接时getAttribute()使用正常,但dataset.自定义属性名 || dataset[ " 自定义属性名 " ]时,属性名需要写成驼峰命名法形式.
<div data-list-name = "007"></div>
console.log( div.getAttribute(" data-list-name") )
console.log(div.dataset.listName) || console.log(div.dataset[ "istName" ])
(五)操作DOM节点
(写完没自动保存 肝疼 过两天再写吧)
(六)DOM重点核心(总结)
文档对象模型,是w3c组织推荐的处理可扩展标记语言(HTML或XML)的标准编程接口
w3c已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式.
1.对于JavaScript,为了能够使JavaScript操作HTML,JavaScript就有了一套自己的dom编程接口
2.对于HTML,dom使得html形成一棵dom树,包含文档/元素/节点
注意:获取过来的DOM元素是一个对象,所以称为文档对象模型
关于dom操作,我们主要针对元素的操作.主要有创建 / 增 / 删 / 改 / 查 /属性操作 / 事件操作
1.创建
- document.write
- innerHTML
- createElement
2.增
- appendChild
- insertBefore
3.删
- removeChild
4.改
主要修改dom的元素属性,dom元素的内容 / 属性 / 表单的值等
- 修改元素属性:src / href / title 等
- 修改普通元素内容 : innerHTML / innerText
- 修改表单元素 : value / type / disabled 等
- 修改元素样式 : style / className
5.查
主要获取查询dom的元素
- dom提供的API方法: getElementById / getElementByTagName
- h5新增方法: querySelector / querySelectorAll
- 利用节点获取元素:
- 父(parentNode) / 子(children) / 兄(previousElementSibling / nextElementSibling)
6.属性操作
主要针对自定义属性
- setAttribute:设置dom的属性值
- getAttribute:获取dom的属性值
- removeAttribute:移除属性
7.事件操作
给鼠标注册时间,采取 事件源.事件类型 = 事件处理程序
(七)事件高级
1. 注册事件(事件绑定)
(1)注册事件概述 传统方式+监听器
给元素添加事件,称为注册事件或者绑定事件
注册事件有两种方式 : 传统方式 和 监听注册方式
传统方式:
利用on开头的事件,onclick
<button onclick = " alert(' hi ') "><button>
btn.onclick = ffunction( )
特点:注册事件唯一性:
{ 同一个元素同一个事件只能设置一个处理函数,最后注册的函数将会覆盖掉前面注册的处理函数 }
btns[0].onclick = function(){
alert( 11 ) ; }
btns[0].onclick = function(){
alert( 22 ) ; } //仅弹出 22
方法监听注册方式:
w3c标准,推荐方式
addEventListener() 是一个方法
ie9以前不支持此方法,可使用attachEvent代替
同一个元素同一个事件可以注册多个监听器
(2)addEventLIstener事件监听方式
eventTarget.addEventListener ( type , listener [ ,userCapture ] )
eventTarget.addEventListener()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象出发指定事件时,就会执行时间处理函数
该方法接受三个参数:
- type: 事件类型字符串,比如 click / mouseover , 里面的事件类型是字符串,必定带引号且不加on
- listener : 事件处理函数,事件发生时,会调用该监听函数
- userCapture :可选参数,是一个boolean类型值,默认false.
btns[1].addEventListener ( "click",function(){
alert( 11 ) ; } )
btns[1].addEventListener ( "click",function(){
alert( 22 ) ; } ) // 两次监听事件均执行,弹出11后弹出22
注意: 1. addEventListener里面的事件类型是字符串,必定添加引号且不加on
2. 同一个元素同一个事件可以添加多个监听器(事件处理程序)
(3)attachEvent事件监听方式(该特性是非标准的,生产环境不适用)
eventTarget.attachEvent (eventNameWithOn , callback ) ie9以前的版本支持
eventTarget.attachEvent()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,指定的回调函数就会被执行
该方法有两个参数:
- eventNameWithOn : 事件类型字符串,比如onclick / onmouseover ,这里还有需要带on
- callback : 事件处理函数,当目标出发事件时回调函数被调用
btn[1].attachEvent( 'onclick' , function(){
alert(111) ; } )
注册事件解决兼容性问题方案:(了解即可 可以使用但没必要)
兼容性处理原则 : 首先照顾大多数浏览器,再处理特殊浏览器
2. 删除事件(解绑事件)
(1)删除事件的方式
- 传统方式
eventTarget.onclock = null ;
var divs = document.querySelectorAll("div");
divs[0].onclick = function(){
alert(11) ; divs[0].onclick = null } // 仅第一次点击事件的时候弹出alert
- 方法监听注册方式
(1). eventTarget.removeEventListener( type , listener , useCapture ) ;
divs[1].addEventListener( "click" , fn ) //里面的fn不需要添加小括号
function fn(){
alert(22) ; divs[1].removeEventListener("click" , fn)}
(2)eventTarget.detachEvent( eventNameWithOn , callback );
divs[2].attachEvent("onclick",fn1) ;
function fn1(){
alert(33) ; div[2].detachEvent("onclick" , fn1)}
删除事件兼容性问题解决方案:
3.DOM事件流理论
JavaScript基础语法-dom-bom-js-es6新语法-jQuery-数据可视化echarts黑马pink老师前端入门基础视频教程(500多集)持续_哔哩哔哩_bilibili