console.log(document);
console.log(typeof document);
//查看document对象的方法和属性
for(var i in document){
console.log(i)
}
DOM把文档视为一棵树形结构,也称为节点树。节点之间的关系包括:上下父子关系,相邻兄弟关系
相邻兄弟关系
<html lang="en">
<head>
<meta charset="UTF-8">
<title>节点title>
head>
<body>
<div id="box">
<p>我是p标签p>
<span>hellospan>
<i>i标签i>
<div>我是divdiv>
<em>em标签em>
div>
<script>
var oBox = document.getElementById("box");
var nodes = oBox.childNodes;
console.log(nodes);//节点的集合 NodeList类型
console.log(nodes[3]);//直接可以获取到节点
console.log(nodes.item(5));//直接可以获取到节点
//document的节点类型 名称 和值
console.log(document.nodeType);//9
console.log(document.nodeName);//#document
console.log(document.nodeValue);//null
//元素节点的类型 名称和 值
console.log(nodes[1].nodeType);//1
console.log(nodes[1].nodeName);//节点名称就是标签名 大写
console.log(nodes[1].nodeValue);//null
//文本节点的类型 名称和 值(文本节点没有子节点)
console.log(nodes[0].nodeType);//3
console.log(nodes[0].nodeName);//#text
console.log(nodes[0].nodeValue);//当前的文本内容
//注释节点的类型 名称和 值
console.log(nodes[9].nodeType);//8
console.log(nodes[9].nodeName);//#comment
console.log(nodes[9].nodeValue);//当前被注释的内容
var myAttr = document.createAttribute("my");
myAttr.value = "yes";
console.log(myAttr);
console.log(myAttr.nodeType);//2
console.log(myAttr.nodeName);//my 属性节点是标准的键值对形式 属性名就是节点名称
console.log(myAttr.nodeValue);//yes 属性值就是节点的值
script>
body>
html>
getElementsByTagName
方法来获取页面上的某一种标签 var oLis = document.getElemerntsByTagName("li");
console.log(oLis);
oLis[0].style.backgroundColor = "green";
oLis[1].style.backgroundColor = "green";
oLis[2].style.backgroundColor = "green";
oLis[3].style.backgroundColor = "green";
//或者
var oLis1 = document.getElementsByTagName("li")[0];
oLis1.style.backgroundColor = "pink";
getElementByID
方法来获取页面上的某一种标签 var oBox = document.getElementById("box");
console.log(oBox);//得到整个元素
oBox.style.backgroundColor = "red";
getElementsByClassName
方法来获取页面上的某一种标签getElementsByTagName
使用方法一致 // IE8不认识此方法:对象不支持“getElementsByClassName”属性或方法
var oLi1 = document.getElementsByClassName("li1");
oLi1[0].style.backgroundColor = "green";
getElementsByName
方法来获取页面上的某一种标签getElementsByTagName
使用方法一致 var oLi = document.getElementsByName("oli");
oLi[0].style.height = "300px";
querySelector
和querySelectorAll(IE8+)
querySelector
和querySelectorAll
方法参数必须是符合css选择器语法规则的字符串。其中querySelector
返回的是一个元素,querySelectorAll
返回的是一个集合,一个NodeList对象(可以使用数组的forEach方法)
<html lang="en">
<head>
<meta charset="UTF-8">
<title>新的选择器title>
head>
<body>
<ul class="outer">
<li>11li>
<li>22li>
<li>33li>
ul>
<script>
var oLis = document.querySelectorAll(".outer>li");
console.log(oLis);//[li,li,li]
console.log(oLis[0]);
var oLi = document.querySelector(".outer>li");
console.log(oLi);
var oLi2 = document.querySelector(".outer>li:nth-child(2)");
console.log(oLi2);
script>
body>
html>
var oUl = document.getElementsByTagName("ul")[0];
var oLis = oUl.getElementsByTagName("li");
console.log(oLis.length);
//直接陷入死循环 因为getElementsByTagName获取的元素是动态的,所以我们遍历的长度是获取元素的长度
// 每次插入一个 长度就会加1 所有永远运行不完
for (var i = 0; i < oLis.length; i++) {
oUl.appendChild(document.createElement("li"))
}
console.log(oLis.length);
// querySelectorAll获取的元素就是静态的
var oLis = document.querySelectorAll("ul li");
console.log(oLis.length);
for (var i = 0; i < oLis.length; i++) {
document.querySelector("ul").appendChild(document.createElement("li"))
}
console.log(oLis.length);
<ul id="box">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var oBox = document.getElementById("box");
//children:获取所有的子元素节点(IE678可以获取到注释节点,如果要兼容IE678 则避免书写注释)
var oLis = oBox.children;
console.log(oLis);
//parentNode:获取当前元素的父节点(全兼容)
console.log(oLis[0].parentNode);//ul
console.log(oLis[0].parentNode.parentNode);//body
console.log(oLis[0].parentNode.parentNode.parentNode);//html
console.log(oLis[0].parentNode.parentNode.parentNode.parentNode);//#document
console.log(oLis[0].parentNode.parentNode.parentNode.parentNode.parentNode);//null
//previousSibling:在ie678中获取的上一个兄弟元素节点,在其他浏览器中 获取的是上一个兄弟节点(可能是文本节点等等。。。)
//previousElementSibling:在浏览器中获取上一个兄弟元素节点 ie678不识别
console.log(oLis[1].nextSibling); //ie的 #text
console.log(oLis[1].nextElementSibling); //其他的 1
//获取上一个兄弟节点
console.log(oLis[3].previousSibling);
console.log(oLis[3].previousElementSibling);
// 兼容性写法
if (oLis[3].previousElementSibling){
console.log(oLis[3].previousElementSibling);
}else{
console.log(oLis[3].previousSibling);
}
// 获取下一个兄弟
console.log(oLis[3].nextElementSibling);
//获取第一个子节点
console.log(oBox.firstElementChild);
//获取最后一个子节点
console.log(oBox.lastElementChild);
//获取上一个兄弟元素的兼容性封装
function getPrevSibling(ele){
if(ele.previousElementSibling){
return ele.previousElementSibling;
}else{
return ele.previousSibling;
}
}
console.log(getPrevSibling(oLis[2])); //2
//获取下一个兄弟元素的兼容性封装
function getnextSibling(ele){
if(ele.nextElementSibling){
return ele.nextElementSibling;
}else{
return ele.nextSibling;
}
}
console.log(getnextSibling(oLis[2])); //4
获取body元素
document.body
==document.getElementsByTagName('body')[0]
获取head元素
document.head
==document.getElementsByTagName('head')[0]
获取html元素
document.documentElement
==document.getElementsByTagName('html')[0]
元素 . on+事件名称 = 函数
focus
获取焦点事件
blur
失去焦点事件
练习:模拟placeholder
<input type="text" id="ipt" value="请输入电话号码">
<script>
var oIpt=document.getElementById("ipt"); //获取元素
oIpt.onfocus=function(){
//绑定事件
if(oIpt.value==="请输入电话号码"){
oIpt.value="";
}
}
oIpt.onblur=function(){
if(oIpt.value===""){
oIpt.value="请输入电话号码";
}
}
script>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点击事件title>
<style>
#box{
width: 300px;
height: 200px;
background: pink;
}
style>
head>
<body>
<div id="box">我是boxdiv>
<script>
var oBox = document.getElementById("box");
// 当在一个元素上按下鼠标 并又抬起的时候 才会触发click事件
//右键也可能触发,但是右键的点击有专门的的事件 oncontextmenu
oBox.onclick = function () {
// alert(1);
}
// 右键事件 按下 并抬起的时候 弹出
oBox.oncontextmenu=function(){
alert(2);
//取消默认右键的菜单弹出 取消默认事件 写在最后
return false;
}
//双击事件
oBox.ondblclick = function () {
alert("用户双击");
}
script>
body>
html>
练习:点击循环变色
开关法:
1.先获取元素
2.元素绑定事件
3.定义一个变量flag开关保存当前状态
4.事件发生后判断状态
5.改变完成后,改变开关的状态
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box{
width: 300px;
height: 200px;
background: red;
}
</style>
</head>
<body>
<div id="box">我是div</div>
<script>
var oBox=document.getElementById("box")
var flag=true;
oBox.onclick=function(){
if(flag){
oBox.style.background="pink";
}else{
oBox.style.background="red";
}
flag=! flag;
}
</script>
</body>
</html>
累加求余法
1.获取元素
2.绑定点击事件
3.定义一个变量保存当前状态
4.每次点击变量加1,然后和2取余看是否为0判断奇偶来改变
<body>
<div id="box">我是div</div>
<script>
var oBox=document.getElementById("box");
var num=0;
oBox.onclick=function(){
num++;
if(num % 2===0){
oBox.style.background="red";
}else{
oBox.style.background="pink";
}
}
</script>
</body>
一般绑定给input或document
onkeydown:键盘按下
onkeyup:键盘抬起
练习:检测剩余字数
<html lang="en">
<head>
<meta charset="UTF-8">
<title>检测剩余字数title>
<style>
textarea{
border: 1px solid #ccc;
outline: none;
}
style>
head>
<body>
<textarea id="text" cols="30" rows="10" >textarea>
<p>还剩余 <span id="reduce">100span> 个字p>
<script>
/*
* 用户在表单中输入内容,剩余字数减少,
* 当剩余字数减少到负数的时候 把提示字数变成红色
*
* 1、获取标签
* 2、书写键盘抬起事件 当抬起的时候 去计算剩余字数
* 3、获取表单输入的长度
* 4、计算剩余的字数是多少
* 5、把计算好的剩余字数给到 reduce标签中
* 6、检测剩余字数 小于0的时候,让标签变红 并且让textarea的边框变红
* 7、当用户把字数重新减小,然后样式变成正常
*/
// 1、获取标签
var oReduce = document.getElementById("reduce");
var oText = document.getElementById("text");
// 2、书写键盘抬起事件 当抬起的时候 去计算剩余字数
oText.onkeyup = function () {
// 3、获取表单输入的长度
var oTextLen = oText.value.length;
// console.log(oTextLen);
// 4、计算剩余的字数是多少
var reduceTextNum = 100 - oTextLen;
// 5、把计算好的剩余字数给到 reduce标签中
oReduce.innerHTML = reduceTextNum;
// 6、检测剩余字数 小于0的时候,让标签变红 并且让textarea的边框变红
if (reduceTextNum < 0){
oReduce.style.color = "red";
oText.style.border = "1px solid red";
}else{
// 7、当用户把字数重新减小,然后样式变成正常
oReduce.style.color = "#000";
oText.style.border = "1px solid #ccc";
}
}
script>
body>
html>
input:当表单内容改变时触发
change:当表单内容改变并且失去焦点时候触发
练习:
模拟数据双向绑定
<html lang="en">
<head>
<meta charset="UTF-8">
<title>input和change事件title>
head>
<body>
<input type="text" id="ipt">
<br>
<span id="text">span>
<script>
/*
* 模拟 数据双向绑定效果
* 当用户在input中输入内容的时候 span中的内容跟着改变
*
* 1、获取标签
* 2、绑定事件 当用户输入的时候触发
* oninput事件-->表单内容只要发生改变就会实时触发
* onchange事件 -->失去焦点 并且表单内容发生改变 才会触发
* 3、获取输入的内容 并赋值给text
*/
// 1、获取标签
var oIpt = document.getElementById("ipt");
var oText = document.getElementById("text");
// 2、绑定事件 当用户输入的时候触发
oIpt.oninput = function () {
// 3、获取输入的内容 并赋值给text
oText.innerHTML = oIpt.value;
}
script>
body>
html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按下抬起事件</title>
<style>
#box{
width: 200px;
height: 200px;
background: red;
}
</style>
</head>
<body>
<div id="box">
</div>
<script>
/*
* 鼠标在元素上 按下 元素变成黄色 抬起 变成红色
* onmousedown 鼠标按下事件
* onmouseup 鼠标抬起事件
*/
var oBox = document.getElementById("box");
oBox.onmousedown = function () {
oBox.style.backgroundColor = "yellow";
}
oBox.onmouseup = function () {
oBox.style.backgroundColor = "red";
}
</script>
</body>
</html>
onscroll 事件在元素滚动条在滚动时触发。
练习
<html lang="en">
<head>
<meta charset="UTF-8">
<title>onscrolltitle>
<style>
#outer{
width: 400px;
height: 300px;
border:1px solid #000;
overflow: scroll;
}
#con{
width: 800px;
height: 1000px;
}
style>
<script>
window.onload = function () {
//script写在head标签中也行
// onscroll是滚动条滚动即执行
var oOuter = document.getElementById("outer");
var oCon = document.getElementById("con");
oOuter.onscroll = function () {
console.log(Date.now());//只要在滚动 那么每次间隔最小可能是十几毫秒 甚至2毫秒 所以onscroll事件执行特别的频繁
console.log("我滚了 再见");
}
}
script>
head>
<body>
<div id="outer">
<div id="con">
今天天气真好 <br> * 100
div>
div>
body>
html>
onload 事件会在页面或图像加载完成后立即发生(一个页面中只能出现一次window.onload 因为DOM0级事件 会覆盖)
<html lang="en">
<head>
<meta charset="UTF-8">
<title>window.onloadtitle>
<script>
// js是可以放在这个位置的,
// 但是在这个位置的js 直接获取元素是会获取不到的 因为代码还没有运行到DOM节点
/* var oBox = document.getElementById("box");
oBox.style.backgroundColor = "red";*/
// 解决方法:添加window.onload
window.onload = function () {
var oBox = document.getElementById("box");
oBox.style.backgroundColor = "red";
}
script>
head>
<body>
<div id="box">我是boxdiv>
<img src="../images/01.jpg" alt="">
<img src="../images/02.jpg" alt="">
<img src="../images/03.jpg" alt="">
<img src="../images/04.jpg" alt="">
body>
html>
<body>
<img id="img" src="01.jpg" alt="">
<script>
//offsetWidth:获取元素的宽度
var oImg = document.getElementById("img");
console.log(oImg.offsetWidth);//0 此时图片还没有下载完成
/*
* 可以给img标签绑定onload事件,当图片加载完成后执行
* */
oImg.onload = function () {
console.log(oImg.offsetWidth);//1920
}
</script>
</body>
</html>
1.获取元素
* 2.遍历生成所有的img标签
* 3.给img标签添加src属性
* 4.给img标签添加onload事件
* 5.当事件发生 让计数器加1
* 6.根据计数器的值 计算当前图片加载的百分比,然后操作DOM
<head>
<meta charset="UTF-8">
<title></title>
<style>
.box{
width: 400px;
height: 40px;
border:3px solid #000;
}
.per{
width: 0;
height: 40px;
background-color: red;
}
</style>
</head>
<body>
<div class="box">
<div class="per"></div>
</div>
<p>已经加载了<span class="num">0</span>%</p>
<script>
var oPer=document.querySelector(".per");
var oNum=document.querySelector(".num"); //1获取元素
var count=0; //定义一个图片加载计数器
for(var i=1;i<31;i++){
var newImg=new Image(); //生成img标签
newImg.src="images/"+(i<10 ? "0"+i : i)+".jpg";
console.log(newImg);
newImg.onload=function(){
//给img标签添加onload事件
count++; //每加载完一个加1
var long=parseInt(count/30 *100); //计算已经加载完成的图片所占用所有图片的百分比
oPer.style.width=long+"%" //控制per的宽度
oNum.innerHTML=long; //改变num的值
}
}
</script>
</body>
</html>
<script>
//获取视口大小封装函数
var getScreen = function () {
var w = document.documentElement.clientWidth||document.body.clientWidth;
var h = document.documentElement.clientHeight||document.body.clientHeight;;
return {
width:w,
height:h
}
}
function fn(){
if(getScreen().width >= 1000){
document.body.style.background = "red";
}else if(getScreen().width >= 700){
document.body.style.background = "pink";
}else if(getScreen().width >= 400){
document.body.style.background = "blue";
}
}
fn();
window.onresize = fn; //方法一
// window.onload = window.onresize = fn; //方法二
</script>
方法一
1.for循环遍历h2给所有的h2绑定点击事件
2.当事件发生的时候,遍历所有的h2
3.判断哪一个h2标签和当前点击的对象相等,如果相等则当前的 下标i就是点击的对象的下标
4.给当前的i的h2和li特殊类型,其他的去掉类名
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
#tab{
width: 600px;
margin: 50px auto;
border: 1px solid #000;
}
#tab .head{
overflow:hidden;
}
#tab .head h2{
width: 198px;
float: left;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 20px;
border: 1px solid #000;
}
#tab .head h2.active{
background-color: red;
color: #fff;
}
#tab .con{
height: 300px;
}
#tab .con li{
height: 300px;
font-size: 60px;
text-align: center;
line-height: 300px;
display: none;
}
#tab .con li.show{
display: block;
}
</style>
</head>
<body>
<div class="outer">
<div id="tab">
<div class="head">
<h2 class="active">标题1</h2>
<h2>标题2</h2>
<h2>标题3</h2>
</div>
<ul class="con">
<li class="show">内容1</li>
<li>内容2</li>
<li>内容3</li>
</ul>
</div>
</div>
<script>
var oH2s=document.querySelectorAll(".head h2"); //获取元素是个集合
var oLis=document.querySelectorAll(".con li");
for(var i=0;i<oH2s.length;i++){
//遍历所有H2
oH2s[i].onclick=function(){
//给所有H2绑定点击事件
for(var i=0;i<oH2s.length;i++){
//事件发生遍历所有h2
if(oH2s[i]==this){
//如果等于当前的话,则加类名,不等于则去掉其他类名
oH2s[i].className="active";
oLis[i].className="show";
}else{
oH2s[i].className="";
oLis[i].className="";
}
}
}
}
</script>
//for是同步代码,事件函数是异步代码
//等事件函数执行的时候,同步代码已经已经执行完毕,此时for循环的i已经执行到完成阶段了,已经3了
/*for (var i = 0; i < oH2s.length; i++) {
oH2s[i].onclick = function(){
this.className = "active";
oLis[i].className = "show"
}
}*/
方法二:
1.给所有的h2绑定点击事件
2.我们自己给每一个h2元素对象 扩展一个自定义对象属性 num 保存的是当前h2在父级元素中的下标
3.每次点击 先全部清空
4.ran然后给当前的元素添加类名字
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
#tab{
width: 600px;
margin: 50px auto;
border: 1px solid #000;
}
#tab .head{
overflow:hidden;
}
#tab .head h2{
width: 198px;
float: left;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 20px;
border: 1px solid #000;
}
#tab .head h2.active{
background-color: red;
color: #fff;
}
#tab .con{
height: 300px;
}
#tab .con li{
height: 300px;
font-size: 60px;
text-align: center;
line-height: 300px;
display: none;
}
#tab .con li.show{
display: block;
}
</style>
</head>
<body>
<div class="outer">
<div id="tab">
<div class="head">
<h2 class="active">标题1</h2>
<h2>标题2</h2>
<h2>标题3</h2>
</div>
<ul class="con">
<li class="show">内容1</li>
<li>内容2</li>
<li>内容3</li>
</ul>
</div>
</div>
<script>
var oH2s=document.querySelectorAll(".head h2");
var oLis=document.querySelectorAll(".con li");
for(var i=0;i<oH2s.length;i++){
oH2s[i].num=i; //自定义H2对象属性num 保存当前h2的下标
oH2s[i].onclick=function(){
for(var i=0;i<oH2s.length;i++){
//事件发生全部清空先
oH2s[i].className ="";
oLis[i].className ="";
}
this.className="active"; //ran然后给当前的元素添加类名字
oLis[this.num].className="show"
}
}
</script>
动画版
//for循环遍历h2给所有的h2绑定点击事件
for (var i = 0; i < oH2s.length; i++) {
oH2s[i].onclick = function () {
//当事件发生的时候,遍历所有的h2
for (var i = 0; i < oH2s.length; i++) {
//判断哪一个h2标签和当前点击的对象相等,如果相等则当前的 下标i就是点击的对象的下标
//给当前的i的h2和li特殊类型,其他的去掉类名
if(oH2s[i] === this){
oH2s[i].className = "active";
//起始位置,直接获取当前滚动条位置即可
var startScroll = oCon.scrollTop;
//结束位置 和当前点击的元素的下标相关
var endScroll = i * oLis[0].offsetHeight;
//起始步数
var startStep = 0;
//结束步数
var endStep = 22;
//每一步所走的距离
var everyStep = (endScroll - startScroll)/(endStep - startStep);
var timer = setInterval(function () {
startStep ++;
if(startStep >= endStep){
clearInterval(timer);
}
//scroll自身可以参与计算,但是最终计算结果会进行省略小数,所有可能不精确,所以请使用变量去计算 然后再赋值
/*console.log(oCon.scrollTop,everyStep)
oCon.scrollTop += everyStep;
console.log(oCon.scrollTop);*/
startScroll += everyStep;
oCon.scrollTop = startScroll;
},1000/60)
}else{
oH2s[i].className = ""
}
}
}
}
window
,它表示浏览器的一个实例。是客户端浏览器对象模型的基类。window
对象有双重角色,它既是通过 JavaScript 访问浏览器窗口的一个接口,又是 ECMAScript 规定的 Global
对象。window
作为其 Global
对象,因此有权访问 isNaN()
、isFinite()
、parseInt()
、parseFloat()
等方法使用 window对象可以访问客户端其他对象,这种关系构成浏览器对象模型。
window.open()
方法既可以导航到一个特定的 URL,也可以打开一个新的浏览器窗口。width=300,height=300,left=200,top=100
窗口名.close()
可以关闭窗口,如果关闭自身 那就使用 window.close()。close()
方法仅适用于通过 window.open()
打开的弹出窗口var newWin = null;
oBtn1.onclick = function () {
// 当书写新窗口打开 并且书写窗口大小位置的时候,会开一个新的浏览器窗口
// window.open("http://www.baidu.com","_blank","width=300,height=300,left=200,top=100");
// 当不写第三个参数的时候,_blank是打开一个新的标签页
// window.open 返回一个值代表的是这个窗口,可以供我们对窗口操作
newWin = window.open("http://www.baidu.com","_blank");
}
oBtn2.onclick = function () {
// 关闭新窗口
newWin.close();
// 关闭自身
// window.close();
}
JavaScript 是单线程语言,但它允许通过设置超时值和间歇时间值来调度代码在特定的时刻执行。前者是在指定的时间过后执行代码,而后者则是每隔指定的时间就执行一次代码。
超时调用需要使用 window
对象的 setTimeout()
方法,能够在指定的时间段后执行特定代码
var TimerID = setTimeout(code,delay,....);
该方法返回值是一个 TimerID,这个ID编号指向延迟执行的代码控制句柄。如果把这个句柄传给 clearTimeout方法,则会取消代码的延迟执行
//写法1
setTimeout('var a = 1;alert(a);',2000);
//写法2
setTimeout(function(){
var a = 2;
alert(a);
},2000)
// 写法3
function fn(){
var a = 2;
alert(a);
}
setTimeout(fn,2000);
//传参方法1
function fn(a){
alert(a);
}
// setTimeout('alert(1)',2000)
setTimeout('fn("传参")',2000)
//传参方法2
function f(name,age) {
alert(name+age)
}
setTimeout(f,2000,"老李",20);
利用cleartimeout
方法在特定的条件下清除延迟处理代码。方法的参数是setTimeout方法的句柄
oBtn1.onclick = function () {
//setTimeout返回一个句柄 是一个id 可以通过这个id(唯一的) 来控制当前的定时器
timer1 = setTimeout(function(){
alert("执行1");
},2000)
timer2 = setTimeout(function(){
alert("执行2");
},4000)
console.log(timer1);
console.log(timer2);
}
oBtn2.onclick = function () {
//向clearTimeout方法传入要取消的超时调用计时器的句柄 就可以取消
clearTimeout(timer1)
}
var oBox = document.getElementById("box");
var oCon = document.getElementById("con");
var timer = null;
oBox.onmouseenter = function(){
/*
* 每次鼠标移入的时候,可能还有一个移出的计时器在执行,那么就有可能等计时器执行结束后,触发消失效果
* 所以每次移入的时候,要清除计时器
* */
clearTimeout(timer);
oCon.style.display = "block";
}
oBox.onmouseleave = function () {
timer = setTimeout(function(){
oCon.style.display = "none";
},1000)
}
var TimerID = setInterval(code,interval);
setTimeout()
方法基本相同,其中参数code表示要周期执行的代码字符串,参数interval表示周期执行的时间间隔,以毫秒为单位 <button id="btn">按钮1</button>
<script>
var oBtn = document.getElementById("btn");
var a = 0;
var timer = setInterval(function () {
a ++;
alert(a);
},2000)
oBtn.onclick = function(){
clearInterval(timer)
}
</script>
利用clearInterval
方法在特定的条件下清除延迟处理代码。方法的参数是setInterval方法的句柄。
var oNum = document.getElementById("num");
var oBox = document.getElementById("box");
var num = 5;
var timer = setInterval(function(){
num --;
if (num <= 0){
clearInterval(timer);
oBox.innerHTML = "全局出击";
}
oNum.innerHTML = num;
},1000)
练习2
动画:点击按钮,让元素向移动
<script>
var oBtn = document.getElementById("btn");
var oCon = document.getElementById("con");
var num = 0;
var timer = null;
//css3方法
// oBtn.onclick = function () {
// oCon.style.left = "1000px";
// }
//js方法
oBtn.onclick = function () {
clearInterval(timer); //先清楚下计时器,每次点击都会生成一个计时器(不会覆盖)
timer = setInterval(function(){
num += 3;
//判断临界值
if(num >= 1000){
//一般情况下,书写临界值使用大于等于,并在判断语句中固定好最终的值
num = 1000;
clearInterval(timer)
}
//一般在判断临界值之后,在最后赋值操作
oCon.style.left = num + "px";
},16)
}
</script>
上面不先清计时器的话,每次点击生成一个新计时器,num每点击一次在原基础上累加,只会跑的越来越快
面试题1
//计时器函数和事件一样 都是异步代码 。让同步代码(for)执行完成以后 才会去执行异步代码,当去执行异步代码的时候 for已经执行完毕 i此时是5了。
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i); // 5,5,5,5,5
},0)
}
面试题2
对上边的代码进行修改,让弹出 0,1,2,3,4
for (var i = 0; i < 5; i++) {
(function fn(i) {
//只要在这个函数中 出现i 那么就不会去使用for循环的i
// 形参i 其实就是这个作用域的变量
setTimeout(function () {
console.log(i);
},0)
})(i);
}
计时器不会覆盖,计时器是异步代码
检测浏览器类型的方法有多种,常用的方法包括两种:特征检测法和字符串检测法,这两种方法都存在各自的优点与缺点,用户可以根据需要进行选择.
if (document.documentElement){
var w = document.documentElement.clientWidth
} else{
var w = document.body.clientWidth
}
```js
var ua = navigator.userAgent.toLowerCase();
var info = {
ie:/msie/.test(ua) && !/opera/.test(ua),
op:/opera/.test(ua),
sa:/version.*safari/.test(ua),
ch:/chrome/.test(ua),
ff:/gecko/.test(ua) && !/webkit/.test(ua)
}
info.ie && console.log("ie");
info.op && console.log("op");
info.sa&& console.log("sa");
info.ch && console.log("ch");
info.ff && console.log("ff");
```
navigator.userAgent返回值一般都会包含操作系统的基本信息,不过这些信息比较散乱,没有统一的规则。
用户可以检测一些更为通用的信息,如检测是否为 Windows系统,或者为 Macintosh系统,而不去分辨操作系统的版本号
例如,如果仅检测通用信息,那么所有 Windows版本的操作系统都会包含"Win”字符串,所有Macintosh版本的操作系统都包含有"Mac”字符串,所有Umix版本的操作系统都包含有"X11”,而 Linux操作系统会同时包含"X11”和" Linux
var isWin = (navigator.userAgent.indexOf("Win") != - 1);
// 如果是Windows系统,则返回true
var isMac = (navigator.userAgent.indexOf("Mac") != - 1);
// 如果是Macintosh系统,则返回true
var isUnix = (navigator.userAgent.indexOf("X11") != - 1);
// 如果是UNIX系统,则返回true
var isLinux = (navigator.userAgent.indexOf("Linux") != - 1);
// 如果是Linux系统, xc则返回true
location对象存储了与当前文档位置(URL)相关的信息,简单地说就是网页地址字符串,使用 window对象的loaction属性可以访问
location对象定义了8个属性,其中7个属性可以获取当前URL的各部分信息,另一个属性(href)包含了完整的URL信息
href : 声明或获取当前文档完整的URL 跳转
protocol:协议部分包括后缀的冒号。例如http:
host:主机和端口名称 www.baidu.com:8080
hostname:主机名称
port:端口号
pathname 路径部分
search:url的查询部分,包括前导问号
hash:锚部分包括前导 #
// location对象属性(哈希值在地址栏中不会影响页面的跳转 浏览器在请求服务器时是不管他的)
console.log(location.hash);
// host:主机名:端口号
console.log(location.host);//localhost:63342
//hostname:主机名
console.log(location.hostname);//localhost
// prot:端口号
console.log(location.port);//63342
// pathname:路径名 在服务器中 当前页面的路径名称
console.log(location.pathname);
// href:url地址 完整路径
console.log(location.href);
// search 查询字符串 路径问号后跟的数据
console.log(location.search);
location还定义两三方法:reload()和replace() assign()
assign:和href相当 跳转
reload:重新加载文档 刷新
replace:可以装载一个新文档而无须为它创建一个新的历史记录。替换当前文档的历史记录 替换地址回不去了
// location的方法
var oBtn1 = document.getElementById("btn1");
var oBtn2 = document.getElementById("btn2");
var oBtn3 = document.getElementById("btn3");
oBtn1.onclick = function () {
location.assign("http://www.baidu.com");
}
oBtn2.onclick = function () {
location.replace("http://www.baidu.com");
}
oBtn3.onclick = function () {
// location.reload(true);//硬刷新
location.reload(false);
}
练习
倒计时跳转
<html lang="en">
<head>
<meta charset="UTF-8">
<title>倒计时跳转title>
head>
<body>
<button id="btn">点击我注册成功button>
<h2><span id="time">3span>秒后进行跳转h2>
<script>
var oBtn = document.getElementById("btn");
var oTime = document.getElementById("time");
var timer = null;
oBtn.onclick = function () {
var reduceTime = 3;
timer = setInterval(function () {
reduceTime --;
oTime.innerHTML = reduceTime;
if(reduceTime <=0 ){
clearInterval(timer)
// location.href 也可以设置页面跳转
// location.href = "http://www.baidu.com";
// location.assign("http://www.baidu.com");
location.replace("http://www.baidu.com");
// window.open("http://www.baidu.com");
}
},1000)
}
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>01title>
head>
<body>
<h1>01h1>
<a href="02.html">02a>
<a href="03.html">03a>
<button id="forward">前进button>
<button id="back">后退button>
<button id="go">走你button>
<script>
var oForward = document.getElementById("forward");
var oBack= document.getElementById("back");
var oGo = document.getElementById("go");
oForward.onclick = function () {
history.forward();
}
oBack.onclick = function () {
history.back();
}
oGo.onclick = function () {
history.go(-2)
}
script>
body>
html>
<style>
#box{
width: 100px;
height: 100px;
background-color: red;
padding: 10px;
border: 1px solid #000;
margin: 5px;
/*display: none;*/
}
style>
head>
<body>
<button id="btn">点我啊button>
<div id="box">div>
<script>
var oBtn = document.getElementById("btn");
var oBox = document.getElementById("box");
oBtn.onclick = function(){
/*offsetWidth 获取元素的宽度 border-box*/
console.log(oBox.offsetWidth);//122
}
script>
<style>
#box{
width: 100px;
height: 100px;
background-color: red;
padding: 10px;
border: 1px solid #000;
margin: 5px;
/*display: none;*/
}
style>
head>
<body>
<button id="btn">点我啊button>
<div id="box">div>
<script>
var oBtn = document.getElementById("btn");
var oBox = document.getElementById("box");
oBtn.onclick = function(){
/*clientWidth 获取元素的宽度 padding-box*/
console.log(oBox.clientWidth);//120
}
script>
<style>
#box{
width: 100px;
height: 100px;
padding: 10px;
border: 1px solid #000;
margin: 5px;
overflow: auto;
}
.con{
width: 1000px;
height: 100px;
background-color: red;
}
style>
head>
<body>
<button id="btn">点我啊button>
<div id="box">
<div class="con">div>
div>
<script>
var oBtn = document.getElementById("btn");
var oBox = document.getElementById("box");
oBtn.onclick = function(){
/*scrollWidth 获取元素的宽度 自身的宽度加溢出一侧的padding*/
console.log(oBox.scrollWidth);//1010
}
script>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>设计位置-offsetLeft和offsetToptitle>
<style>
#outer{
width: 500px;
height: 500px;
margin: 50px;
overflow: hidden;
background-color: red;
padding: 10px;
border: 1px solid #000;
position: relative;
}
#inner{
width: 300px;
height: 300px;
background-color: yellow;
margin: 20px;
padding: 10px;
border: 1px solid #ccc;
/*position: relative;*/
}
#con{
width: 100px;
height: 100px;
margin: 10px;
/*position: absolute;*/
/*left: 40px;*/
/*top: 40px;*/
background-color: #0ee69c;
}
style>
head>
<body>
<div id="outer">
<div id="inner">
<div id="con">div>
div>
div>
<script>
var oCon = document.getElementById("con");
console.log(oCon.offsetLeft);
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>offsetParenttitle>
<style>
#outer{
width: 500px;
height: 500px;
margin: 50px;
overflow: hidden;
background-color: red;
padding: 10px;
border: 1px solid #000;
position: relative;
}
#inner{
width: 300px;
height: 300px;
background-color: yellow;
margin: 20px;
padding: 10px;
border: 1px solid #ccc;
position: relative;
}
#con{
width: 100px;
height: 100px;
margin: 10px;
/*position: absolute;*/
/*left: 40px;*/
/*top: 40px;*/
background-color: #0ee69c;
}
style>
head>
<body>
<div id="outer">
<div id="inner">
<div id="con">div>
div>
div>
<script>
var oCon = document.getElementById("con");
console.log(oCon.offsetParent);
script>
body>
html>
获取con距离屏幕边缘的距离
var l = 0;//定义一个值用来储存left
while(oCon){
//第二次循环开始ocon变成了包含块,一直到null循环停下
l += oCon.offsetLeft; // oCon到包含块的距离与包含块到自己包含块的距离累加
oCon = oCon.offsetParent; //这时的 oCon是ocon的包含块了
}
console.log(l)
<html lang="en">
<head>
<meta charset="UTF-8">
<title>scrollLeft和scrollToptitle>
<style>
#outer{
width: 200px;
height: 200px;
border: 1px solid #000;
overflow: auto;
}
#con{
width: 2000px;
height: 2000px;
background-color: pink;
}
style>
head>
<body>
<button id="btn">点一哈button>
<div id="outer">
<div id="con">div>
div>
<script>
var oOuter = document.getElementById("outer");
var oBtn = document.getElementById("btn");
oBtn.onclick = function () {
// oOuter.scrollLeft = 200;
console.log(oOuter.scrollLeft);
}
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>设计位置-clientLeft和clientToptitle>
<style>
#outer{
width: 500px;
height: 500px;
margin: 50px;
overflow: hidden;
background-color: red;
padding: 10px;
border: 1px solid #000;
position: relative;
}
#inner{
width: 300px;
height: 300px;
background-color: yellow;
margin: 20px;
padding: 10px;
border: 1px solid #ccc;
/*position: relative;*/
}
#con{
width: 100px;
height: 100px;
margin: 10px;
/*position: absolute;*/
/*left: 40px;*/
/*top: 40px;*/
background-color: #0ee69c;
}
style>
head>
<body>
<div id="outer">
<div id="inner">
<div id="con">div>
div>
div>
<script>
var oCon = document.getElementById("con");
console.log(oCon.clientLeft);
console.log(oCon.parentNode.clientLeft);
console.log(oCon.parentNode.parentNode.clientLeft);
script>
body>
html>
self.pageYOffse获取系统滚动条位置的新方法
//兼容性封装
<script>
document.onclick = function(){
//可以不要点击事件
function getDocScroll() {
var h = document.documentElement;
var b = document.body;
var y = self.pageYOffset||
h.scrollTop||
b.scrollTop;
var x = self.pageXOffset||
h.scrollLeft||
b.scrollLeft;
return {
x:x, //返回对象
y:y
}
}
console.log(getDocScroll().y) //
}
</script>
//设置滚动条位置兼容性封装
<script>
document.onclick = function(){
//可以不要点击事件
function setDocScroll(x,y) {
if(arguments.length === 1 && typeof x === "number"){
window.scrollTo(x,0);
document.documentElement.scrollLeft = x;
document.body.scrollLeft = x;
}
if(arguments.length === 2 && typeof x === "number" && typeof y === "number"){
window.scrollTo(x,y);
document.documentElement.scrollLeft = x;
document.documentElement.scrollTop = y;
document.body.scrollLeft = x;
document.body.scrollTop = y;
}
}
setDocScroll(0,300)
}
</script>
标签的clientWidth和clientHeight属性,就可以知道浏览器窗口的可视宽度和高度。document.documentElement
document.documentElement.clientWidth
document.body.clientWidth
document.documentElement.clientWidth||document.body.clientWidth;
//获取窗口的大小兼容性封装
<script>
document.onclick = function(){
function getWinSize(){
var h = document.documentElement;
var b =document.body;
return {
y:h.clientHeight || b.clientHeight,
x:h.clientWidth || b.clientWidth
}
}
console.log(getWinSize().X)
console.log(getWinSize().y)
}
</script>
//获取整个文档大小兼容性封装
<script>
document.onclick = function(){
function getDocSize(){
var h = document.documentElement;
var b =document.body;
return {
y:h.offsetHeight || b.offsetHeight,
x:h.offsetWidth || b.offsetWidth
}
}
console.log(getDocSize().x)
console.log(getDocSize().y)
}
</script>
oBox.getBoundingClientRect().top; // 元素上边距离页面上边的距离
oBox.getBoundingClientRect().right; // 元素右边距离页面左边的距离
oBox.getBoundingClientRect().bottom; // 元素下边距离页面上边的距离
oBox.getBoundingClientRect().left; // 元素左边距离页面左边的距离
/*
* 作者:李沛华
* 时间:2020-7-18
* 内容:个人封装函数库
*
* ;是为了防止其他库末尾不加分号 引起错误
* + - ~ ! 等一元运算符 代表把匿名函数括起来
* 在匿名函数中定义一个对象,把所有的方法放到这个对象上,方便识别和管理
* */
;+function(w){
w.my = {
};
/*
* getDocScroll方法:获取系统滚动条的位置
* @param {} 无参数
* @return {Object} x:横向滚动条 y:竖向滚动条
* */
w.my.getDocScroll = function(){
var h = document.documentElement;
var b = document.body;
var y = self.pageYOffset||
h.scrollTop||
b.scrollTop;
var x = self.pageXOffset||
h.scrollLeft||
b.scrollLeft;
return {
x:x,
y:y
}
}
/*
* setDocScroll方法:设置系统滚动条的位置
* @param {x:[number],y:[number]} x:横向滚动条 y:竖向滚动条
* @return {} 无
* */
w.my.setDocScroll = function(x,y){
if(arguments.length === 1 && typeof x === "number"){
window.scrollTo(x,0);
document.documentElement.scrollLeft = x;
document.body.scrollLeft = x;
}
if(arguments.length === 2 && typeof x === "number" && typeof y === "number"){
window.scrollTo(x,y);
document.documentElement.scrollLeft = x;
document.documentElement.scrollTop = y;
document.body.scrollLeft = x;
document.body.scrollTop = y;
}
}
/*
* getWinSize方法:获取视口的大小
* @param 无
* @return {Object} x:宽 y:高
* */
w.my.getWinSize = function(){
var h = document.documentElement;
var b =document.body;
return {
y:h.clientHeight || b.clientHeight,
x:h.clientWidth || b.clientWidth
}
}
/*
* getDocSize方法:获取文档的大小
* @param 无
* @return {Object} x:文档宽 y:文档高
* */
w.my.getDocSize = function(){
var h = document.documentElement;
var b =document.body;
return {
y:h.offsetHeight || b.offsetHeight,
x:h.offsetWidth || b.offsetWidth
}
}
}(window)
<script src="./my.js"></script>
<script>
var oBack = document.querySelector(".back");
var oBox = document.getElementById("box");
var timer = null;
//window的scroll事件触发
window.onscroll = function(){
if (my.getDocScroll().y >= 200){
//获取当前滚动条位置作比较
oBack.style.display = "block";
}else{
oBack.style.display = "none";
}
}
oBack.onclick = function(){
clearInterval(timer);
//起始位置
var startScroll = my.getDocScroll().y;
//结束位置
var endScroll = 0;
//起始步数
var startStep = 0;
//总步数
var endStep = 40;
//每一步所走的距离
var everyStep = (endScroll - startScroll) / (endStep - startStep); //为负数
//执行动画
timer = setInterval(function(){
//让起始步数累加,通过起始步数和结束步数的对比 判断临界值
startStep ++; //纯临界值判断作用
if(startStep >= endStep){
clearInterval(timer);
}
startScroll += everyStep; //当前位置加负数每一步距离
//每次计时器执行结束,就赋值操作
my.setDocScroll(0,startScroll);
},1000/60)
}
</script>
var newLi=document.createElement("li");//插入li节点
使用document对象的createTextNode()方法可创建文本节点
参数是一个字符串
创建的文本节点需要使用appendChild等方法才能插入到元素节点中
当然也可以使用innerHTML方法给元素节点添加内容
//1.
var newText=document.createTextNode("新的li");
newLi.appendChild(newText);
//2.
newLi.innerHTML="新的li";
appendChild()方法可以向当前节点的字节点列表的末尾添加新的节点
如果文档树中已经存在参数节点,则将从文档树中删除,然后重新插入新的位置
oBox.appendChild(newLi); //插到父级ul oBox中去了
使用insertBefore(newChild,oldChild)方法可以在已有的子节点前插入一个新的子节点
newChild表示新插入的节点,oldChild用于指定插入节点的后边的相邻位置。
插入成功以后,该方法返回新插入的节点
insertBefore可以把指定元素及其所包含的所有子节点都一起插入到指定位置中。同时会先删除移动的元素,再重新插入
oBox.insertBefore(oLis[3],oLis[1]) // 旧的元素也可以插 在下标3前面插了
oBox.insertBefore(newLi,oLis[1]) //插入新元素
var newBox = oBox.cloneNode(true); //辅助oBox
newBox.id = newBox.id + i;
被删除元素的父级调用
removeChild方法可以从子节点列表中删除某个节点
如果删除成功,则返回被删除的节点,如果失败则返回null
当remove 删除节点的时候,该节点所包含的所有子节点将同时被删除
var oLisDeles = document.querySelectorAll("#box li a")
for (var i = 0; i < oLisDeles.length; i++) {
oLisDeles[i].onclick = function(){
/*
* 被删除元素的父级 调用removeChild方法 removeChild方法的参数是被删除的元素
* */
this.parentNode.parentNode.removeChild(this.parentNode);//a-li-ul.removeChild(li)
}
}
oBox.replaceChild(newLi,oLis[1])
oBox.replaceChild(oLis[3],oLis[1])
<div id="box">
<p>新节点</p>
<a href="##">删除</a>
</div>
<script>
var oBox=document.getElementById("box");
console.log(oBox.innerHTML); //获取字符串会带标签
oBox.innerHTML="我是新的内容 " // 设置可以解析标签并且会替换掉原来的内容(BOX内的)
console.log(oBox.innerHTML);
console.log(oBox.innerText); //获取内容不带标签
oBox.innerText="我是新的内容 "//设置解析不了标签 ,也会替换原有内容(BOX内的)
console.log(oBox.innerText);
</script>
console.log(oBox.outerHTML); //获取包含BOX本身的标签与内容
oBox.outerHTML = "我是新的内容 " // 设置可以解析标签但是包含BOX直接被替换了
console.log(oBox.outerText); //获取内容不带标签
oBox.outerText = "我是新的内容 " //设置解析不了标签 ,但是也会替换掉整个BOX
console.log(oBox.textContent); //获取内容不带标签
oBox.textContent = "我是新的内容 " //设置解析不了标签 ,也会替换原有内容
console.log(oBox.textContent);
//兼容性处理
function setOrGetContent(node,content) {
if(arguments.length === 1){
//代表当前是读取操作
if(node.textContent){
//只要能拿到这个dom对象的textContent属性值,代表当前用户是高级浏览器
return node.textContent;
}else {
//代表拿不到 那就是低级浏览器
return node.innerText;
}
}else if(arguments.length === 2){
//代表写入操作
if(node.textContent){
//代表高级
node.textContent = content;
}else {
//代表低级
node.innerText = content;
}
}
oBtn.onclick = function(){
//创建一个属性节点 没有值
var myAttr = document.createAttribute("study");
console.log(myAttr)
//通过value属性给属性节点赋值
myAttr.value = "js";
console.log(myAttr)
//setAttributeNode 是给某一个元素设置一个属性节点
oBox.setAttributeNode(myAttr);
}
<script>
var oBtn = document.getElementById("btn");
var oBox = document.getElementById("box");
oBox.study = "css";
oBtn.onclick = function(){
//元素自有的属性可以直接通过点语法来获取 class例外 需要使用className
console.log(oBox.id);
//非自有属性,必须通过getAttribute属性来获取
//如果不是自有属性,通过点语法获取的是 js对象上的属性 而不是js对象对应的元素上的属性
console.log(oBox.study)
console.log(oBox.getAttribute("study"));
//如果直接通过点语法设置属性,设置的仅仅是js对象的属性,而不是元素上的属性
oBox.select = true;
oBox.setAttribute("select",true);
//removeAttribute只能移出元素上的属性节点
oBox.removeAttribute("study");
}
</script>
HTML5允许用户为元素自定义属性,但是要求添加前缀data
oBtn.onclick = function(){
//直接使用元素节点的dataset属性上 去访问自定属性
console.log(oBox.dataset);
console.log(oBox.dataset.study);
//直接给元素节点的dataset属性添加属性 就可以添加属性节点
oBox.dataset.select = true;
//删除 只需要删除dataset上的属性即可
delete oBox.dataset.study;
}
// createDocumentFragment创建一个DocumentFragment,它是一个轻量级的文档格式,作用是临时存储节点,等待插入到文档中
// createDocumentFragment是解决大量添加节点时候的性能问题
var fragment = document.createDocumentFragment();
for (var i = 0; i < 100; i++) {
var newLi = document.createElement("li");
// textContent给元素插入文本
newLi.textContent = "hello 6666";
fragment.appendChild(newLi); //先全部插到fragment中(仅仅存在于内存中,没有添加到文档树中)
}
oBox.appendChild(fragment);//再把fragment插到oBox中
基本事件模型:也称为DOM0事件模型(同一元素只能绑定同一事件一次,后绑定的会覆盖前面的)
DOM事件模型:
ie事件模型
事件流就是多个节点对象对同一种事件进行响应的先后顺序,主要包括以下3种类型
把JS脚本作为属性值,直接赋值给事件属性**(直接在元素行内绑定)**
<div onclick="fn()">div</div>
<script>
function fn() {
alert(1);
}
</script>
使用DOM对象的事件属性进行赋值
* DOM0的特点
* 1.绑定事件简单 把事件函数赋值给DOM对象的事件属性上
* 2.DOM0绑定事件事件流是冒泡
* 3.DOM0对同一个元素绑定同一个事件多次,会进行覆盖
* 4.注销DOM0事件 只需要给事件属性赋值为null
oOuter.onclick = function(){
alert("outer");
}
oInner.onclick = function(){
alert("inner");
}
oCon.onclick = function(){
alert("con1");
}
oCon.onclick = function(){
alert("con2");
}
/*取消事件*/
var oBtn = document.getElementById("btn");
btn.onclick = function () {
oInner.onclick = null;
}
事件处理函数是一类特殊的函数,与函数直接量结构相同,主要任务是实现事件处理,为异步调用,由事件触发进行相应。
/*
* addEventListener()是事件处理函数
* - type:事件名称
* - fn: 事件函数
* - boolean:控制冒泡或捕获 false:冒泡 true就是捕获
*
* 特点:
* 1.可以绑定同一个元素同一个事件多次
* 2.可以控制冒泡或捕获
* 3.DOM2级事件(DOMContentLoaded事件) 只能通过DOM2绑定事件方法绑定
*
* */
oCon.addEventListener("click", function () {
alert("con")
}, true);
oOuter.addEventListener("click", function () {
alert("outer1")
}, true);
oOuter.addEventListener("click", function () {
alert("outer2")
}, false);
oInner.addEventListener("click", function () {
alert("inner")
}, false);
//执行顺序由外到内先执行捕获,然后由内到外再执行冒泡
//事件函数,方便绑定和移除事件使用
function fn(){
alert("con")
}
oCon.addEventListener("click",fn,false);
/*
* removeEventListener 注销事件
* - type 要注销的事件名
* - fn 要注销事件的函数
* */
oBtn.onclick = function(){
oCon.removeEventListener("click",fn)
}
/*
* attachEvent() 低版本IE事件处理函数
* - type 事件名称 加on
* - fn 事件函数
*
* 注意:
* 对一个对象绑定用一个事件多次,执行顺序是逆向的(下--上)
* 只支持冒泡
*
* */
oCon.attachEvent("onclick",function(){
alert("con1")
})
oCon.attachEvent("onclick",function(){
alert("con2")
})
oInner.attachEvent("onclick",function(){
alert("inner")
})
oOuter.attachEvent("onclick",function(){
alert("outer")
})
//事件函数,方便绑定和移除事件使用
function fn(){
alert("con")
}
oCon.attachEvent("onclick",fn);
/*
* detachEvent 注销事件
* - type 要注销的事件名
* - fn 要注销事件的函数
* */
oBtn.onclick = function(){
oCon.detachEvent("onclick",fn)
}
/*
* 只有当需要DOM2绑定时 才会需要兼容
* ele:事件绑定的对象
* type:事件名称
* fn:事件函数
* boo:冒泡或捕获的布尔值
* */
function addEvent(ele,type,fn,boo) {
if (ele.addEventListener){
ele.addEventListener(type,fn,boo || false);
}else if(ele.attachEvent){
ele.attachEvent("on"+type,fn);
}else{
ele["on"+type] = fn;
}
}
addEvent(oCon,"click",fn,false);
//注销事件兼容
function delet(ele, type, fn) {
if (ele.removeEventListener) {
ele.removeEventListener(type, fn);
} else if (ele.detachEvent) {
ele.detachEvent(type, fn);
} else {
ele["on" + type] = null;
}
}
delet(oCon, "click", fn, false);
window.onload = function(){
alert("DOM和资源加载完毕")
}
/*
* DOMContentLoaded事件
* - DOM2级事件 需要使用事件监听来绑定
* - 当DOM节点加载完成即可执行,不需要等待资源(图片加载)
* */
window.addEventListener("DOMContentLoaded",function(){
alert("DOM节点加载完毕")
},false)
window.addEventListener("load",function(){
})
oBox.onclick = function(e){
var e = e || window.event;
console.log(e);
}
oBox.onclick = function (e) {
var e = e || window.event;
console.log(e);
// clientX和clientY:元素(鼠标)距离浏览器视口的距离 ,视口变了也会变不算滚动条
// console.log(e.clientX)
// console.log(e.clientY)
}
//只会阻止自身当前事件类型的传播
//只阻止自身的传播,不影响其他人的传播
oCon.addEventListener("click", function (e) {
//阻止传播
e.stopPropagation();
alert("con")
}, false);
oInner.addEventListener("click", function () {
alert("inner")
}, false);
oOuter.addEventListener("click", function () {
alert("outer1")
}, false);
//阻止鼠标右键
document.oncontextmenu = function (e) {
var e = e || window.event;
e.preventDefault ? e.preventDefault() : e.returnValue = false;
return false;
}
键盘事件定义了很多属性
keyCode:对应键盘中对应键位的键值
shiftKey、ctrlKey、altKey是否按下shift strl alt按键 返回布尔值
//ctrl c+v 失效
document.onkeydown = function (ev) {
console.log(ev);
if (ev.keyCode === 67 && ev.ctrlKey) {
alert("cv再见");
ev.preventDefault();
}
}
把原本内部目标节点的事件绑定到祖先的节点上,通过冒泡被祖先捕捉到,然后再使用event对象的target获取事件的精准目标
<button id="btn">
添加一个新元素
</button>
<ul id="box">
<li>11</li>
<li>22</li>
<li>33</li>
<li>44</li>
<li>55</li>
</ul>
<script>
var oBtn = document.getElementById("btn");
var oBox = document.getElementById("box");
var oLis = oBox.getElementsByTagName("li");
oBtn.onclick = function () {
var newLi = document.createElement("li");
newLi.innerHTML = "newLi";
oBox.appendChild(newLi);
}
oBox.onclick = function (ev) {
var ev = ev || window.event;
// ev.target当前时间精确发生的元素
console.log(ev.target);
// 在这里this仍然是指向oBox
// this.style.backgroundColor = "red";
// 给精确的元素绑定点击事件,但是没有判断 所有元素都能触发
// ev.target.style.backgroundColor = "red";
if (ev.target.nodeName.toLowerCase() == "li" ){
ev.target.style.backgroundColor = "red";
}
}
//根据冒泡原理,点击li就是点击了ul 所以如果给ul绑定点击事件,则点击li的时候就会触发ul的点击事件
//事件委托,1.减少绑定事件,提高效率 2.可以给未来的元素绑定事件
//event事件对象的target属性,就是你的目标元素(鼠标点击精确的元素)
谷歌/ie
* 滚轮事件:onmousewheel
* 需要获取event事件对象的 wheeldelta 属性
* 如果wheeldelta > 0 滚轮上滚
* 如果wheeldelta < 0 滚轮下滚
* 火狐:
* 滚轮事件:DOMMouseScroll
* 需要event事件对象的 detail属性
* 如果detail属性 > 0 滚轮下滚
* 如果detail属性 < 0 滚轮上滚
function mouseScroll(e) {
var e = e || window.event;
if (e.detail){
if(e.detail > 0){
x ++;
}else{
x --;
}
} else{
if (e.wheelDelta > 0){
x --;
} else{
x ++;
}
}
oBox.style.width = x + "px";
}
//火狐调用
oBox.addEventListener("DOMMouseScroll",mouseScroll);
// 谷歌调用
oBox.onmousewheel = mouseScroll;
<div class="outer">
<form action="###">
<input type="text" name="username" autocomplete="off">
<button>提交</button>
</form>
</div>
<script>
var oForm = document.querySelector("form");
var oBtn = document.querySelector("form button");
var oUserName = document.querySelector("input[name=username]");
document.onkeydown = function(e){
if(e.keyCode === 13){
//回车键码
//判断input不为空且全部都是数字 就直接提交
if(oUserName.value && !isNaN(Number(oUserName.value))){
// JS提交form表单 使用form元素submit方法
oForm.submit();
}else{
alert("格式不对或者不能为空")
}
return false;
}
}