DOM 的节点我们一般分为常用的三大类 元素节点/ 文本节点/ 属性节点
我们通过 getElementBy... 获取到的都是元素节点
我们通过getAttribute 获取的就是元素的属性节点
我们通过 innerText 获取到的就是元素的文本节点
// childNodes 属性 vs children
childNodes 所有节点
children 所有元素
// firstChild 和 firstElementChild
firstChild 第一个节点
firstElementChild 第一个元素节点
// lastChild 和 lastElementChild
lastChild 最后一个节点
lastElementChild 最后一个元素节点
// previousSibling 和 previousElementSibling
previousSibling 上一个兄弟节点
previousElementSibling 上一个兄弟元素节点
// nextSibling 和 nextElementSibling
previousSibling 下一个兄弟节点
previousElementSibling 下一个兄弟元素节点
// parentNode 和 parentElement 父节点
// getAttribute 属性节点重点
box.getAttribute("index") 获取box里面的index属性节点
box.getAttributes 获取box里面所有的属性节点
box.getAttributes[0] 获取box里面所有的第一个属性节点
创建节点:createElement
var odiv = document.createElement(“div”)
odiv.className=“aaa”
odiv.innerHTML=“我是新创建的节点”
插入节点:appendChild
box.appendChild(odiv) 直接在box子节点下最后面插入odiv节点
box.insertBefore(odiv,child) 在child节点前插入odiv节点
替换节点:replaceChild(新节点,老节点)
var odiv2=document.createElement(“div”)
odiv2.innerHTML=“222”
box.replaceChild(odiv2,child)
克隆节点 :cloneNode(true) 默认false 不克隆后代;true 克隆后代
var oCloneBox=box.cloneNode(true)
console.log(oCloneBox)
oCloneBox.id=“box2”
document.body.appendChild(oCloneBox)
<body>
<div id="box">
<div id="child">1111</div>
</div>
<script>
var odiv = document.createElement("div")
odiv.innerHTML = "我是新创建的节点"
//插入节点
box.appendChild(odiv)
</script>
</body>
<body>
<ul id="list"></ul>
<script>
var arr=[111,2222,3333,4444]
for (var i=0;i<arr.length;i++){
var oli=document.createElement("li") //创建节点
oli.innerHTML=arr[i] // 节点赋值
var obutton=document.createElement("button") //创建按钮
obutton.innerHTML="删除" // 节点赋值
obutton.οnclick=handler // 绑定事件
list.appendChild(oli) //插入节点
oli.appendChild(obutton) //插入节点
}
function handler(){
this.parentNode.remove() //获取父节点,移除所有子节点包含自己
}
</script>
</body>
可以通过 .nodeType 查找节点属性值(如1代表元素节点 2属性节点 3文本节点)
<body>
<div id="box">
<div>111</div>
</div>
<script>
var obox = document.querySelector(".box")
console.log(obox.childNodes)
for(var i=0;i<obox.childNodes.length;i++){
// console.log(obox.childNodes[i].nodeType)
if(obox.childNodes[i].nodeType===1){
console.log(obox.childNodes[i])
}
}
</script>
</body>
offsetWidth 和 offsetheight
offsetwidth:获取的是元素 内容+padding+border的宽度
offsetheight:获取的是元素 内容+padding+border的高度
clientWidth 和 clientheight
clientwidth:获取的是元素 内容+padding的宽度
clientheight:获取的是元素 内容+padding的高度
注意:
1.单位 数字
2.box-sizing 没有影响计算方式
3.display:none 拿不到值节点前插入odiv节点
offsetLeft 和 offsetTop
参考点:是定位父级;如果父级元素都没有定位,偏移量相当于body
clientLeft 和 clientTop就是左边框或上边框的值
可视窗口的尺寸
window.innerwidth 和Window.innerHeight 包含滚动条的宽度
document.documentElement.clientWidth 不包含滚动条的宽度
renderHTML(arr1)
function renderHTML(arr){
//list.innerHTML +=arr.map(function(item){
// return`<li> </li>`}).join("")
for(var i=0;i<arr.length;i++){
var oli =document.createElement("li")
oli.innerHTML=`<img src="${arr[i].url} alt=""> <h3>${arr[i].name}</h3>`
list.appendChild(oli)
}
}
inLoading=false
window.οnscrοll=function(){
var listHeight=list.offsetHeight
var listTop=list.offsetTop
var scrollTop=document.documentElement.scrollTop||document.body.scrollTop
var windowHeight=document.documentElement.clientHeight
if(isLoading)return
if((listHeight+listTop)-Math.round(windowHeight+scrollTop)<50){
console.log("到底了")
isloading=true
setTimeout(function(){
renderHTML(arr2)
isLoading=false},1000)
}
}
事件
一个事件由什么东西组成
1、触发谁的事件:事件源
2、触发什么事件:事件类型
3、触发以后做什么:事件处理函数
如:
var oDiv=document.queryselector("div")
oDiv.onclick=function(){}
// oDiv 就是这个事件的事件源
// onclick 就是这个事件的类型
// function(){} 这个事件的处理函数
*每当我们点击div的时候,就会执行事件函数内部的代码
*每点击一次,就会执行一次事件处理函数(如果有多个事件函数,后面的会覆盖前面的)
//dom2 绑定多个事件处理函数 按照顺序执行(兼容性 低版本的浏览器不支持 如IE:6/7/8)
box2.addEventListener(“click”,function(){ })
低版本:box2.attachEvent(“onclick”,function(){ })
代码1如下:
<body>
<button id="btn">抽奖</button>
<script>
btn.οnclick=function(){
console.log("谢谢惠顾")
this.disabled="disabled"}
</script>
</body>
//这个是在前端直接禁用,可以直接删除"disabled"代码重新点击"抽奖"
代码2如下:
<body>
<button id="btn">抽奖</button>
<script>
btn.οnclick=function(){
console.log("谢谢惠顾")
this.οnclick=null}
</script>
</body>
// dom节点.οnclick=null 赋值空
代码3如下:
<body>
<button id="btn">抽奖</button>
<script>
function handler(){
console.log("谢谢惠顾")
this.removeEventListener("click",handler)
}
btn.addEventListener("click",handler)
</script>
</body>
//btn.removeEventListener("click",handler)移除掉函数
常用事件类型
//鼠标事件 click单击鼠标
dbclick 双击鼠标
contextmenu 右键单击
mousedown 鼠标按下
mousemove 鼠标移动
mouseup 鼠标抬起
//移入移出 mouseover mouseout (放在子元素上也会触发)
//移入移除 mouseenter mouseleave (放在子元素上不会触发)
//键盘事件 onkeydown 按下键盘
onkeyup 抬起键盘
如:
<body>
<input type="text" id="username">
<script>
//window,document,输入框 input
uername.onkeydown = function(){
console.log("按下键盘")
}
</script>
</body>
浏览器事件
load 页面全部加载完毕
scroll 浏览器滚动的时候触发
表单事件
change 表单内容改变事件(获取焦点、失去焦点的对比里面的内容不一样才会触发)
input 表单内容输入事件 (内容不一样)
submit 表单提交事件
reset 表单重置事件
focus 获取焦点 // blur 失去焦点
触摸事件
touchstart 开始触摸
touchmove 触摸移动的时候
touchend 结束触摸
事件对象:
你触发一个点击事件的时候,你点在那个位置了,坐标是多少
你触发一个键盘事件的时候,你按的是哪个按钮
代码如下:
<body>
<input type="text" id="username">
<div id="box"></div>
<script>
box.onοnkeyup=function(evt){
console.log(evt)
}
//打印形参,里面有个keyCode值代表键盘上的键位,13代表回车键
username.onkeyup = function(evt){
console.log(evt.keyCode)
if(evt.keyCode===13){
console.log("创建节点")
}
}
</script>
</body>
鼠标对象事件
<body>
<div id="box"></div>
<script>
box.onclick = function (evt){
console.log(evt.clientX,evt.clientY)
}
// clientX clientY 距离浏览器可视窗口的左上角的坐标
// pageX pageY 距离文档页面左上角的坐标
// offsetX offsetY 距离触发元素的左上角的坐标值
</script>
</body>
代码如下:
<style>
*{margin:0;padding: 0}
#box{width: 100px;height: 100px;background-color: yellow}
body{width: 2000px;height: 2000px}
#box p{width: 300px;
height: 300px;
background-color:red ;
position: absolute;
top:100px;
left: 100px;
display: none;
/* pointer-events: none; 穿透,鼠标会跟着p标签
}
</style>
</head>
<body>
<div id="box">
kerwin的头像
<p>
kerwin的介绍
</p>
</div>
<script>
box.onmouseover = function (){
this.firstElementChild.style.display="block"
}
box.onmouseout = function (){
this.firstElementChild.style.display="none"
}
box.onmousemove = function (evt){
console.log(evt.offsetX,evt.offsetY )
this.firstElementChild.style.left = evt.offsetX+10+"px"
this.firstElementChild.style.top = evt.offsetY+10+"px"
}
//clientX clientY 距离浏览器可视窗口的左上角的坐标
</script>
</body>
代码如下:
head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{margin:0;padding: 0}
#box{width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
left:100px;
top:100px;
}
body{width: 2000px;height: 2000px}
</style>
</head>
<body>
<div id="box">
</div>
<script>
box.onmousedown =function (){
document.onmousemove =function (evt){
//.log("move")
var x=evt.clientX-box.offsetWidth/2
var y=evt.clientY-box.offsetHeight/2
if(y<=0) y=0
if(x<=0) x=0
var a=document.documentElement.clientWidth-box.offsetWidth
var b=document.documentElement.clientHeight-box.offsetHeight
if(x>=a) x=a
if(y>=b) y=b
box.style.left=x+"px"
box.style.top=y+"px"
}
}
box.onmouseup = function (){
console.log("up")
document.οnmοusemοve=null
}
</script>
</body>
子标签的事件会触发父标签的事件(事件会往上传递)
标准事件流:
捕获:window–document–html–body–outer–center–inner
目标:inner
冒泡:inner–cente–outer–body–html–document–window
点击inner上的事件,会往上触发center。。。等事件(默认情况,只在冒泡的时候触发)
evt.stopPropagation()阻止事件传播(兼容版本 IE版本:evt.cancelBubble=true 实现阻止)
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul id="list"></ul>
<script>
var arr=[111,2222,3333,4444]
for (var i=0;i<arr.length;i++){
var oli=document.createElement("li")
oli.innerHTML=arr[i]
var obutton=document.createElement("button")
obutton.innerHTML="删除"
obutton.οnclick=handler
oli.appendChild(obutton)
oli.οnclick=function (){
location.href="http://www.baidu.com"
}
list.appendChild(oli)
}
function handler(evt){
this.parentNode.remove()
evt.stopPropagation()
}
</script>
</body>
</html>
代码如下:return false 和 evt.preventDefault()
dom1:
myform.onsubmit =function(){
console.log("submit","校验表单内容")
reture false //阻止表单提交
}
dom2:
document.addEventListener("contextmenu" ,function (evt){
evt.preventDefault()
})
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{margin:0;padding:0 }
li{list-style: none}
#box{width: 50px;height: 100px;background-color: #76818c;
border:1px solid black;
display: none;
position: absolute}
ul li:hover{background-color: #3ca5f6}
</style>
</head>
<body>
<ul id="box">
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
<script>
document.addEventListener("contextmenu" ,function (evt){
console.log("右键")
evt.preventDefault()
box.style.display="block"
var x=evt.clientX
var y=evt.clientY
var a=document.documentElement.clientWidth-box.offsetWidth
var b=document.documentElement.clientHeight-box.offsetHeight
if(x>=a) x=a
if(y>=b) y=b
box.style.left=x+"px"
box.style.top=y+"px"
})
document.οnmοuseup=function (){
box.style.display="none"
}
</script>
</body>
</html>
事件委托
就是把我要做的事情委托给别人来做
因为我们的冒泡机制,点击子元素的时候,也会同步触发父元素的相同事件
所以我们就可以把子元素的事情委托给父元素来做
target
target 这个属性就是事件对象里面的属性,表示你点击的目标
当你触发点击事件的时候,你点击在哪个元素上,target就是哪个元素
这个target也不兼容,在IE下使用 srcElement
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ou1=document.querySelector("ul")
ou1.addEventListener("click",function(e){
//console.log("我是ul的点击事件,我被触发了")
e=e||e.srcElement
var target=e.target||e.srcElement
console.log(target)
})
</script>
<body>
list.onclick = function(evt){
//console.log(evt.target.nodeName)
if(evt.target.nodeName==="BUTTON"){
evt.target.parentNode.remove()
}
}
上个例子自定义右键菜单,也可以用target来实现 li 里面的函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{margin:0;padding:0 }
li{list-style: none}
#box{width: 50px;height: 100px;background-color: #76818c;
border:1px solid black;
display: none;
position: absolute}
ul li:hover{background-color: #3ca5f6}
</style>
</head>
<body>
<ul id="box">
<li class="aaa">111</li>
<li class="bbb">222</li>
<li class="ccc">333</li>
</ul>
<script>
document.addEventListener("contextmenu" ,function (evt){
// console.log("右键")
evt.preventDefault()
box.style.display="block"
var x=evt.clientX
var y=evt.clientY
var a=document.documentElement.clientWidth-box.offsetWidth
var b=document.documentElement.clientHeight-box.offsetHeight
if(x>=a) x=a
if(y>=b) y=b
box.style.left=x+"px"
box.style.top=y+"px"
})
document.οnmοuseup=function (){
box.style.display="none"
}
box.addEventListener("click",function (evt){
// console.log(evt.target)
target=evt.target||evt.srcElement
if(target.className==="aaa"){
console.log("1")
}
if(target.className==="bbb"){
console.log("2")
}
if(target.className==="ccc"){
console.log("3")
}
})
</script>
</body>
</html>
var reg= / \d /
console.log(reg.test("abc")) // 返回 false
console.log(reg.test("123")) // 返回 true (123为一个数字)
var reg= / \D /
console.log(reg.test("123abc")) // 返回 true
console.log(reg.test("123")) // 返回 false
var reg= / \s /
console.log(reg.test("12 3abc")) // 返回 true
console.log(reg.test("12\n3")) // 返回 true (\n换行符)
console.log(reg.test("123abc")) // 返回 false
var reg= / \S /
console.log(reg.test("12 bc")) // 返回 true
console.log(reg.test(" \n\n ")) // 返回 false (\n换行符)
console.log(reg.test(" ")) // 返回 false
var reg= / \w /
console.log(reg.test("1—")) // 返回 true
console.log(reg.test("12aab ")) // 返回 true
console.log(reg.test("&*")) // 返回 false
var reg= / \w /
console.log(reg.test("1—")) // 返回 false
console.log(reg.test("12aab ")) // 返回 false
console.log(reg.test("&*")) // 返回 true
var reg= / \w /
console.log(reg.test("1\n—")) // 返回 true
console.log(reg.test("\n")) // 返回 false
console.log(reg.test("&*")) // 返回 true
8 . \ 转义字符 //1.2 2.3 通过 \ 把 . 转义成普通字符
如:
var reg= / \d \.\d/
console.log(reg.test("1.2")) // 返回 true
console.log(reg.test("1a2)) // 返回 false
1 ^ 第一位
如:var reg= /^ \d / (第一位必须是数字)
console.log(reg.test("abc123")) // 返回 false
console.log(reg.test("123abc")) // 返回 true (第一位为数字)
2 $ 最后一位
如:var reg= / \d$ / (最后一位必须是数字)
console.log(reg.test("123abc")) // 返回 false
console.log(reg.test("abc123")) // 返回 true (最后一位为数字)
1 * 0~多次
如:var reg= /\d* /
console.log(reg.test("abc123")) // 返回 true
console.log(reg.test("123abc")) // 返回 true
2 + 1~多次
如:var reg= / \d+ / (包含至少1位数字)
console.log(reg.test("abc")) // 返回 false
console.log(reg.test("abc1")) // 返回 true
3 ? 0~1次
如:var reg= / \d?/
console.log(reg.test("abc")) // 返回 true
console.log(reg.test("abc1")) // 返回 true
4 {n} 指定次数 ( {n,} 表示大于等于n次 {n,5}表示大于等于n 小于等于5)
/abc{2}/ 表示必须包含abcc( {}只匹配最近的一位字符)
如:var reg= / \d{3}/ (出现3次数字)
console.log(reg.test("abc")) // 返回 false
console.log(reg.test("ab12")) // 返回 false
console.log(reg.test("abc123")) // 返回 true
1 () 把字符括起来表示一个整体
如:var reg= /(abc){2}/ (表示包含abcabc)
console.log(reg.test("abc123")) // 返回 false
console.log(reg.test("abcabc123")) // 返回 true
2 | 或
如:var reg= / a|b / (包含a或b)
console.log(reg.test("ac")) // 返回 true
console.log(reg.test("cb1")) // 返回 true
如:var reg= / abc|def|xyz/ (表示abc、def、xyz整体中的一个)
如:var reg= / (abc|def)/ (表示abc或加上d、e、f中的任意)
console.log(reg.test("ab")) // 返回 false
onsole.log(reg.test("abc")) // 返回 true
console.log(reg.test("abcef")) // 返回 true
3 [ ] 代表1个
如:var reg= / [abcdef]/ (表示abcdef中的任意1位)
onsole.log(reg.test("xyz")) // 返回 false
console.log(reg.test("axyz")) // 返回 true
如:var reg= /[abcdef]{3,5}/ (出现3~5次任意字符)
console.log(reg.test("abc")) // 返回 true
console.log(reg.test("ab12")) // 返回 false
[a-zA-Z0-9_] 等价 \w
[0-9] 等价 \d
[^abc] 取反,表示有1个不在abc里面的任意字符
如:var reg= /[^abc]/
console.log(reg.test("a")) // 返回 false
console.log(reg.test("abz")) // 返回 true (z在abc里面)
如:var reg= /\d{3}/ (表示捕获3个数字)
console.log(reg.exec("abc123aaa")) // 返回 123
console.log(reg.test("abcabc")) // 返回 null
如:var datestr="time is 2029-01-01 12:20:20"
var reg= /\d{4}-\d{1,2}-\d{1,2}/ (表示捕获时间2029-01-01)
var newdatestr=reg.exec(datestr)
// console.log(newdatestr[0]) // 返回 2029-01-01
console.log(newdatestr[0].split("-").join("/")) // 返回 2029/01/01 (split分割)
g 全局表示符 i 不分字母大小写
如:
var datestr="time is from2029-01-01 12:20:20 to 2029-11-11 12:20:20"
var reg= /\d{4}-\d{1,2}-\d{1,2}/ g
var newdatestr1=reg.exec(datestr) // 只能捕获时间2029-01-01
console.log(newdatestr1[0]) // 返回 2029-01-01
var newdatestr2=reg.exec(datestr) //捕获下个时间2029-11-11
console.log(newdatestr2[0]) // 返回 2029-11-11)
如:
var reg= /\d{1,4}/ (贪婪)
console.log(reg.exec("abc12345aaa")) // 返回 1234
如:
var reg= /\d{1,4}?/ (?非贪婪)
console.log(reg.exec("abc12345aaa")) // 返回 1
正则.test(字符串)
正则.exec(字符串)
字符串.replace替换 search查找一个字符 match匹配拿到一个字符
replace
如:
var reg= "adefaea"
var newreg=reg.replace("a","*")
console.log(newreg) // 返回 *defaea
var newreg=reg.replace(/a/g,"*")
console.log(newreg) // 返回 *def*e*
search
如:
var reg= "adefaea"
var newreg=reg.search("d")
console.log(newreg) // 返回 1
var newreg=reg.search(/a/g)
console.log(newreg) // // 返回 0
match 捕获内容
如:
var reg= "adefaea"
var newreg=reg.match("ad")
console.log(newreg) // 返回 ad
如:
var datestr="time is from2029-01-01 12:20:20 to 2029-11-11 12:20:20"
var newdatestr=datestr.match(/\d{4}-\d{1,2}-\d{1,2}/ g)
console.log(newdatestr) // 返回 ['2029-01-01','2029-11-11']
案例
<body>
<form>
<input type="text">
</label>
<p>
<span>弱</span>
<span>中</span>
<span>强</span>
</p>
</form>
<script>
var ospan=document.querySelector("span")
var oinput=document.querySelector("input")
var reg1 = /\d/
var reg2 = /[a-z]/i
var reg3 = /[~!@#$%^&*()_+?":><]/
oinput.οninput=function (evt){
console.log(this.value)
//console.log(evt.target.value)
var level = 0
if(reg1.test(this.value)) level++
if(reg2.test(this.value)) level++
if(reg3.test(this.value)) level++
//console.log(level)
for (var i=0;i<ospan.length;i++){
if(i<level){
ospan[i].classList.add("active")
}
}
}
</script>
</body>
五、this指向
1.this 关键字(谁调用我,this就指向谁)
// 全局
//console.log(this) // window
function test(){
console.log(this)}
window.test() // window
// 对象
setInterval(function (){
console.log(111,this)
},2000) //this指向window
// 事件绑定的this
box.οnclick=function (){
console.log(this)
} //this 指向box节点
2.改变this指向
// call或apply 执行函数,并改变this执行为函数的第一个参数
//call支持多个参数;apply两个参数,第二个参数是一个数组
// bind 改变this指向为函数第一个参数,不会自动执行函数
var fun1= obj1.getName.bind(obj2)
console.log(fun1)}
fun1() // 指向obj2
// oDiv 就是这个事件的事件源
// onclick 就是这个事件的类型
总结
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 517ttc.cn 版权所有 赣ICP备2024042791号-8
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务