一、昨日反馈
1、事件对象
- IE浏览器获取事件对象: window.event;
- 非IE:使用的是事件处理函数的形参
- 兼容性的写法:var e = window.event||evt;
2、获取页面中的节点
- document.getEle….By…
- document.querySelector(‘css选择器’);
- document.querySelectorAll(‘css选择器’);
<ul>
<li>刘备</li>
<li>关羽</li>
<li>张飞</li>
</ul>
<script>
/*** 演示查找页面中的元素 **/
//var liu = document.getElementsByTagName('li')[0];
//var liu = document.querySelector('li'); //只查找符号条件的第一个元素
var ul = document.querySelector('ul');
var liu = ul.firstElementChild;
liu.style.color = 'red';
/*** 创建并添加元素 ***/
//创建一个<li>曹操</li>,并放到ul中
var li = document.createElement('li'); //创建li这个标签节点
var text = document.createTextNode('曹操');
li.appendChild(text); //把文本节点放到li中
document.querySelector('ul').appendChild(li);
</script>
二、今日目标
- 1、能够对属性类型的节点进行增删改查操作(重点)
- 2、能够学会使用innerHTML和innerText(重点)
- 3、知道通过nodeValue可以获得文本类型的节点的值
- 4、知道nodeType表示什么
- 5、能够掌握三种绑定事件的方式(重点)
- 6、能够知道事件处理函数中this表示什么(重点、难点)
- 7、能够知道如何移除事件
- 8、能够通过事件对象的keyCode获取键盘的对应值
- 9、了解什么是冒泡事件及会阻止冒泡事件的发生
- 10、能够会用一种办法阻止标签的默认行为
三、DOM之属性节点操作
属性不能单独存在,一定属于一个标签。所有,操作属性,前提必须找到标签。
1、获取元素的属性
attributes:元素标签的所有属性
getAttribute(); :获取元素的属性。只能获取有具体值的属性 属性吗=‘属性值’
var t = input.getAttribute('type'); //getAttribute(); 获取type属性
元素.属性:获取元素的属性,能够获取类似于readOnly、cheCked等属性
var t2 = input.type; //获取type属性 能够获取类似于readOnly、checked等属性
2、添加/修改元素的属性
- 元素节点.setAttribute(属性名,属性值)
- 元素节点.属性名 = 值
<input type="text" name="tel" />
<script>
//setAttribute方法
var input = document.querySelector('input');
input.setAttribute('name', 'email'); //修改,修改input的name值为email
input.setAttribute('value', '你好'); //添加,添加value属性,值为你好
//元素.属性名 = 值;
input.size = 5;
input.value = 'hello';
input.disabled = true; // true表示禁用,false表示非禁用状态
</script>
如果要设置checked、readonly、disabled,则需要设置它的值为true或false。
3、删除元素的属性
- 元素节点.removeAttribute(属性名) 删除一个属性
4、判断元素是否有哪个属性
- elementNode.hasAttribute(属性名) 检测是否有某个属性,有返回true,没有返回false
<input type="text" name="tel" />
<script>
var input = document.querySelector('input');
//删除input的name属性
input.removeAttribute('name');
//判断元素的属性是否存在
console.log(input.hasAttribute('name')); //false,上面删除了
console.log(input.hasAttribute('type')); //true
</script>
总结:
- 节点分为元素类型的节点和属性类型的节点,也包括文本类型的节点。
元素/标签类型的节点:
增: document.createElement()、document.createTextNode()、父节点.appendChild()、父节点.insertBefore()
删:父节点.removeChild();
改:父节点.replaceChild();
查:document.getEle….By… document.querySelector()
属性类型的节点:
增:元素.setAttribute(属性名, 值); 元素.属性名 = 值;
删:元素.removeAttribute(属性名);
改:元素.setAttribute(属性名, 值); 元素.属性名 = 值;
查:元素.attributes; 元素.getAttribute(属性名); 元素.属性名;
四、DOM对象的通用属性
innerHTML:获取/设置元素里的html内容
innerText:获取/设置元素里面的文本内容
演示获取标签里面内容的代码:
演示获取标签里面内容的代码:
<p><span>你好</span><b>hello</b></p>
<script>
//获取p元素里面的html内容 -- innerHTML
//找到p元素
var p = document.querySelector('p');
console.log(p.innerHTML);
//获取p元素里面的文本内容 -- innerText
console.log(p.innerText);
/** 设置p元素里面的内容 **/
p.innerHTML = "<a href='#'>跳转</a>"; //设置p的内容之后,会覆盖掉原来的内容
p.innerText = '最终文本'; //设置p的内容之后,会覆盖掉原来的内容
</script>
nodeName
nodeName 是只读的
元素节点的 nodeName 与标签名相同
属性节点的 nodeName 与属性名相同
文本节点的 nodeName 始终是 #text
文档节点的 nodeName 始终是 #document
nodeValue
元素节点的 nodeValue 是 undefined 或 null
文本节点的 nodeValue 是文本本身
属性节点的 nodeValue 是属性值
nodeType:调用nodeType属性会得到一个数字,这个数字表示节点的类型
元素 1
属性 2
文本 3
注释 8
文档 9
下面代码演示了使用nodeValue和nodeType的例子:
下面代码演示了nodeType的其他用法:
<ul>
<li>hello</li>
<li>hello</li>
<li>hello</li>
<li>hello</li>
</ul>
<script>
//先找到li
var li = document.getElementsByTagName('li')[0];
console.log(li.childNodes[0].nodeValue);
//查看节点的类型 -- nodeType
console.log(li.nodeType); // 元素类型的,结果是 1
console.log(li.childNodes[0].nodeType); //文本类型的,结果是 3
//使用nodeType的例子
//先找到ul
var ul = document.getElementsByTagName('ul')[0];
//console.log(ul.children); //children会忽略文本类型的子节点
//函数,参数是父元素,返回该父元素的所有元素类型的子节点。但是不能使用children,必须使用childNodes
function getChildren(ele){
var all = ele.childNodes; //找到所有子元素,包含文本和标签类型
var result = []; //用于保存元素类型的节点
for(var i=0; i<all.length; i++){
if(all[i].nodeType == 1){
//nodeType是1,说明是标签类型的
result.push(all[i]);
}
}
return result;
}
console.log(getChildren(ul));
</script>
案例 — 全选、反选、取消
<p align="center">
<a href="javascript:void(0);" id="quanxuan">全选</a>
<a href="javascript:void(0);" id="fanxuan">反选</a>
<a href="javascript:void(0);" id="quxiao">取消</a>
</p>
<table border="1" cellpadding="2" cellspacing="0" rules="all" align="center" width="500">
<tr>
<th>ID</th>
<th>标题</th>
</tr>
<tr>
<td>
<input type="checkbox" name="id[]" value="1">
</td>
<td>诸葛亮是一个医学家</td>
</tr>
<tr>
<td>
<input type="checkbox" name="id[]" value="1">
</td>
<td>诸葛亮是一个医学家</td>
</tr>
<tr>
<td>
<input type="checkbox" name="id[]" value="1">
</td>
<td>诸葛亮是一个医学家</td>
</tr>
<tr>
<td>
<input type="checkbox" name="id[]" value="1">
</td>
<td>诸葛亮是一个医学家</td>
</tr>
<tr>
<td>
<input type="checkbox" name="id[]" value="1">
</td>
<td>诸葛亮是一个医学家</td>
</tr>
<tr>
<td>
<input type="checkbox" name="id[]" value="1">
</td>
<td>诸葛亮是一个医学家</td>
</tr>
<tr>
<td>
<input type="checkbox" name="id[]" value="1">
</td>
<td>诸葛亮是一个医学家</td>
</tr>
</table>
<script>
//全选
//选择a标签,然后绑定单击事件
document.getElementById('quanxuan').onclick = function(){
//点击全选后,做的工作都写到这个函数中
//alert(123);
//找到所有的input标签
var inputs = document.getElementsByTagName('input'); //找到所有的input
//var inputs = document.querySelector('input[type="checkbox"]'); //找到所有的input
//console.log(inputs);
for(var i in inputs){
inputs[i].checked = true;
}
};
//取消
//选择a标签,然后绑定单击事件
document.getElementById('quxiao').onclick = function(){
//点击取消后,做的工作都写到这个函数中
//alert(123);
//找到所有的input标签
var inputs = document.getElementsByTagName('input'); //找到所有的input
//var inputs = document.querySelector('input[type="checkbox"]'); //找到所有的input
//console.log(inputs);
for(var i in inputs){
inputs[i].checked = false;
}
};
//反选
document.getElementById('fanxuan').onclick = function () {
//找到所有的input标签
var inputs = document.getElementsByTagName('input'); //找到所有的input
//遍历,设置input的check属性
for(var i in inputs){
/*if(inputs[i].checked == true){
inputs[i].checked = false;
}else{
inputs[i].checked = true;
}*/
inputs[i].checked = !inputs[i].checked;
}
};
</script>
五、DOM获取元素的位置
- offsetLeft 元素在网页中水平坐标值
- offsetTop 元素在网页中垂直坐标值
- offsetWidth 元素在页面中占据的宽度
- offsetHeight 元素在页面中占据的高度
- scrollLeft 滚动条在容器中水平滚动的距离,多用于浏览器的滚动条
- scrollTop 滚动条在容器中垂直滚动的距离,多用于浏览器的滚动条
有的浏览器只要一刷新,滚动条就会到最顶部,做左侧,所以需要绑定滚动事件
这部分内容一般用于窗口显示,异步加载等。目前可以作为了解的内容,等学习了jQuery,jQuery中有封装好的兼容各个浏览器的方法。
六、事件绑定与移除
事件绑定就是添加事件,那么为谁添加事件呢?可以为页面中的所有标签(元素、节点)添加事件,大到整个文档(document),小到其中一个标签都可以添加事件。
在为一个节点添加事件的时候,有三种方式:
- 直接在标签中添加,即使用onclick、onmouseover等HTML属性;
- DOM的方式添加,即通过dom方法获取节点,然后为其绑定事件;
- 使用addEventListener或attachEvent(IE8及更低版本浏览器)。
为一个标签添加事件之后,还可以删除这个事件。
1、为DOM对象添加事件
最基本的语法:
DOM对象.事件 = 处理函数;
有些时候,可以先定义处理函数,然后在绑定事件:
事件处理函数中,this表示什么?
2、直接在HTML标签中添加事件
通过html标签的on….属性(onclick、onmouseover…),来添加事件。
如果说,单击按钮的时候,要执行的代码非常多,则可以将代码封装成函数,然后onclick的时候,调用函数即可,函数中的this是window对象。
如果上面两种绑定事件的方式都存在,执行哪一种?优先执行DOM方式绑定的事件
上面两种方式绑定事件,都可以通过设置事件处理函数为null来去取事件:
document.getElementById('btn').onclick = null;//取消事件
3、事件监听使用addEventListener或attachEvent方法添加事件
使用下面的方法为DOM对象添加事件,也叫做事件监听。
- IE浏览器中用:元素节点.attachEvent(事件名, 事件处理函数);
- 火狐浏览器用:元素节点.addEventListener(事件名, 事件处理函数);// 事件名不要带on
为了兼容各个浏览器,可以自定义一个兼容的函数,来为元素绑定事件:
button id="btn">点击测试</button>
<script>
var btn = document.getElementById('btn');
/*********** 自定义事件监听函数 ***********/
function addEvent(ele, type, fn){
if(window.addEventListener){
ele.addEventListener(type, fn);
}else{
ele.attachEvent('on' + type, fn);
}
}
//测试自定义函数是否可用
function m(){
alert(111);
}
addEvent(btn, 'click', m);
function n(){
alert(222);
}
addEvent(btn, 'click', n);//绑定两个相同的事件
</script>
事件监听方式添加的事件,特点是可以为一个元素绑定多个同类型的事件。
通过事件监听方法添加的事件,也可以被移除,移除的方法是:
- 火狐:元素节点.removeEventListener(事件名, 处理函数); //事件名不要带on
- IE:元素节点.dettachEvent(事件名 处理函数);
也可以自定义一个兼容各个浏览器的移除事件监听的方法:
/*** 自定义事件监听移除函数 ***/
function removeEvent(ele, type, fn){
if(window.removeEventListener){
ele.removeEventListener(type, fn);
}else{
ele.detachEvent('on' + type, fn);
}
}
//调用移除方法,测试
removeEvent(btn, 'click', m);
七、事件对象相关属性和方法使用
事件对象存在于事件处理函数中。不同的浏览器获取事件对象的方式也不同,IE始终使用window.event来当做事件对象,非IE浏览器使用事件处理函数的形参当做事件对象。
1、获取键盘的keyCode值
<input type="text" id="btn" />
<script>
document.getElementById('btn').onkeyup = function (evt) {
//IE获取事件对象的方法:window.event;
//非IE浏览器获取事件对象的方式:处理函数是形参
var e = window.event||evt; //兼容各个浏览器的获取事件对象的方式
//console.log(e);
//通过事件对象可以获取键盘的keyCode值
var keyCode = e.keyCode; //获得的keyCode可以用于判断用户按的是哪个键
console.log(keyCode);
};
</script>
2、冒泡事件及阻止冒泡事件的发生
什么是冒泡事件?
上述小例子中,点击元素的子元素,会透过子元素触发元素本身的事件,这就是冒泡事件。
有些时候要的就是这个效果,可以不做任何处理;有些时候不希望有冒泡事件发生,那么可以通过事件对象的方法来阻止冒泡的发生。
阻止冒泡事件的发生有:
- 标准浏览器使用 evt.stopPropagation(); //evt指的是事件对象
- IE内核浏览器使用 window.event.cancelBubble = true;
可以封装一个兼容各个浏览器的阻止冒泡的方法:
<style>
#d1{
width:200px;
height:200px;
background-color: brown;
}
#d2{
width:100px;
height:100px;
background-color: chartreuse;
}
</style>
<div id="d1">
<div id="d2"></div>
</div>
<script>
/** 阻止冒泡函数 **/
function zuzhi(evt){
if(window.event){
window.event.cancelBubble = true;
}else{
evt.stopPropagation(); //evt指的是事件对象
}
}
//分别给两个div绑定单击事件
document.getElementById('d1').onclick = function () {
alert(11111);
};
document.getElementById('d2').onclick = function (evt) {
alert(22222);
//阻止冒泡发生
zuzhi(evt);
};
</script>
3、阻止标签的默认行为
默认行为就是html标签的一些默认行为,比如点击a标签会跳转,比如点击了submit按钮表单会提交。这些都属于标签的默认行为。
有些时候,点击了a标签或者submit按钮后不希望执行标签的默认行为,这时候就需要阻止默认行为。
阻止默认行为:
- 标准浏览器:evt.preventDefault();
- IE内核浏览器:window.event.returnValue = false;
<a href="13冒泡事件.html">跳转</a>
<form name="f1" action="07全选.html" method="post">
用户名:<input type="text" name="username"><br>
密 码:<input type="password" name="pwd"><br>
<input type="submit" id="sub" value="提交">
</form>
<script>
/********* 阻止标签的默认行为 *********/
//形参evt标签标准浏览器的事件对象
function zuzhi(evt){
if(window.event){
//IE浏览器
window.event.returnValue = false;
}else{
//非IE浏览器
evt.preventDefault();
}
}
//测试
document.getElementById('sub').onclick = function (evt) {
//检测用户名是否为空
if(document.f1.username.value == ''){
alert('用户名不能为空');
//阻止表单提交
zuzhi(evt);
//return false; //return false也可以阻止表单提交
}
};
</script>
八、案例–可编辑的表格
1、完成html+css
*{
margin:0;
padding:0;
border:0 none;
}
table,th,td{
border:solid 1px #1b272e;
border-collapse: collapse; /*合并边框*/
}
table{
width:400px;
margin:10px auto; /*左右居中对齐*/
}
th,td{
width:50%;
padding:3px;
}
<table>
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>林冲</td>
</tr>
<tr>
<td>2</td>
<td>武松</td>
</tr>
<tr>
<td>3</td>
<td>金莲</td>
</tr>
<tr>
<td>4</td>
<td>武大</td>
</tr>
<tr>
<td>5</td>
<td>杨志</td>
</tr>
<tr>
<td>6</td>
<td>曹浩</td>
</tr>
</tbody>
</table>
2、JS做隔行换色
//隔行换色
//找到所有的tbody中的tr
var trs = document.querySelectorAll('tbody tr');
//console.log(trs);
for(var i=0; i<trs.length; i++){
if(i%2 == 0){
trs[i].style.backgroundColor = '#d4d4d4';
}
}
3、给姓名所在的td添加单击事件
4、单击td,创建input并放到td中
5、设置input的样式和td一样
//兼容各个浏览器的获取完整css样式的写法
function getStyle(node, styleName){
if(node.currentStyle){
//说明是IE
return node.currentStyle[styleName];
}else{
return getComputedStyle(node)[styleName];
}
}
设置input的样式,并获取焦点:
6、给input绑定事件完全确定和取消功能
完整代码
<style>
*{
margin:0;
padding:0;
border:0 none;
}
table,th,td{
border:solid 1px #1b272e;
border-collapse: collapse; /*合并边框*/
}
table{
width:400px;
margin:10px auto; /*左右居中对齐*/
}
th,td{
width:50%;
padding:3px;
}
</style>
<table>
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>林冲</td>
</tr>
<tr>
<td>2</td>
<td>武松</td>
</tr>
<tr>
<td>3</td>
<td>金莲</td>
</tr>
<tr>
<td>4</td>
<td>武大</td>
</tr>
<tr>
<td>5</td>
<td>杨志</td>
</tr>
<tr>
<td>6</td>
<td>曹浩</td>
</tr>
</tbody>
</table>
<script>
//兼容各个浏览器的获取完整css样式的写法
function getStyle(node, styleName){
if(node.currentStyle){
//说明是IE
return node.currentStyle[styleName];
}else{
return getComputedStyle(node)[styleName];
}
}
//隔行换色
//找到所有的tbody中的tr
var trs = document.querySelectorAll('tbody tr');
//console.log(trs);
for(var i=0; i<trs.length; i++){
if(i%2 == 0){
trs[i].style.backgroundColor = '#d4d4d4';
}
}
//找姓名所在的td
var tds = document.querySelectorAll('tbody td:nth-child(2n)');
//console.log(tds); //
//循环,为每个符合条件的td绑定单击事件
for(var i=0; i<tds.length; i++){
//循环过程中,为每个td绑定单击事件
tds[i].onclick = function(){
//alert(123);
// 创建一个input,设置input的样式和当前td样式一致。
//input的value值应该是当前td中的文本
//将this赋值给一个变量
var td = this;
//判断,如果说当前的td中有一个input了,就不要执行下面的代码了
if(td.children.length >= 1){
return false;
}
//保存td中的文本
var text = td.innerText;
//清空td
td.innerHTML = '';
//创建input
var input = document.createElement('input');
//设置input的样式
input.style.width = getStyle(td, 'width'); // getConmputedStyle currentStyle
input.style.height = getStyle(td, 'height');
input.style.backgroundColor = getStyle(td, 'backgroundColor');
input.style.fontSize = getStyle(td, 'fontSize');
input.style.outline = 'none';
//设置input的value值
input.value = text;
//把input放到td中
td.appendChild(input);
//让input获取焦点
input.focus();
//绑定键盘事件
input.onkeyup = function (evt) {
var e = window.event||evt;
var keyCode = e.keyCode;
if(keyCode == 13){ //表示按了回车,表示确定
td.innerHTML = ''; //先清空td中的input
td.innerHTML = this.value;
}
if(keyCode == 27){ //按ESC键表示取消
td.innerHTML = ''; //先清空td中的input
td.innerHTML = text;
}
};
//失去焦点,表示取消修改
/*input.onblur = function () {
td.innerHTML = text;
};*/
};
}
</script>