DOM简介
-
DOM名称
Document Object Model文档对象模型
-
理解DOM
JS中通过DOM来对HTML文档进行操作,只要理解了DOM就可以随心所欲的操作Web页面
-
文档-表示整个HTML网页文档
-
对象-网页中的每一个部分都转化成了一个对象
-
模型-使用模型来表示对象之间的关系,方便获取对象
-
-
节点Node
-
节点是构成我们网页的最基本的组成部分,网页中的每一个部分都可以称为是一个节点
-
比如:html标签、属性、文本、注释、整个文档都是一个节点
-
虽然都是节点,但是实际上他们的具体类型是不同的
-
比如:html标签称为元素节点、元素的属性称为属性节点、html标签中的文本称为文本节点、整个html文档称为文档节点。
-
节点的类型不同,属性和方法都不尽相同。
-
nodeName nodeType nodeValue
-
nodeName | nodeType | nodeValue | |
---|---|---|---|
文档节点 | #document | 9 | null |
元素节点 | 标签名 | 1 | null |
属性节点 | 属性名 | 2 | 属性值 |
文本节点 | #text | 3 | 文本内容 |
- 实例
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button id="btn">我是一个按钮</button>
<script>
//浏览器为我们提供了文档节点对象,这个对象是window属性
//可以在页面中直接使用,文档节点代表的是整个网页
//document
var btn = document.getElementById("btn");
btn.innerHTML="I'm a button";
</script>
</body>
</html>
事件
-
事件
文档或浏览器窗口中发生的一些特定的交互瞬间
- JavaScript与HTML交互就是通过事件实现的
- 对于Web应用来说,有如下这些代表性的事件:点击某个元素、将鼠标移动至某元素上方、按下键盘上某个键
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--
我们可以在事件对应的属性中设置一些js代码
这样当事件被触发时,这些代码将会执行
这种写法,我们称为结构和行为耦合,不方便维护,不推荐使用
-->
<button id="btn" onclick="alert("讨厌,你点我干嘛")">我是一个按钮</button>
<script type="text/javascript">
var btn=document.getElementById("btn");
//绑定一个单击事件
//为单机事件绑定的函数,我们称为单击响应函数
btn.onclick=function(){
//双击:ondblcilck
//鼠标移动:onmousemove
alert("你还点~~~");
};
</script>
</body>
</html>
文档的加载
浏览器加载一个页面时,是按照自上向下顺序加载的
读取一行就运行一行,如果将script标签写到页面的上边
在代码执行时,页面还没有加载,DOM对象还没有加载完毕
将js代码编写到页面的下面就是为了,可以在页面加载完毕以后再执行js代码
-
onload事件
会在这个那个页面加载完成之后才触发
为了方便管理,将script标签写在head标签里面,通常为window绑定一个onload事件
这样该事件对应的响应函数将在页面加载完成之后执行
这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
window.onload=function(){
//js代码都写这里面 即可
};
</script>
</head>
<body>
</body>
</html>
DOM查询
- 通过document对象调用
- getElementById-通过id属性获取一个元素节点对象
- getElementsByTagName-通过标签名获取一组元素节点对象
- getElementsByName-通过name属性获取一组元素节点对象
innerHTML用来获取元素的内部文本
对于自结束标签不能使用innerHTML
如果需要读取元素节点属性,直接使用元素.属性名 元素.id 元素.value
但是,读取class属性的内容则不能采用这种方式,只能使用 元素.className
图片切换练习代码
<!doctype html>
<html>
<!-- 图片切换 -->
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin:0;
padding:0;
}
#outer{
width:500px;
margin:50px auto;
padding:10px;
background-color:greenyellow;
text-align:center;
}
</style>
<script type="text/javascript">
window.onload=function(){
//点击切换图片
var prev=document.getElementById("prev");
var next=document.getElementById("next");
var img=documnet.getElementsByTag("img")[0];
//设置一个图片路径的数组
var imgArr=["img/1.jpg","img/2.jpg","img/3.jpg","img/4.jpg","img/5.jpg"];//
//设置一个当前显示的图片,默认显示第一张
var index=0;
var info=document.getElementById("info");
info.innerHTML="一共 "+imgArr.length+" 张图片,当前是第 "+(index+1)+" 张";
prev.onclick=function(){
index--;
if(index<0)
index=imgArr.length-1;
info.innerHTML="一共 "+imgArr.length+" 张图片,当前是第 "+(index+1)+" 张";
};
next.onclick=function(){
index++;
if(index>imgArr.length-1)
index=0;
info.innerHTML="一共 "+imgArr.length+" 张图片,当前是第 "+(index+1)+" 张";
};
};
</script>
</head>
<body>
<p id="info"></p>
<div id="outer">
<img src="img/1.jpg" alt="冰棍" />
<button id="prev">上一张</button>
<button id="next">下一张</button>
</div>
</body>
</html>
DOM查询2
-
通过具体的元素节点调用
-
getElementsByTagName()
方法:返回当前节点指定标签名后代节点
-
childNodes
属性:表示当前节点的所有子节点
会获取包含文本节在内的所有节点
根据DOM标签间空白也会当成文本节点
-
firstChild
属性:表示当前节点的第一个子节点
-
lastChild
属性:表示当前节点的最后一个子节点
-
var btn04=document.getElementById("btn04");
btn04.onclick=function(){
var city=document.getElementById("city");
var lis=city.getElementsByTagName("li");
for(var i=0;i<lis.length;i++)
alert(lis[i].innerHTML);
};
var btn05=document.getElementById("btn05");
btn05.onclick=function(){
var city=document.getElementById("city");
var cns=city.childNodes;
var cns2=city.children;//children属性可以获取当前元素的所有子元素,children更好一点
alert(cns2.length);
}
var btn06=docement.getElementById("btn06");
btn06.onclick=function(){
var phone=document.getElementById("phone");
var fir=phone.firstChild;//包含了文本元素
fir=phone.firstElementChild;//不支持IE8及以下
alert(fir);
}
-
通过具体的节点调用
-
parentNode
属性:表示当前节点的父节点
-
previousSibling
属性:表示当前节点的前一个兄弟节点
-
nextSibling
属性:表示当前节点的后一个兄弟节点
-
function myClick(idStr,fun){
//idStr 要绑定的单击响应函数的对象的id属性值
//fun 事件的回调函数,当单击元素时,该函数将会被触发
var btn=document.getElementById(idStr,fun);
btn.onclick=fun;
};
};
myClick("btn07",function(){
var bj=document.getElementById("bj");
var pn=bj.parentNode;
alert(pn.innerHTML);
//innerText该属性可以获取内部文本
//和innerHTML类似,不同的是他会自动将html去除,只留下文本
});
myClick("btn08",function(){
var and=document.getElementById("Android");
var ps=and.previousSibling;//也可能获取到空白文本
//var pe=and.previousElementSibling;//获取前一个兄弟元素,IE8及以下不支持
alert(ps);
});
myClick("btn09",function(){
var um=document.getElementById("username");
alert(um.value);
});
myClick("btn10",function(){
var um=document.getElementById("username");
um.value="今天天气真不错~~";
});
myClick("btn11",function(){
var bj=document.getElementById("bj");
alert(bj.innerHTML);
//var fc=bj.firstChild;
//alert(fc.nodeValue);//获取文本内容
//bj.firstChild.nodeValue;
});
全选练习
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html";charset="UTF-8">
<title>全选练习</title>
<script type="text/javascript">
window.onload=function(){
//全选按钮
var items=document.getElementsByName("items");
var checkedAllBtn=document.getElementById("checkedAllBtn");
var checkedAllBox=document.getElementById("checkedAllBox");
checkedAllBtn.onclick=function(){
//获取四个多选框
for(var i=0;i<items.legnth;i++)
//通过checked 属性可以来获取或设置多选框的选中状态
items[i].checked=true;
checkedAllBox.checked=true;
};
var checkedNoBtn=document.getElementById("checkedNoBtn");
checkedNoBtn.onclick=function(){
for(var i=0;i<items.legnth;i++)
//通过checked 属性可以来获取或设置多选框的选中状态
items[i].checked=false;
checkedAllBox.checked=false;
};
var checkedRevBtn=document.getElementById("checkedRevBtn");
checkedRevBtn.onclick=function(){
for(var i=0;i<items.legnth;i++)
//通过checked 属性可以来获取或设置多选框的选中状态
//if(items[i].checked)
//items[i].checked=false;
//else
//items[i].checked=true;
items[i].checkde=!items[i].checked;
};
var sendBtn=document.getElementById("sendBtn");
sendBtn.onclick=function(){
for(var i=0;i<items.length;i++)
if(items[i].checked)
alert(items[i].value);
};
checkedALlBox.onclick=function(){
checkedAllBox.checked=true;
for(var i=0;i<items.length;i++)
items[i].checked=!this.checked;//事件是给谁绑定的,this就是谁
if(!items[j].checked)
checkedAllBox.checked=false;
}
};
};
</script>
</head>
<body>
<form method="post" action="">
你爱好的运动是?<input type="checkbox" id="checkedAllBox"/>全选/全不选
<br/>
<input type="checkbox" name="items" value="足球"/>足球
<input type="checkbox" name="items" value="篮球"/>篮球
<input type="checkbox" name="items" value="羽毛球"/>羽毛球
<input type="checkbox" name="items" value="乒乓球"/>乒乓球
<br/>
<input type="button" name="checkedAllBtn" value="全 选"/>
<input type="button" name="checkedNoBtn" value="全不选"/>
<input type="button" name="checkedRevBtn" value="反 选"/>
<input type="button" name="sendBtn" value="提交"/>
</form>
</body>
</html>
DOM查询的其他方法
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
window.onload=function(){
//获取body标签
//var body=document.getElementByTagName("body")[0];
//在document中有一个属性body,它保存的是body的引用
var body=document.body;
var html=document.documentElement;//html根标签
var all=document.all;//页面中所有的元素
all.document.getElementsByTagName("*");//所有元素
//根据元素的class属性值查询一组元素节点对象
var box1=document.getElementsByClassName("box1");//不支持IE8及以下浏览器
var divs=document.getElementsBtTagName("div");
//获取class为.box1中的div
//document.querySelector()
//-需要一个选择器的字符串作为参数,可以根据一个CSS选择器来查询一个元素节点对象
//-虽然IE8中没有getElementsByClassName()但是可以使用querySelector()代替
//-使用该方法总会返回唯一的一个元素,如果满足条件的元素有多个,那么它只会返回第一个
var div=document.querySelector(".box1 div");
var box1=document.querySelector(".box1");
//querySelectorAll()与querySelector()用法类似,不同的是,前者会将符合条件的元素封装到数组中
//-即使返回的只有一个元素,也会返回所有的元素
box1=document.querySelectorAll(".box1");
box1=document.querySelectorAll("#box1");
};
</script>
</head>
<body>
<div class="box1">
<div></div>
</div>
<div>
</div>
</body>
</html>
DOM增删改
window.onload=function(){
myClick("btn01",function(){
//创建一个元素
var li=document.createElement("li");
//创建文本节点
var gzText=document.createTextNode("广州");
//将gzText设置为li的子节点
//父元素.appendChild();
li.appendChild(gzText);
//获取id为city的节点
var city=document.getElementById("city");
city.appendChild(li);
});
mtClick("btn02",function(){
var li=createElement(li);
var gzText=document.createTextNode("广州");
li.appendChild(gzText);
var bj=document.getElementById("bj");
var city=document.getElementById("city");
city.insertBefore(li,bj);//可以在指定的子节点前,插入新的节点
});
myClick("btn03",function(){
var li=document.createElement("li");
var gzText=document.createTextNode("广州");
li.appendChild(gzText);
var bj=document.getElementById("bj");
var city=document.getElementById("city");
city.replaceChild(li,bj);
});
myClick("btn04",function(){
var bj=document.getElementById("bj");
//var city=document.getElentById("city");
//city.removeChild(bj);
bj.parentNode.removeChild(bj);//更常用,更方便
});
myClick("btn05",function(){
var city=document.getElementById("city");
alert(city.innerHTML);
});
myClick("btn06",function(){
var bj=document.getElementById("bj");
bj.innerHTML="昌平";
});
myClick("btn07",funtion(){
var city=document.getElementById("city");
//通过innerHTML修改,是覆盖,加上+=
//虽然创建简单,但是会让整个innerHTML动
city.innerHTML+="<li>广州</li>";
//改进
var li=document.createElement("li");
li.innerHTML+="广州";
});
function myClick(idStr,fun){
var btn=document.getElementById(idStr);
btn.onclick=fun;
}
};
DOM练习
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html";charset="UTF-8">
<title>添加删除记录练习</title>
<link rel="stylesheet" type="text/css" href="ex_2_style/css.css"/>
<script type="text/javascript">
function delA(){
/*
点击超链接以后,会跳转页面,这个是超链接的默认行为
但是此时我们不希望出现默认行为,可以通过在响应函数的最后return false来取消默认行为
或者:调整<a href="javascipt:;">Delete</a>
*/
//点击超链接后,删除本行
//
var tr=this.parentNode.parentNode;
var name=tr.getElementsByTagName("td")[0].innerHTML;
//var name=tr.children[0].innerHTML;
//删除之前,弹出一个提示框
//alert("确认删除吗?");
//confirm用于弹出一个带有确认取消按钮的提示框
//需要一个字符串作为参数,该字符串作为提示文字显示出来
if(confirm("确认删除"+name+"吗?"))
tr.parentNode.removeChild(tr);
return false;
};
//点击超链接之后,删除一个员工的信息
window.onload=function(){
var allA=document.getElementsByTagName("a");
for(var i=0;i<allA.length;i++){
allA[i].onclick=delA;
}
//添加记录的功能
var addEmpButton=document.getElementById("addEmpBUtton");
addEmpButton.onclick=function(){
var name=document.getElementById("empName").value;
var email=document.getElementById("email").value;
var salary=document.getElementById("salary").value;
//需要将获取的信息保存到tr中
var tr=document.createElement("tr");
var nameTd=document.createElement("td");
var emailTd=document.createElement("td");
var salaryTd=document.createElement("td");
var aTd=document.createElement("td");
var a=document.createElement("a");
var nameText=document.createTextNode(name);
var emailText=document.createTextNode(email);
var salaryText=document.createTextNode(salary);
var delText=document.createTextNode("Delete");
nameTd.appendChild(nameText);
emailTd.appendChild(emailText);
salaryTd.appendChild(salaryText);
a.appendChild(delText);
aTd.appendChild(a);
tr.appendChild(nameTd);
tr.appendChild(emailTd);
tr.appendChild(salaryTd);
tr.appendChild(aTd);
a.href="javascript:;";
a.onclick=delA;
var employeeTable=document.getElementById("employeeTable");
//因为浏览器会自动添加tbody,导致以上添加的内容和原本存在的数据内容不是兄弟关系,所以存在隐患,我们要继续改进
var tbody=employeeTable.getElementsByTagName("tbody")[0];
tbody.appendChild(tr);
/*
改进:
var tr=document.createElement("tr");
tr.innerHTML="<td>"+name+"</td>"+
"<td>"+email+"</td>"+
"<td>"+salary+"</td>"+
"<td><a href='javascipt:;'>Delete</a></td>";
//获取元素,绑定单击
var a=tr.getElementsByTagName("a")[0];
a.οnclick=delA;
*/
};
};
</script>
</head>
<body>
<table id="employeeTable">
<tr>
<th>Name</th>
<th>Email</th>
<th>Salary</th>
<th>%nbsp;</th>
</tr>
<tr>
<td>Tom</td>
<td>tom@tom.com</td>
<td>5000</td>
<td><a href="deleteEmp?id=001">Delete</a></td>
</tr>
<tr>
<td>Jerry</td>
<td>jerry@sohu.com</td>
<td>8000</td>
<td><a href="deleteEmp?id=002">Delete</a></td>
</tr>
<tr>
<td>Bob</td>
<td>bob@tom.com</td>
<td>10000</td>
<td><a href="deleteEmp?id=003">Delete</a></td>
</tr>
</table>
<div id="formDiv">
<h4>
添加新员工
</h4>
<table>
<tr>
<td class="word">name:</td>
<td class="inp"><input type="text" name="empName" id="empName"/></td>
</tr>
<tr>
<td class="word">email:</td>
<td class="inp"><input type="text" name="email" id="email"/></td>
</tr>
<tr>
<td class="word">salary:</td>
<td class="inp"><input type="text" name="salary" id="salary"/></td>
</tr>
<tr>
<td colspan="2" align="center">
<button id="addEmpButton" value="abc">Submit</button>
</td>
</tr>
</table>
</div>
</body>
</html>
补充一个索引问题
for循环会在页面加载完立即执行
而响应函数会在超链接被点击时才执行
当响应函数执行时,for循环早已执行完毕
使用DOM操作CSS
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width:200px;
height:200px;
background-color:red;
}
</style>
<script type="text/javascript">
window.onload=function(){
var box1=document.getElementById("box1");
var btn01=document.getElementById("btn01");
btn01.onclick=function(){
//语法:元素.style.样式名=样式值
//注意:如果css样式名中含有-号
//这种名称在JS中不合法,如:background-color
//需要将这种样式名修改为驼峰命名法
//去掉-,将-后的字母大写
box1.style.width="300px";
box1.style.width="300px";
box1.style.backgroundColor="yellow";
//我们通过style属性设置的样式都是内联样式
//而内联样式有较高的优先级,所以通过JS修改的样式往往会立即显示
//但是如果在样式中写了!important,则此时样式会具有最高优先级
//即使通过JS也不能覆盖该样式,此时将会倒是JS样式失效
//所以尽量不要为样式添加!important
};
var btn02=document.getElementById("btn02");
btn02.onclick=function(){
//读取样式
//语法:元素.style.样式名
//通过style读取和设置都是内联样式
//无法读取样式表里的内容
};
};
</script>
</head>
<body>
<button id="btn01">点我一下</button>
<button id="btn02">点我一下</button>
<br/>
<br/>
<div if="box1"></div>
</body>
</html>
获取元素的样式
读取元素的当前的样式
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width:100px;
height:100px;
background-color:yellow;
}
</style>
<script type="text/javascript">
window.onload=function(){
var box1=document.getElementById("box1");
var btn01=document.getElementById("btn01");
btn01.onclick=function(){
//alert("box1.style.width");这种方式只能读取内联样式
//如何获取元素的当前正在显示的样式
//语法:元素.currentStyle.样式名(这种方式只有IE浏览器支持)
//如果没有设置样式,那么会显示默认样式的值
//currentStyle只有IE支持
alert(box1.currentStyle.width);
alert(box1.currentStyle.backgroundColor);
//其他浏览器:getComputedStyle()方法,获取当前样式
//这个方法是window的方法,可以直接使用(IE8及以下不支持)
//第一个,要获取样式的元素
//第二个,可以传递一个伪元素,一般都传null
//该方法会返回一个对象,对象中封装了当前元素对应的样式
//如果获取的样式没有设置,则会获取真实的值,而不是默认值
//如:如果获取width,返回的是真实值,而不是auto
var obj=getComputedStyle(box1);
alert(obj.width);
//以上两种方式,读取的样式都是只读的,不能修改
};
};
//定义一个函数,用来获取指定元素的当前样式
//参数:obj要获取的样式名
function getSyle(obj,name){
if(window.getComputedStyle)
//写window,如果没有window它是一个变量,没有的时候,会报错
//写了window,就变成window的一个属性
return getComputedStyle(obj,null)[name];
else
return obj.currentStyle[name];
}
</script>
</head>
<body>
<button id="btn01">点我一下</button>
<div id="box1"></div>
</body>
</html>
其他样式相关的属性
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width:100px;
height:100px;
background-color:red;
border:10px solid yellow;
}
</style>
<script type="text/javascript">
window.onload=function(){
var box1=document.getElementById("box1");
var btn01=document.getElementById("btn01");
btn01.onclick=function(){
//clientWidth
//clientHeight,这些属性不带px,返回都是一个数字,可以直接进行计算
//包括内容区和内边距,也是只读的,不能修改
alert(box1.clientWidth);
//offsetWidth
//offsetHeight获取元素的整个的宽度和高度
//包括内容区、内边距和边框
alert(box1.offsetWidth);
//offsetParent
//获取当前元素的定位父元素
//获取离当前元素最近的开启了定位的祖先元素
//如果所有的祖先都没有开启定位,则返回body
var op=box1.sffsetParent;
alert(op.id);
//offsetLeft//相对于其定位元素的水平偏移量
//offsetTop//相对于其定位元素的垂直偏移量
alert(box1.offsetLeft);
//scrollHeight
//scrollWidth -可以获取滚动高度,滚动宽度
//scrollLeft
//scrollTop -获取水平滚动条水平、垂直移动的距离
//当scrollHeight-scrollTop==clientHeight时
//说明垂直滚动条滚动到底了
};
};
</script>
</head>
<body>
<button id="btn01">点我一下</button>
<br/><br/>
<div id="box1"></div>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#info{
width:300px;
height:500px;
background-color:green;
}
</style>
<script type="text/javascript">
window.onload=function(){
//onscroll会在滚动条滚动时触发
var info=document.getElementById("info");
var inputs=document.getElementsByTagName("input");
info.onscroll=function(){
//检查滚动条是否滚动到底了
if(info.scrollHeigth-info.scrollTop==info.clientHeight){
inputs[0].disabled=false;
inputs[1].disabled=false;//disabled属性可以设置是否禁用
}
};
};
</script>
</head>
<body>
<h3>欢迎亲爱的用户注册</h3>
<p id="info">亲爱的用户,请仔细阅读以下协议...</p>
<!-- 当滚动条到底了,才可以点击,先设置disabled不能选 -->
<input type="checkbox" disabled="disabled" />我已自习阅读协议,一定遵守
<input type="submit" value="注册"/>
</body>
</html>
事件对象
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#areaDiv{
}
#showMsg{
border:1px solid black;
width:300px;
height:20px;
}
</style>
<script type="text/javascript">
window.onload=function(){
//当鼠标在Div中移动时,在showMsg中显示坐标
var areaDiv=document.getElementById("areaDiv");
var showMsg=document.getElementById("showMsg");
//onmousemove鼠标移动事件
//鼠标在元素中移动时触发
areaDib.onmousemove=function(event){
//在IE8中,响应函数被触发时,浏览器不会传递事件对象
//在IE8及以下浏览中,是将事件对象作为window对象的属性保存的
//在showMsg中显示坐标
//事件对象
//- 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数
//我们只要设置一个形参就可以,获取事件对象的信息
//在事件对象中,封装了当前事件的一切相关信息,比如,鼠标的坐标,键盘哪个案件被按下等
//clientX可以获取鼠标指针的水平坐标
//clientY可以获取鼠标指针的垂直坐标
//做一个判断
if(!event)
event=window.event;//用来处理兼容性问题,解决事件对象的兼容性问题
//或者 event=event||window.event;
var x=event.clientX;
var y=event.clientY;
showMsg.innerHTML="x="+x+"y="+y;
}
};
</script>
</head>
<body>
<div id="areaDiv"></div>
<div id="showMsg"></div>
</body>
</html>
div跟随鼠标移动练习
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width:100px;
height:100px;
background-color:red;
/*要设置定位,一定要开启定位
*/
position:absolute;
}
</style>
<script type="text/javascript">
window.onload=function(event){
var box1=document.getElementById("box1");
document.onmousemove=function(event){
//如果是box1.onmousemove,只要鼠标移出box1的范围,就不跟着走了,所以用document
event=event||window.event;//解决兼容性问题
var left=event.clientX;
var top=event.clientY;
//clientX和ClientY用于获取当前的可见窗口的坐标
//-div的偏移量,是相对于整个页面的
//pageX和pageY是相对于整个页面的
//-但是这两个属性在IE8中不支持,所以如果需要兼容IE8,则不要使用pageX,pageY
left=event.pageX;
top=event.pageY;
//法2:获取滚动条滚动的距离
//有些浏览器认为是滚动条是body的,有些认为是html根标签的(多)
//解决兼容性问题
var st=document.body.scrollTop||document.documentElement.scrollTop;
var sl=document.body.scrollLeft||document.documentElement.scrollLeft;
box1.style.left=left+sl+"px";//手动加上sl的长度
box1.style.top=top+st+"px";//手动加上st的长度
};
};
</script>
</head>
<body>
<div id="box1"></div>
</body>
</html>
事件的冒泡
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width:200px;
height:200px;
background-color:yellowgreen;
}
#s1{
background-color:yellow;
}
</style>
<script type="text/javascript">
window.onload=function(){
//事件的冒泡
//所谓的冒泡就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
//在开发中,冒泡是有用的
//如果不希望发生事件冒泡,可以通过事件对象来取消冒泡
var s1=document.getElementById("s1");
s1.onclick=function(event){
event=event||window.event;
alert("我是span的单击响应函数");
//可以将事件对象的cancelBubble设置为true,即可取消冒泡
event.cancelBubble=true;
};
var box1=document.getElementById("box1");
box1.onclick=function(event){
event=event||window.event;
alert("我是box1的单击响应函数");
event.cancelBubble=true;
};
var body=document.getElementById("body");
body.onclick=function(){
alert("我是body的单击响应函数");
};
};
</script>
</head>
<body>
<div id="box1">
我是box1
<span id="s1">我是span</span>
</div>
</body>
</html>
事件的委派
事件的委派:
将事件统一绑定给共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素
event.target :target表示触发事件的对象
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
window.onload=function(){
var u1=document.getElementById("u1");
var btn01=document.getElementById("btn01");
btn01.onclick=function(){
var li=document.createElement("li");
li.innerHTML="<a href='javascript:;' class='link'>新建的超链接</a>";
u1.appendChild(li);
};
//这里我们为每一个超链接都绑定单击响应函数,这种操作比较麻烦
//而且这些操作只能为已有的超链接设置事件,而新添加的超链接必须重新绑定
//var allA=document.getElementsByTagName("a");
//for(var i=0;i<allA.length;i++){
//allA[i].οnclick=function(){
//alert("我是a的单击响应函数");
//};
//}
//我们希望,只绑定一次事件,即可应用到多个元素上,即使元素是后添加的
//我们可以尝试将其绑定给父元素或者共同的祖先元素
u1.onclick=function(event){
//如果触发事件的对象是我们期望的元素,则执行,否则不执行
event=event||window.event;
if(event.target.className=="link")
//target表示的是触发事件的对象,由谁触发就是谁
alert("我是u1的单击响应函数");
};
};
</script>
</head>
<body>
<button id="btn01">添加超链接</button>
<ul id="u1">
<li><p>我是p元素</p></li>
<li><a href="javascript:;" class="link">超链接一</a></li>
<li><a href="javascript:;" class="link">超链接二</a></li>
<li><a href="javascript:;" class="link">超链接三</a></li>
</ul>
</body>
</html>
事件的绑定
addEventListener()函数
不支持IE8及以下浏览器
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
window.onload=function(){
var btn01=document.geteElementById("btn01");
//使用对象.事件=函数 的形式绑定响应函数
//-它只能同时为一个元素的一个事件绑定一个响应函数
//-不能绑定多个,如果绑定了多个,则后边会覆盖掉前边的
btn01.onclick=function(){
alert(1);
};
btn01.onclick=function(){
alert(2);
};
//addEventListener()
//-通过这个方法可以为元素绑定响应函数
//-参数 1.事件的字符串,不要on
// 2.回调函数,当事件触发时该函数会被调用
// 3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false
btn01.addEventListener("click",function(){
alert(1);
},false);
btn01.addEventListener("click",function(){
alert(2);
},false);//可以实现为一个元素的相同事件同时绑定多个响应函数
//按照绑定的事件的顺序执行
//在IE8中可以使用attachEvent()
//参数 : 1.事件的字符串,要on
// 2.回调函数
// 这个方法也可以同时为一个事件绑定多个处理函数
// 不同的是,它是后绑定的先执行,执行顺序和addEventListener()相反
btn01.attachEvent("onclick",function(){
alert(1);
});
btn01.attachEvent("onclick",function(){
alert(2);
});
btn01.attachEvent("onclick",function(){
alert(3);
});
};
//addEventListener()中的this,是绑定事件的对象
//attachEvent()中的this,是window
//需要统一一下这两种方法
//定义一个函数,用来为指定元素绑定响应函数--要兼容所有浏览器
//参数,obj 要绑定的事件的对象,eventStr 事件的字符串 , callback 回调函数
function bind(obj,eventStr,callback){
if(obj.eventListener){
obj.addEventListener(eventStr,callback,false);
}
else{
//this是谁由调用方式决定
//callback.call(obj)
//obj.attachEvent("on"+eventStr,callback);
obj.attachEvent("on"+eventStr,function(){
//在匿名函数中调用回调函数,this改变了
callback.call(obj);
});
}
}
</script>
</head>
<body>
<button id="btn01">点我一下</button>
</body>
</html>
事件的传播
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width:300px;
height:300px;
background-color:yellowgreen;
}
#box2{
width:200px;
height:200px;
background-colod:yellow;
}
#box3{
width:150px;
height:150px;
background-color:skyblue;
}
</style>
<script type="text/javascript">
window.onload=function(){
var box1=document.getElementById("box1");
var box2=document.getElementById("box2");
var box3=document.getElementById("box3");
bind(box1,"click",function(){
alert("我是box1的响应函数");
});
bind(box2,"click",function(){
alert("我是box2的响应函数");
});
bind(box3,"click",function(){
alert("我是box3的响应函数");
});
//事件的传播
//1.捕获阶段:在捕获阶段从最外层的祖先元素,向目标元素进行时间的捕获,但是默认此时不会触发事件
//2.目标阶段:事件捕获到目标元素
//3.冒泡阶段:事件从目标元素想祖先元素传递,一次出发祖先元素上的事件
//如果希望捕获阶段就出发事件,可以将addEventListener()的第三个三处设置为false,一般我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
//IE8及以下浏览器没有捕获阶段
};
function bind(obj,eventStr,callback){
if(obj.eventListener){
obj.addEventListener(eventStr,callback,false);
}
else{
obj.attachEvent("on"+eventStr,function(){
callback.call(obj);
});
}
</script>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
</body>
</html>
拖拽
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width:100px;
height:100px;
background-color:red;
position:absolute;
}
#box2{
width:100px;
height:100px;
background-color:yellow;
position:absolute;
left:200px;
top:200px;
}
</style>
<script type="text/javascript">
window.onload=function(){
//完成拖拽
/* 1.当鼠标在拖拽原属上按下时,开始拖拽 onmousedown
2.当鼠标移动时,被拖拽元素跟随鼠标移动 onmousemove
3.当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
*/
var box1=document.getElementById("box1");
box1.onmousedown=function(event){
//setCapture()只在IE里支持
if(box1.setCapture)
box1.setCapture();
//或者:(高级一点)
//box1.setCapture&&box1.setCapture();
//为document绑定一个onmousemove事件
event=event||window.event;
//求出偏移量:鼠标.clientX-元素.offsetLeft
// 鼠标.clientY-元素.offsetTop
var ol=event.clientX-box1.offsetLeft;
var ot=event.clientY-box1.offsetTop;
document.onmousemove=function(event){
event=event||window.event;
//获取鼠标的坐标
var left=event.clientX-ol;
var top=event.cilentY-ot;
box1.style.left=left+"px";
box1.style.top=top+"px";
};
document.onmouseup=function(){
//注意也是给document绑定onmouseup事件
//为元素绑定一个鼠标松开事件onmouseup
//取消document.onmousemove事件
document.onmousemove=null;
//取消onmouseup事件
document.onmouseup=null;
//当鼠标松开时,取消对事件的捕获
box1.releaseCapture&&box1.releaseCapture();
};
//当我们去拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,此时,会导致拖拽功能的异常,这个是浏览器的默认行为
//如果不希望发生这个行为,则可以通过return false 取消默认行为
//但是对IE8不起作用
return false;
};
};
</script>
</head>
<body>
我是一段文字
<div id="box1"></div>
<div id="box2"></div>
</body>
</html>
btn01.setCapture();
//设置btn01对鼠标按下的相关事件进行捕获
//当调用一个元素的setCapture()方法以后,这个元素将会把下一次所有的鼠标按下的相关的事件捕获带自身上
//提取一个专门用来设置拖拽的函数
//参数:开始拖拽的元素
function drag(obj){
obj.onmousedown=function(event){
//setCapture()只在IE里支持
if(obj.setCapture)
obj.setCapture();
//或者:(高级一点)
//box1.setCapture&&box1.setCapture();
//为document绑定一个onmousemove事件
event=event||window.event;
//求出偏移量:鼠标.clientX-元素.offsetLeft
// 鼠标.clientY-元素.offsetTop
var ol=event.clientX-obj.offsetLeft;
var ot=event.clientY-obj.offsetTop;
document.onmousemove=function(event){
event=event||window.event;
//获取鼠标的坐标
var left=event.clientX-ol;
var top=event.cilentY-ot;
obj.style.left=left+"px";
obj.style.top=top+"px";
};
document.onmouseup=function(){
//注意也是给document绑定onmouseup事件
//为元素绑定一个鼠标松开事件onmouseup
//取消document.onmousemove事件
document.onmousemove=null;
//取消onmouseup事件
document.onmouseup=null;
//当鼠标松开时,取消对事件的捕获
obj.releaseCapture&&obj.releaseCapture();
};
//当我们去拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,此时,会导致拖拽功能的异常,这个是浏览器的默认行为
//如果不希望发生这个行为,则可以通过return false 取消默认行为
//但是对IE8不起作用
return false;
};
};
滚轮的事件
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width:100px;
height:100px;
background-color:red;
}
</style>
<script type="text/javascript">
window.onload=function(){
//当鼠标滚轮向下滚动时,box1变长,向上滚动时,box1变短
var box1=document.getElementById("box1");
box1.onmousewheel=function(){
//鼠标滚动时会触发,火狐不支持
//在火狐中,使用DOMmouseScroll 来绑定滚动事件
//注意,该事件要通过addEventListener()函数来绑定
};
box1.onmousewheel=function(event){
//判断鼠标滚轮滚动的方向
event=event||window.event;
event.wheelDelta;//获取滚轮滚动的方向,向上为正,向下为负
//火狐里面不支持wheelDelta
//火狐中使用event.detail来获取滚动的方向
//向上为负,向下为正
if(event.wheelDelta>0||event.detail<0){
box1,style.height=box1.clientHeight-10+"px";
}else{
box1.style.height=box1.clientHeight+10+"px";
}
//使用addEventListener()保定响应函数,取消默认行为时,不能使用return false,IE浏览器不支持,如果直接调用会报错
event.preventDefault&&event.preventDefault();
//当滚动时,如果浏览器也有滚动条,滚动条也会随之滚动
//这是浏览器的默认行为,如果不希望发生,则可以取消默认行为
return false;
};
bind(box1,"DOMMouseScroll",box1.onmousewheel);
};
function bind(obj,eventStr,callback){
if(obj.eventListener){
obj.addEventListener(eventStr,callback,false);
}
else{
obj.attachEvent("on"+eventStr,function(){
callback.call(obj);
});
}
</script>
</head>
<body>
<div id="box1"></div>
</body>
</html>
键盘事件
onkeydown
-
对于onketdown来说,如果一直按着某个按键不松手,则事件会一直触发
-
当onkeydown连续触发时,第一次和第二次之间会间隔稍长一点,其他的会非常的快
-
这种设计是为了防止误操作的发生
onkeyup
<!doctype>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
window.onload=function(){
//键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document
/* document.οnkeydοwn=function(){
console.log("被按下");
};
document.οnkeyup=function(){
console.log("松开");
};*/
document.onkeydown=function(event){
event=event||window.event;
//可以通过keyCode来获取按键的编码
//通过它可以判断哪个按键是否被按下
//除了keyCode,事件对象中还提供了几个属性
//altKey/crtlKey/shiftKey 用来判断相应按键是否被按下,如果按下,返回true,否则返回false
if(event.keyCode===89&&event.ctrlKey)
console.log("control和y都被按下了");
};
var input=document.getElementsByTagName("input")[0];
input.onkeydown=function(event){
//console.log("按键被按下了");
//数字0-9的keyCode是48-57
event=event||window.event;
if(event.ketType>=48&&eventkeyType<=57){
return false;//输入数字时,取消了默认行为,使得用户输入数字输不到文本框中
}
return false;//取消默认行为
//在文本框中输入内容属于onkeydown默认行为
//如果onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
};
};
</script>
</head>
<body>
<input type="text"/>
</body>
</html>
键盘移动div练习
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width:100px;
height:100px;
background-color:red;
position:absolute;
}
</style>
<script type="text/javascript">
window.onload=function(){
//为document绑定键盘按下的事件
document.onkeydown=function(event){
event=event||window.event;
var speed=10;
//37 左 38 上 39 右 40 下
if(event.ctrlKey){
speed=50;//如果按了control,会加速
}
switch(event.keyCode){
case 37:
box1,style.left=box1.offsetLeft-speed+"px";
break;
case 38:
box1.style.Top=box1.offsetTop-speed+"px";
break;
case 39:
box1,style.left=box1.offsetLeft+speed+"px";
break;
case 40:
box1.style.Top=box1.offsetTop+speed+"px";
break;
}
};
};
</script>
</head>
<body>
<div id="box1"></div>
</body>
</html>