webAPI(DOM) 2.1 获取页面元素 | 事件1 | 属性操作 | 节点 | 创建元素 | 事件2
js分三个部分:
ECMAScript标准:js的基本语法
DOM:Ducument Object Model--->文档对象模型--->操作页面的元素
BOM:Browser Object Model--->浏览器对象---->操作浏览器
1,什么是api-----可以理解为一套方法(或者工具)
2,什么是webapi-----那就是网络提供的方法(或者工具)
获取页面元素的几种方法
1,根据标签名获取元素
document.getElementsByTagName('div'); // 能够获取所有div标签
可以通过已找到的元素来调用
2,根据标签的class属性获取元素
document.getElementsByClassName('nav'); // 能够获取所有class="nav"的元素
可以通过已找到的元素来调用
在IE9以后的版本才支持!
3,根据标签的name属性获取元素
document.getElementsByName('mv'); // 能获取所有name="mv"的元素
在不同浏览器工作的方式不同,在IE和Opera浏览器下这个方法
将返回具有id属性和name属性是这个值的!
4,根据标签的id属性获取元素
document.getElementById('btn'); // 只能获取第一个id="btn"的元素
只能通过document来调用!
5,根据选择器来查找元素:
document.querySelector('ul li'); // 只能获取第一个元素
document.querySelectorAll('ul li'); // 可以获取ul下的所有li元素
有浏览器兼容性问题,在IE8以后的版本才会执行。移动端开发可以直接使用,不用担心兼容性问题
事件1
事件:就是当什么时候做什么事情
触发~响应
1,先获取元素
2,给元素注册事件
事件名称
事件源
事件处理函数
实例:点击按钮后弹出窗口
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试</title> </head> <body> <input type="button" value="点我" id="btn"> <script> // 先获取元素 var btn = document.getElementById('btn'); // 注册事件 btn.onclick = function () { alert('点到我了'); } </script> </body> </html>
例子1:点击按钮切换图片
<!DOCTYPE> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试</title> </head> <input type="button" value="点我" id="btn"> <br /> <img src="images/a.jpg" id="mv" /> <script> // 获取元素 var btn = document.getElementById('btn'); var mv = document.getElementById('mv'); // 标志位,保证两种照片可以来回切换 var flag = true; // 注册事件 btn.onclick = function () { if (flag) { mv.src = 'images/b.jpg'; flag = false; } else { mv.src = 'images/a.jpg'; flag = true; } } </script> </html>
属性操作
非表单的属性 : 只展示出来给用户看
表单元素:可以和用户进行交互 如 input button
非表单的属性: href, title, alt, id, src, className
而这些属性都是可以修改的
实例:
<!DOCTYPE> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试</title> </head> <a href="http://www.baidu.com" id="link">百度</a> <script> var link = document.getElementById('link'); // 修改链接 link.href = 'http://www.jd.com'; </script> </html>
例子:点击按钮div显示或隐藏
<!DOCTYPE> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试</title> <style> * { margin: 0; padding: 0; } #box { width: 200px; height: 200px; background-color: pink; } .show { display: block; } .hidden { display :none; } </style> </head> <input type="button" value="隐藏" id="btn"> <br /> <div class="show" id="box"></div> <script> // 获取元素 var btn = document.getElementById('btn'); // 标志位,控制来回切换 var isShow = true; // 注册事件 btn.onclick = function () { // 获取元素 var box = document.getElementById('box'); // div是否显示 if (isShow) { // 修改元素的类名 // className为什么DOM对象的对应标签的class属性的名字叫做className, // 因为class在javascript中是关键字,关键字不可以作为变量或者属性的名字。 box.className = 'hidden'; // 修改按键的属性。 // this的几种情况: // 1,在函数内----指向window // 2,在构造函数中----指向的是构造函数创建的对象 // 3,在方法中----指向的是这个方法所属的对象 // 4,在事件处理函数中----谁调用该事件,this就指向谁 this.value = '显示'; isShow = false; } else { box.className = 'show'; this.value = '隐藏'; isShow = true; } } </script> </html>
取消a标签的默认行为:不会跳转到href指定的页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <a href="http://www.baidu.com" id="link">百度</a> <script> // 获取元素 var link = document.getElementById('link'); // 注册事件 link.onclick = function () { alert('hello world'); // 重要的一步:取消a标签的默认行为 return false; } </script> </body> </html>
job:相册(来回切换照片)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> /** { padding: 0; margin: 0; }*/ /* 清除浮动*/ .clearfix:after { content: 0; display: block; height: 0; visibility: hidden; clear: both; } .clearfix { *zoom: 1; } /*a标签*/ #imagegallery a { display: inline-block; margin: 0 20px 20px 0; padding: 0; text-decoration: none; } #imagegallery a img { border: 0; } </style> </head> <body> <h2> 美女画廊 </h2> <div id="imagegallery" class="clearfix"> <a href="images/1.jpg" title="美女A"> <img src="images/1-small.jpg" width="100px" alt="美女1"> </a> <a href="images/2.jpg" title="美女B"> <img src="images/2-small.jpg" width="100px" alt="美女2"> </a> <a href="images/3.jpg" title="美女C"> <img src="images/3-small.jpg" width="100px" alt="美女3"> </a> <a href="images/4.jpg" title="美女D"> <img src="images/4-small.jpg" width="100px" alt="美女4"> </a> </div> <img id="image" src="images/placeholder.png" width="450px" /> <p id="des">请选择一张照片</p> <script> // 获取所有的a元素 var imagegallery = document.getElementById('imagegallery'); var links = imagegallery.getElementsByTagName('a'); // 给所有的a元素添加事件 for (var i = 0; i < links.length; i++) { // 所有的a标签对应的元素 var link = links[i]; link.onclick = function () { // 获取占位图 var image = document.getElementById('image'); // 切换图片 image.src = this.href; // 获取p元素 var des = document.getElementById('des'); // 设置p标签的内容 des.innerText = this.title; //取消a标签的默认行为 return false; } } </script> </body> </html>
打印对象:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="box"> hello world <span>Hi</span> </div> <script> // 获取元素 var box = document.getElementById('box'); // 打印这个对象 console.dir(box); // div#box // 获取内部文本 console.log(box.innerText); // hello world Hi // 获取内部文本和标签(有标签时) console.log(box.innerHTML); // </script> </body> </html>
innerHTML:获取内部文本和标签(如果有标签)
innerText / textContent:获取内部文本(不包含标签),有浏览器兼容问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div id="box">hello</div> <script> // innerText的浏览器兼容处理 function getInnerText(element) { // 判断是否有innerText属性 if (typeof element.innerText === 'string') { // 浏览器支持innerText则使用 return element.innerText; } else { // 浏览器不支持innerText,则使用textContent return element.textContent; } } // 获取元素 var box = document.getElementById('box'); // 传入函数 alert(getInnerText(box)) </script> </body> </html>
设置内容时该什么方法:
innerText / textContent // 内容不带标签
innerHTML // 内容带标签
当设置不含标签的内容时候,应该使用innerText,它的效率高!
表单元素属性:
value // 用于大部分表单元素的内容获取(option 除外)
type // 可以获取input标签的类型(输入框或复选框等)
checkeed // 复选框选中属性。(返回的值是布尔类型)
selected // 下拉菜单选中属性。(返回的值是布尔类型)
文本域的相关属性设置:
disabled // 禁用属性。让用户无法输入内容。(返回的值是布尔类型)
readOnly // 只读不能修改
.value // 可以修改文本域里面的内容---建议使用这种
.innerText // 可以修改文本域里面的内容
job:点击按钮禁用文本框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <input type="button" value="点我" id="btn"> <input type="button" value="写入内容" id="btn1"> <br /> <input type="text" id="text" value="123"> <script> // 获取元素 var btn = document.getElementById('btn'); // 注册事件 btn.onclick = function () { var text = document.getElementById('text'); // 禁止属性。只是让用户无法输入。但还是可以通过代码写入内容 text.disabled = true; } // 获取元素 var btn1 = document.getElementById('btn1'); // 注册事件 btn1.onclick = function () { // 获取元素 var text = document.getElementById('text'); // 写入内容。 text.value = 'hello world'; } </script> </body> </html>
job:给文本框赋值,获取文本框的值---两种实现方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> input { display: block; margin: 10px 10px; } </style> </head> <body> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="button" value="获取文本框的值" id="btn"> <script> // 给文本框赋值,获取文本框的值 // 1,先给文本框赋值 // // 获取所有input元素 var inputs = document.getElementsByTagName('input'); // 拿到每一个input元素 for (var i = 0; i < inputs.length; i++) { var input = inputs[i]; // 判断是不是文本框 if (input.type === 'text') { input.value = i; } } // 2,获取文本框的值 // // 获取btn元素 var btn = document.getElementById('btn'); // 注册事件 btn.onclick = function () { // 存储全部文本框的值 var array = []; // 获取所有文本框的值 for (var i = 0; i < inputs.length; i++) { // 判断是不是文本框 var input = inputs[i]; if (input.type === 'text') { array.push(input.value); } } // 拼接成0|1|2|3|4|5|6|7|8|9 var s = array.join('|'); console.log(s); } </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> input { display: block; margin: 10px 0; } </style> </head> <body> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="text" name="" id=""> <input type="button" value="获取所有属性的值" id="btn"> <script> // 1,给所有文本框赋值 // // 获取所有input元素 var inputs = document.getElementsByTagName('input'); // 遍历所有input元素 for (var i = 0; i < inputs.length; i++) { var input = inputs[i]; // 判断是不是文本框 if (input.type === 'text') { // 给文本框赋值 input.value = i; } } // 2,获取所有文本框中的值,并拼接 // 获取按钮元素 var btn = document.getElementById('btn'); // 注册事件 btn.onclick = function () { // 存储所有文本框的值 var str = ''; // 遍历所有input元素 for (var i = 0; i < inputs.length; i++) { var input = inputs[i]; // 判断是不是文本框 if (input.type === 'text') { // 拼接字符串 str += input.value + '|'; } } var s = str.substr(0, str.length - 1); console.log(s); } </script> </body> </html>
自定义属性 :
setAttribute('属性名', '值') // 设置自定义属性
getAttribute('属性名') // 获取自定义属性的值
removeAttribute('属性名') // 移除自定义属性或者自带属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div>111111</div> <div>222222</div> <div>333333</div> <div>444444</div> <div>555555</div> <input type="button" value="移除自定义属性" id="btn"/> <script> var Objs = document.getElementsByTagName('div'); // 遍历 for (var i = 0; i < Objs.length; i++) { // 设置自定义属性和值 Objs[i].setAttribute('num', (i + 1)); // 根据标签名获取元素,为元素注册点击事件,添加事件处理函数 Objs[i].onclick = function () { // 获取自定义属性的值 alert(this.getAttribute('num')); }; } // 根据id获取元素,注册点击事件,添加事件处理函数 document.getElementById('btn').onclick = function () { // 遍历 for (var i = 0; i < Objs.length; i++) { // 移除自定义属性 Objs[i].removeAttribute('num'); } }; </script> </body> </html>
节点:node
介绍:
1,页面上的所有内容都是节点:标签是节点,属性是节点,文本也是节点(文本有文字空格换行)
2,获取标签元素非常方便
节点的属性:
节点的属性:(可以使用标签(元素).出来,可以使用属性节点.出来,文本节点.点出来)
节点的类型 nodeType // 1 标签节点,2 属性节点,3 文本节点
节点的名字 nodeName // 大写标签名 标签节点,小写属性名 属性节点,#text 文本节点
节点的值 nodeValue // Null 标签节点,属性名 属性节点,文本的内容
获取节点:
1,只有标签才能作为父节点
2, .parentNode,.parentElement支持所有浏览器(谷歌,火狐,IE8)
3,.childNodes,children也支持所有浏览器(谷歌,火狐,IE8)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>kay</title> </head> <body> <input type="button" value="获取" id="btn"/> <ul id="uls"> <li>kay1</li> <li>kay2</li> <li>kay3</li> <li id="middle">kay4</li> <li>kay5</li> <li>kay6</li> <li>kay7</li> </ul> <script> // 根据id获取按钮,注册点击时间,添加事件处理函数 document.getElementById('btn').onclick = function () { // 根据id获取元素li var middle = document.getElementById('middle'); // 获取父节点 console.log(middle.parentNode); // 获取到整个ul // 获取父元素 console.log(middle.parentElement); // 获取到也是整个ul // 获取前一个兄弟元素 console.log(middle.previousElementSibling); // 获取到kay3 // 获取前一个兄弟节点 console.log(middle.previousSibling); // 返回#text(就是距离前一个元素中间的那段换行) } </script> </body> </html>
//获取父节点 parentNode //获取父元素 parentElement // 获取子节点 childNodes //获取子元素 children //获取第一个子节点 firstChild // 获取第一个子元素 firstElementChild //获取最后一个子节点 lastChild //获取最后一个子元素 lastElementChild //获取前一个节点 previousSibling //获取前一个元素 previousElementSibling //获取后一个节点 nextSibling //获取后一个元素 nextElementSibling
浏览器兼容问题:
1,在IE8获取子节点和兄弟节点被变成获取子元素和兄弟元素
2,在IE8获取父节点和父元素可以正常获取
//总结:凡是获取节点的代码在谷歌和火狐得到的都是 相关的节点
//凡是获取元素的代码在谷歌和火狐得到的都是 相关的元素
//从子节点和兄弟节点开始,凡是获取节点的代码在IE8中得到的是元素,获取元素的相关代码,在IE8中得到的是undefined----元素的代码,iE中不支持
// 获取任意一个父级元素的第一个子元素 function getFirstElementChild(element) { // 判断浏览器是否支持 if (typeof element.firstElementChild !== 'undefined') { // 返回第一个子元素 return element.firstElementChild; } else { // node=第一个字节点 var node = element.firstChild; // node.nodeType !== 1(不是标签) while (node && node.nodeType !== 1) { // // node = 后一个字节点 node = node.nextSibling; } return node; } } // 获取任意一个父级元素的最后一个子元素 function getLastElementChild(element) { // if (typeof element.lastElementChild !== 'undefined') { return element.lastElementChild; } else { // node=最后一个子节点 var node = element.lastChild; // node.nodeType !== 1(不是标签) while (node && node.nodeType !== 1) { // node = 前一个字节点 node = node.previousSibling; } // 返回节点 return node; } }
创建元素:元素创建的三种方式:
1,document.write('标签的代码及内容')
// 缺陷:如果在页面加载完毕后,通过这种方式创建元素,会把页面的所有内容都清除(只剩下这个创建的元素)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>kay</title> </head> <body> <input type="button" value="获取" id="btn"/> <ul id="uls"> <li>kay1</li> <li>kay2</li> <li>kay3</li> <li id="middle">kay4</li> <li>kay5</li> <li>kay6</li> <li>kay7</li> </ul> <script> // 根据id获取按钮,注册点击时间,添加事件处理函数 document.getElementById('btn').onclick = function () { document.write('<p>哈哈页面消失了吧</p>'); } </script> </body> </html>
2,对象.innerHTML='标签及代码'
// 在谁里面创建就应该是(谁.innerHTML)
document.getElementById('btn').onclick = function () { var middle = document.getElementById('middle'); middle.innerHTML = '<p>见证奇迹的时刻</p>'; }
3,document.createElement('标签的名字')
// 根据id获取按钮,注册点击时间,添加事件处理函数 document.getElementById('btn').onclick = function () { // 创建p元素 var p = document.createElement('p'); // 设置p元素中间内容 p.innerText = '见证奇迹'; // 把创建的子元素,追加到父元素里面 document.getElementById('middle').appendChild(p); }
元素相关操作:
.appendChile(newChild) // 追加子元素
.insertBefore (newChild,refChild) // 在某元素之前插入新元素。.insertAfter在某元素之后插入新元素
.replaceChild (newChild,refChild) // 替换子元素
.removeChild(oldChild) // 移除子元素
job:
// 第一种实现方式 my$('btn').onclick = function () { // 如果这个按钮存在 if (my$('btn1')) { // 移除这个按钮 my$('dv').removeChild(my$('btn1')); } // 创建按钮 var input = document.createElement('input') input.type = 'button'; input.value = '按钮'; input.id = 'btn1'; // 追加 my$('dv').appendChild(input); }; //--------------------- // 第二种实现方式 my$('btn').onclick = function () { // 判断这个按钮是否存在 if (!my$('btn1')) { // 按钮不存在 var obj = document.createElement('input'); obj.type = 'button'; obj.value = '按钮'; obj.id = 'btn1'; my$('dv').appendChild(obj); } }
事件2
绑定事件的三种方式:
addEventListener和attachEvent可以绑定多个相同事件!
a,.on事件名=事件处理函数 // 谷歌,火狐,IE8都支持
缺点:不能绑定多个相同事件,假如绑定多个的话最终只有一个。
b,.addEventListener(type,listener,useCapture) //只有谷歌和火狐支持
//参数1:事件的类型---事件的名字,没有on
//参数2:事件处理函数---函数(命名函数,匿名函数)
//参数3:布尔类型,目前就写false
// 不支持IE8 document.getElementById('btn').addEventListener('click', function () { console.log('hello'); }, false);
c,.attachEvent(type,listener) //只有IE8支持
//参数1:事件类型---事件名字,有on
//参数2:事件处理函数---函数(命名函数,匿名函数)
// 只支持IE8 document.getElementById('btn').attachEvent('onclick', function () { console.log('hello'); });
解绑事件:对应以上的三种解绑方法
注意:用什么方式绑定事件,就应该用对应的方式解绑事件
a,对象.on事件名=null
// 绑定 document.getElementById('btn1').onclick = function () { console.log('kay'); } document.getElementById('btn2').onclick = function () { // 解绑 document.getElementById('btn1').onclick = null; }
b,对象.removeEventListener('不带on的事件名', 函数名, false)
// 命名函数 function f1() { console.log('hello') } // 绑定 document.getElementById('btn1').addEventListener('click', f1, false) document.getElementById('btn2').onclick = function () { // 解绑 document.getElementById('btn1').removeEventListener('click', f1, false); };
c,对象.detachEvent(带on的事件名, 函数名)
// 命名函数 function f2() { console.log('kay'); } // 绑定 document.getElementById('btn1').attachEvent('onclick', f2); // document.getElementById('btn2').onclick = function () { // 解绑 document.getElementById('btn1').detachEvent('onclick', f2); };
解决浏览器兼容问题:
// 为任意元素绑定任意事件 function addEventListener(element, type, fn) { // 如果浏览器有这个方法,谷歌,火狐 if (element.addEventListener) { element.addEventListener('click', fn, false); // IE8的 } else if (element.attachEvent) { element.attachEvent('on' + type, fn); } else { element['on' + type] = null; } } // 两个命名函数 function f1() { console.log('kay1'); } function f2() { console.log('kay2'); } var btn1 = document.getElementById('btn1'); // 绑定两个点击事件 addEventListener(btn1, 'click', f1); addEventListener(btn1, 'click', f2);
// 为任意元素解绑事件 function removeEventListener(element, type, fnName) { // 如果浏览器有这个方法 if (element.removeEventListener) { element.removeEventListener(type, fnName, false); } else if (element.detachEvent) { element.detachEvent('on' + type, fnName); } else { element['on' + type] = null; } } // 解绑事件 removeEventListener(btn1, 'click', f2);
事件冒泡:
事件冒泡解释:
多个元素嵌套,有层次关系,这些元素都注册了相同的事件,
如果里面的元素的事件触发了,
外面的元素的该事件自动的触发了.
<div id="dv1"> <div id="dv2"> <div id="dv3"></div> </div> </div> <script> // 最外层 document.getElementById('dv1').onclick = function () { console.log('外层===' + this.id); }; // 第二层 document.getElementById('dv2').onclick = function () { console.log('第二层===' + this.id); }; // 最里层 document.getElementById('dv3').onclick = function () { console.log('最里层===' + this.id); }; </script>
阻止事件冒泡:
1,window.event.cancelBubble = true; // 谷歌和IE8支持,火狐不支持
2,e.stopPropagation(); // 谷歌和火狐支持,IE8不支持
这种使用的是事件处理函数的参数对象.方法()
document.getElementById('dv1').onclick = function () { console.log('外层===' + this.id); }; document.getElementById('dv2').onclick = function () { console.log('第二层===' + this.id); // 阻止事件冒泡第一种 // window.event.cancelBubble = true; }; // function (参数对象) document.getElementById('dv3').onclick = function (e) { console.log('最里层===' + this.id); // 阻止事件冒泡第二种, e.stopPropagation(); };
事件分三个阶段:
1捕获阶段 --- 从外到里
2目标阶段
3冒泡阶段 --- 从里到外
e.eventPhase // 调用事件处理程序的阶段
// 命名函数 function fn(e) { var current = ''; // 判断事件处于哪个阶段 switch (e.eventPhase) { case 1: current = '捕获阶段'; break; case 2: current = '目标阶段'; break; case 3: current = '冒泡阶段'; break; } console.log(this.id + '===' + current); }
// var dv1 = document.getElementById('dv1'); var dv2 = document.getElementById('dv2'); var dv3 = document.getElementById('dv3'); var objs = [dv1, dv2, dv3]; // 为数组中每个元素注册点击事件 objs.forEach(function(item) { // true捕获阶段,false冒泡阶段 item.addEventListener('click', fn, false) });
被点击的div3就是:目标阶段
job:为同一元素绑定多个不同事件,并使用同一个事件处理函数
// 命名函数 function fn(e) { switch(e.type) { case 'click': alert('kay,hellow'); break; case 'mouseover': this.style.backgroundColor = 'hotpink'; break; case 'mouseout': this.style.backgroundColor = 'green'; break; } } var btn = document.getElementById('btn'); // 为按钮绑定:点击,鼠标进入,鼠标离开事件 btn.addEventListener('click', fn, false); btn.addEventListener('mouseover', fn, false); btn.addEventListener('mouseout', fn, false);