JS核心知识点:DOM\BOM\EVENT
1.DOM(Document Object Model) :文档对象模型
2. DOM节点:页面中最基本的组成部分
3. childNodes:获取某个节点下所有的子节点
- 在标准及ie9以上 : 会获取空文本节点。
- 在ie6/7/8 : 没有空文本节点。
<script type="text/javascript">
window.onload=function ()
{
t=document.body.childNodes[0].nodeType;
alert(t)// 3 文本节点
m=document.body.childNodes[1].nodeType;
alert(m)// 1 元素节点
}
</script>
</head>
<body>
文本文字
<Span>123455</Span>
</body>
</html>
4. nodeType:查看某个节点的类型
- 1 代表 元素节点
- 2 代表 属性节点
- 3 代表 文本节点
- 8 代表 注释节点
- 9 代表 文档节点
<script type="text/javascript">
window.onload=function ()
{
var oUl=document.getElementById('ul1');//选出ul
for(var i=0;i<oUl.childNodes.length;i++){
oUl.childNodes[i].style.background='red';//让所有的子节点变红色 火狐下没有变色
}
}
</script>
<ul id="ul1">
<li></li>
<li></li>
<li></li>
</ul>
5. nodeName:查看某个节点的标签名
6. children:获取某个节点下所有的子节点
a. 和childNodes的区别是,children只会获取到元素节点
b. children非标准属性,childNodes是标准属性
7. parentNode:获取元素的父级
8. offsetParent获取定位元素的父节点
--- 实例:树形菜单收缩与展开
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多级展开菜单</title>
<style>
body,ul{margin: 0;padding: 0;}
li{list-style: none;}
a{text-decoration: none; color: #000; font-size: 18px; height: 24px; line-height: 24px; display: block;}
a:hover{color: red;}
#ul1{margin: 50px;}
ul{position: relative;left: 20px;}
#ul1 ul{display: none;}
</style>
<script>
window.onload = function(){
var oUl1 = document.getElementById('ul1');
var aUl = oUl1.getElementsByTagName('ul');
var aA = oUl1.getElementsByTagName('a');
for(var i=0;i<aA.length;i++){
aA[i].onclick=function(){
var oUl = getNext( this ); //a的下一个兄弟节点,即要展开的下一级
//获取此li下的所有子孙ul(有问题:同级点关不了。)
//获取此li父级ul下
var siblingsUl = this.parentNode.parentNode.getElementsByTagName('ul');
if( oUl ){
if( oUl.style.display == 'block' ){
oUl.style.display = 'none';
}else{
//如果是隐藏的点击,全关,开当前。。如果是的展开,上次点击已经全关了,再点直接关闭即可
/*for(var i=0; i<aUl.length; i++){
aUl[i].style.display = 'none';
} //问题:二级以下无法展开 */
for(var i=0; i<siblingsUl.length; i++){
siblingsUl[i].style.display = 'none';
}
oUl.style.display = 'block';
}
}
var oSpan = this.getElementsByTagName('span')[0];
var aSpan = this.parentNode.parentNode.getElementsByTagName('span');
if( oSpan.innerHTML == '-' ){
oSpan.innerHTML = '+';
}else{
for(var i=0; i<aSpan.length; i++){
aSpan[i].innerHTML = '+';
}
oSpan.innerHTML = '-';
}
}
}
function getNext( obj ){
if( !obj || !obj.nextSibling ) return null;
return obj.nextSibling.nodeType === 1 ? obj.nextSibling : getNext( obj.nextSibling );
}
}
</script>
</head>
<body>
<ul id="ul1">
<li><a href="javascript:;"><span>+</span>第一级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第二级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第三级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第四级菜单</a>
<ul>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;"><span>+</span>第二级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第三级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第四级菜单</a>
<ul>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第二级菜单</a></li>
<li><a href="javascript:;">第二级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;"><span>+</span>第一级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第二级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第三级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第四级菜单</a>
<ul>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;"><span>+</span>第二级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第三级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第四级菜单</a>
<ul>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第二级菜单</a></li>
<li><a href="javascript:;"<span>+</span>第二级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;"><span>+</span>第一级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第二级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第三级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第四级菜单</a>
<ul>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;"><span>+</span>第二级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第三级菜单</a>
<ul>
<li><a href="javascript:;"><span>+</span>第四级菜单</a>
<ul>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
<li><a href="javascript:;">第五级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
<li><a href="javascript:;">第四级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
<li><a href="javascript:;">第三级菜单</a></li>
</ul>
</li>
<li><a href="javascript:;">第二级菜单</a></li>
<li><a href="javascript:;">第二级菜单</a></li>
</ul>
</li>
</ul>
</body>
</html>
1. 获取第一个或最后一个节点,也可以获取元素上个或下个兄弟节点的属性
- firstChild : 第一个子节点 在标准和ie9下会获取到空白文本节点。
- firstElementChild : 标准下获取第一个子元素节点,ie6/7/8不支持。
- lastChild : 最后一个子节点 在标准和ie9下会获取到空白文本节点。
- lastElementChild : 标准下获取最后一个子元素节点,ie6/7/8不支持。
- nextSibling:下一个兄弟节点 在标准和ie9下会获取到空白文本节点。
- nextElementSibling:标准下获取下一个兄弟节点,ie6/7/8不支持。
- previousSibling:上一个兄弟节点,在标准和ie9下会获取到空白文本节点。
- previousElementSibling:标准下获取上一个兄弟节点,ie6/7/8不支持
--- 实例:封装四个方法 first()、last()、next()、prev();
<script type="text/javascript">
//封装函数
function getPrev( obj ){
if( !obj || !obj.previousSibling ) return null;
//先处理参数为假或者兄弟节点不存在的情况。
return obj.previousSibling.nodeType === 1 ? obj.previousSibling : getPrev( obj.previousSibling );
}
function getNext( obj ){
if( !obj || !obj.nextSibling ) return null;
//先处理参数为假或者兄弟节点不存在的情况。
return obj.nextSibling.nodeType === 1 ? obj.nextSibling : getNext( obj.nextSibling );
}
function getFirst( obj ){
if( !obj || !obj.firstChild ) return null;
return obj.firstChild.nodeType === 1 ? obj.firstChild : getNext( obj.firstChild );
}
function getLast( obj ){
if( !obj || !obj.lastChild ) return null;
return obj.lastChild.nodeType === 1 ? obj.lastChild : getPrev( obj.lastChild );
}
</script>
2. offsetParent:距离当前节点最近的具有定位属性的祖先节点
3. 元素定位后相对offsetParent的距离
a. offsetLeft : 当前节点的左外边框到offsetParent的左内边框之间的距离。
b. offsetTop : 当前节点的上外边框到offsetParent的上内边框之间的距离。
--- 实例:实用的文字提示层
4. 文档宽高:元素在页面所占的空间宽高
a. offsetWidth / offsetHeight:获取元素在页面所占的空间宽高,包含边框
b. clientWidth / clientHeight :获取元素在页面所占的空间宽高,不包含边框
注意:如果元素没有占页面空间,那么这四属性的值都为0
(比如给元素设置了 display: none; 属性)
5. 内容宽高:被内容所撑出来的高度
a. scrollWiddth / scrollHeigt : 获取被内容所撑出来的高度
注意:当获取body的内容宽高时,在chrome下内容宽高没有可视区宽高,
内容宽高就是可视区的宽高。
其他浏览器, 内容的实际宽高
--- 实例:全盘锁定页面,元素不可操作
知识点:DOM中动态创建元素
当使用innerHTML的时候,赋值之前的事件,赋值后会被注销。
1、createElement(’要创建的标签名‘):创建一个DOM节点
语法:document.createElement(’要创建的节点‘)只能从document中去创建新节点;
--- 实例:创建留言板内容
2、父级.appendChild(要添加的元素);从父级的尾部添加一个节点。
--- 实例:留言板插入内容
3、父级.insertBefore(要添加的元素 );从父级的首部添加一个节点。第一个参数:准备插入的节点(内容);第二个参数:插入到哪个节点的前面(目标);
如果父级没有内容,那么会新添加一个元素节点;
在IE下如果第2个参数不存在会报错;在其他标准浏览器下如果第二个参数的节点不存在则会以appendChild的形式进行添加;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>留言板加强,限制条数</title> <script> window.onload = function(){ var oText = document.getElementById('text1'), oBtn = document.getElementById('btn'), oUl = document.getElementById('ul1'), n = 5; //此处可以设置保留条目的数量 oBtn.onclick = function(){ if (!oText.value){ return; } var oLi = document.createElement('li'); oLi.innerHTML = oText.value; if (oUl.children[0]) { oUl.insertBefore(oLi, oUl.children[0]); } else { oUl.appendChild(oLi); } if (oUl.children[n]){ oUl.removeChild(oUl.children[n]); } oText.value = ''; } } </script> </head> <body> <input type="text" id='text1' /><input type="button" value="留言" id="btn" /> <ul id="ul1"></ul> </body> </html>
4、父级.removeChild( 删除谁) ; 从一个节点里面删除某个指定的子节点。
--- 实例:删除留言内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>留言板加强,批量删除</title> <script> window.onload = function(){ var oText = document.getElementById('text1'), oBtn = document.getElementById('btn'), oUl = document.getElementById('ul1'), oDelete = document.getElementById('btn1'), flag = true; oBtn.onclick = function(){ if (!oText.value){ return; } var oLi = document.createElement('li'); oLi.innerHTML = oText.value; if (oUl.children[0]) { oUl.insertBefore(oLi, oUl.children[0]); } else { oUl.appendChild(oLi); } oText.value = ''; for (var i = 0; i < oUl.children.length; i++) { oUl.children[i].onclick = function(){ if (flag) { this.mark = '1'; this.style.background = 'yellow'; flag = !flag; } else { this.mark = ''; this.style.background = ''; flag = !flag; } } }; } oDelete.onclick = function(){ for (var i = 0; i < oUl.children.length; i++) { if(oUl.children[i].mark) { oUl.removeChild(oUl.children[i]); i--; } }; } } </script> </head> <body> <input type="text" id='text1' /><input type="button" value="留言" id="btn" /><input type="button" value="批量删除" id="btn1" /> <ul id="ul1"></ul> </body> </html>
5、父级.replaceChild( ) ;用一个节点替换掉另一个节点里面指定的子节点。
有两个参数:第一个参数是newNode(新的节点);第二个参数是oldNode(想要替换的节点);且当替换元素之后,之前绑定的所有事件都将会被清空;
--- 实例:始终显示一条留言
解决方案:循环一遍后再添加,或者通过createElement创建出来的元素上添加事件。
6、要克隆的元素. cloneNode( ):克隆节点;如果没有参数那么只会克隆这个元素,但不会克隆里面的子元素;
如果参数是 true 那么会克隆所有的元素包含子元素;
如果参数是 false 那么只会克隆当前要克隆的元素(不包含子元素);
被克隆的元素如果包含事件,则事件是无法被克隆的;(克隆->复制)
--- 综合实例:元素上移下移,加上运动形式
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style> ul{ position: relative; } li{ padding: 10px; position: relative; } </style> <script> window.onload = function() { var oUl = document.getElementById('oUl'); var oLi = oUl.children; for(var i=0 ; i<oLi.length ; i++) { oPre = oLi[i].children[1];//上一个 oNext = oLi[i].children[2];//下一个 oPre.onclick = function()//上一个 { //当插入的目标点为空时,默认被插的元素是放在它父级的最后一个上故而当点击第一个的时候会自动跳到最后一个 var prevLi = Prev(this.parentNode); oUl.insertBefore(this.parentNode,prevLi);//把当前节点插入到上一个节点前 } oNext.onclick = function()//下一个 { if(!Next(this.parentNode))//判断 { oUl.insertBefore(this.parentNode,oLi[0]); return; } var nextLi = Next(this.parentNode); oUl.insertBefore(nextLi,this.parentNode);//把下一个节点插入到当前节点前 } } function Prev(obj){ if(!obj || !obj.previousSibling){ return null; } return obj.previousSibling.nodeType==1?obj.previousSibling:Prev(obj.previousSibling);//判断元素节点,如果等于1就是元素节点,故而直接返回previousSibling } function Next(obj){ if(!obj || !obj.nextSibling){ return null; } return obj.nextSibling.nodeType==1?obj.nextSibling:Next(obj.nextSibling); } } </script> </head> <body> <ul id="oUl"> <li> <span>啦啦啦啦 1</span> <input type="button" value="上移" class="pre"> <input type="button" value="下移" class="next"> </li> <li> <span>哈哈哈哈 2</span> <input type="button" value="上移" class="pre"> <input type="button" value="下移" class="next"> </li> <li> <span>嘿嘿额和 3</span> <input type="button" value="上移" class="pre"> <input type="button" value="下移" class="next"> </li> <li> <span>呱呱呱呱 4</span> <input type="button" value="上移" class="pre"> <input type="button" value="下移" class="next"> </li> <li> <span>哥哥哥哥 5</span> <input type="button" value="上移" class="pre"> <input type="button" value="下移" class="next"> </li> </ul> </body> </html>
7、父级.appendChild、父级.insertBefore、父级.replaceChild 如果要添加或者插入或者替换的元素都是该父级下已有的元素,那么该元素都是被 剪切 到目标位置的。
8、动态数组:只要定义一次,再去修改节点时,同样能够重新计算节点的新length。
9、在循环中操作DOM,会因为动态数组的原因,改变了操作DOM之后的结果。
10. 操作元素属性的两种方式:中括号([]) 或 点(.)
11. 操作元素属性的第三种方式
a. getAttribute():获取属性,也可以获取自定义在行间的属性
注意:可以获取到src,href,url等的相对地址。
b. setAttribute(): 设置属性
c. removeAttribute:删除属性
注意:在ie低版本下属性名应避开关键字
--- 实例:图片的按需加载方式