10-DOM(下)

1:DOM节点简介

根据 DOM规定,HTML 文档中的每个成分都是一个节点。
DOM 是这样规定的:
    整个文档是一个文档节点。
    每个 HTML 标签是一个元素节点。
    包含在 HTML 元素中的文本是文本节点。
    每一个 HTML 属性是一个属性节点。
注释属于注释节点。

2:如何获取DOM节点

(1)旧的获取节点引用方式。
getElementById()
getElementsByTagName()
getElementsByName()
缺点:浪费内存,逻辑性不强。
(2通过节点的关系属性来获得节点的引用。
对象.parentNode  获得父节点的引用。
<div id="parent">
    <div id="center"></div>
</div>
<script>
    var center = document.getElementById('center');
    var parent = center.parentNode;  //<div id="parent">....</div>
</script>
对象.childNodes  获得子节点的集合(子节点们),包括空白节点。IE7/8不包含空文本节点,但IE7包含首个注释节点(前面没有元素节点),IE8包含所有的注释节点。
<div id="parent">
    <div id="up"></div>
    <div id="center""></div>
    <div id="down"></div>
</div>
<script>
    var center = document.getElementById('center');
    var parent = center.parentNode;
    var children = parent.childNodes;
    console.log(children);   //NodeList(7) [text, div#up,text, div#center, text, div#down, text]
</script>

对象.children    获得子节点的集合,不包含空白节点。但IE7包含首个注释节点(前面没有元素节点),IE8包含所有的注释节点。

<div id="parent">
    <div id="up"></div>
    <div id="center""></div>
    <div id="down"></div>
</div>
<script>
    var center = document.getElementById('center');
    var parent = center.parentNode;
    var children = parent.children;
    console.log(children); //HTMLCollection(3) [div#up, div#center, div#down,length:3]
</script>
对象.firstChild   获得第一个子节点。(IE7/8非空白节点,可能是注释节点)
<div id="parent">
    <div id="up"></div>
    <div id="center""></div>
    <div id="down"></div>
</div>

<script>
    var center = document.getElementById('center');
    var parent = center.parentNode;
    var firstChild = parent.firstChild;
    console.log(firstChild);  //#text
</script>
注:在IE下是第一个非空白元素节点
对象.firstElementChild  获得第一个非空白的子节点。(IE7/8不支持)
<div id="parent">
    <div id="up"></div>
    <div id="center""></div>
    <div id="down"></div>
</div>

<script>
    var center = document.getElementById('center');
    var parent = center.parentNode;
    var firstChild = parent.firstElementChild;
    console.dir(firstChild);  //div#up
</script>
注:在低版本ie下不支持,是undefined
兼容各个浏览器写法:
var firstChild = parent.firstElementChild || parent.firstChild;
对象.lastChild   获得最后一个子节点。(IE7最后一个元素节点,IE8最后一个非空白节点,可能是注释节点)
<div id="parent">
    <div id="up"></div>
    <div id="center""></div>
    <div id="down"></div>
</div>
<script>
    var center = document.getElementById('center');
    var parent = center.parentNode;
    var lastChild = parent.lastChild;
    console.dir(lastChild);  //#text
</script>
注:在IE下就是最后一个非空白元素节点
对象.lastElementChild    获得最后一个非空白的子节点。(IE7/8不支持)
<div id="parent">
    <div id="up"></div>
    <div id="center""></div>
    <div id="down"></div>
</div>
<script>
    var center = document.getElementById('center');
    var parent = center.parentNode;
    var lastChild = parent.lastElementChild;
    console.dir(lasttChild);  //div#down
</script>
注:在低版本ie下不支持,是undefined
兼容各个浏览器写法:
var lastChild = parent.lastElementChild || parent.lastChild;

对象.nextSibling 获得下个兄弟节点的引用。(包括空白节点和注释。IE7/8包括注释节点,不包括空白节点。)
var nextSibling = center.nextSibling;
console.dir(nextSibling );  //#text
对象.nextElementSibling 获得下个兄弟节点的引用。 (IE7/8不支持)
var nextSibling = center.nextElementSibling;
兼容写法:
 
var nextSibling = center.nextElementSibling || center.nextSibling;
对象.previousSibling 获得上个兄弟节点的引用。(包括空白节点和注释。 IE7/8包括注释节点,不包括空白节点。)
var previousSibling  = center.previousSibling;
console.dir(nextSibling ); 

对象.previousElementSibling 获得上个兄弟节点的引用。(IE7/8不支持)
var prevSibling = center.previousElementSibling;
console.dir(prevSibling );  //div#up     
       
兼容写法:
var prevSibling = center.previousElementSibling || center.previousSibling;

缺点:兼容性不好。

3:节点其它属性

ownerDocument: 获取该节点的文档根节点,相当于 document。
<div id="parent">
    <div id="up"></div>
    <div id="center""></div>
    <div id="down"></div>
</div>
<script>
    var center = document.getElementById('center');
    console.log(center.ownerDocument); //#document
</script>
attributes: 获取当前元素节点的所有属性节点集合(IE7下不正常)。
<div id="parent">
    <div id="up"></div>
    <div id="center" class="aaa bbb ccc" age="18" title="这是标题"></div>
    <div id="down"></div>
</div>
<script>
    var center = document.getElementById('center');
    console.log(center.attributes); //NamedNodeMap {0: id, 1: class, 2: age, 3: title, id: id, class:
class, age: age, title: title, length: 4}
</script>
tagName: 获取元素节点的标签名。
console.log(center.tagName);   // DIV
id :元素节点的ID名称。
console.log(center.id);  //center
title: 元素节点的title属性值(鼠标悬停时提示)
console.log(center.title);  //这是标题
className: 元素节点的类名(不可以使用class)
console.log(center.className);   //aaa bbb ccc

4:节点信息(属性)

                             节点类型         节点名字       节点值
            nodeType(数值)       nodeName    nodeValue
元素节点         1               标签名          null  
属性节点         2               属性名         属性值
文本节点         3               #text          文本
注释节点         8               #comment     注释的文字
文档节点         9               #document      null
Eg: 元素节点:
console.log(center.nodeName);   //DIV
console.log(center.nodeType);   // 1
console.log(center.nodeValue);  //null
属于节点:
var attr = center.attributes[0];
console.log(attr.nodeName);   // id
console.log(attr.nodeType);   //2
console.log(attr.nodeValue);  // center
文本节点:
var text = document.createTextNode('这是一段文本');
console.log(text.nodeType);    //3
console.log(text.nodeName);  //#text
console.log(text.nodeValue);  //这是一段文本
注: 注释节点一样
// 扩展知识(添加class名)             
 // 判断class名(因为有的话在加会重复)
function hasClass(obj, className) {
    var allClass = obj.className;
    if(allClass.indexOf(className) !== -1) {
        return true;
    } else {
        return false;
    }
}
// 添加class名
function addClass(obj, className) {
    if(!hasClass(obj, className)) {
        obj.className = obj.className + ' ' + className;
    }
}
addClass(center, 'ddd');

元素身上的一些属性:

center.classList.add('ccc');
center.classList.remove('ccc');

//查 看有没有
console.log(center.classList.contains('bbb'));  center.classList.replace('bbb', 'ddd');
//toggle有就删除,没有就加
center.classList.toggle('eee');  center.classList.toggle('eee');
console.dir(center);

var oNewP = document.createElement('p');
oNewP.innerHTML = '你好!';
center.after(oNewP);
center.before(oNewP);
center.append(oNewP);
center.remove();
center.replaceWith(oNewP);
1:隔行变色。
<h2 id="title">新闻列表</h2>
<ul id="list">
    <li>这是第1个LI</li>
    <li>这是第2个LI</li>
    <li>这是第3个LI</li>
    <li>这是第4个LI</li>
    <li>这是第5个LI</li>
    <li>这是第6个LI</li>
</ul>
<style>
* {
       margin: 0;
       padding: 0;
}
ul {
       list-style: none;
}
#title {
       padding: 10px 0;
       text-align: center;
}
#list li{
       padding: 0 4px;
       line-height: 30px;
       border-top: 1px dashed #ccc;
}
</style>

<script>
    var list = document.getElementById('list');
    var aLi  = list.children;
    for(var i = 0; i < aLi.length; i++) {
        if(i % 2 === 0) {
            aLi[i].style.background = '#eee';
        }
        aLi[i].onmouseover = function () {
            this.style.background = 'skyblue';
        };
        aLi[i].index = i;
        aLi[i].onmouseout = function () {
            if(this.index % 2 === 0) {
                this.style.background = '#eee';
            } else {
                this.style.background = '#fff';
            }
        };
    }
</script>
2:进度条。
 
<div id="outer">
    <div id="inner">0%</div>
</div>
<style>
* {
    margin: 0;
    padding: 0;
}
#outer {
    margin: 50px auto;
    width: 800px;
    background: #eee;
}
#inner {
    width: 0;
    line-height: 30px;
    text-align: center;
    color: #fff;
    background: blue;
}
</style>
<script>
var outer = document.getElementById('outer');
var inner = document.getElementById('inner');

var timer = setInterval(function () {
    inner.style.width = inner.offsetWidth + 17 + 'px';
    inner.innerHTML = Math.round( inner.offsetWidth / outer.offsetWidth * 100 ) + '%';

    if(inner.offsetWidth >= outer.offsetWidth) {
        clearInterval(timer);
        inner.style.width = outer.offsetWidth + 'px';
        inner.innerHTML = '100%';
    }
}, 100);
</script>

5:创建文档碎片

语法:
var oFragment = document.createDocumentFragment();
经过测试,在ie,firefox下性能明显得以提高。
比如创建10000个li:
<ul id="list"></ul>
<script>
    var oList = document.getElementById('list');
    for(var i = 0; i < 10000; i++) {
        var oLi = document.createElement('li');
        oLi.innerHTML = '这是第' + i + '个LI!';
        oList.appendChild(oLi);
    }
</script>
文档碎片方法:
var oFragement = document.createDocumentFragment();
for(var i = 0; i < 10000; i++) {
    var oLi = document.createElement('li');
    oLi.innerHTML = '这是第' + i + '个LI!';
    oFragement.appendChild(oLi);
}
oList.appendChild(oFragement);

6:节点计算属性

1:offsetParent :获取元素的最近的具有定位属性(absolute或者relative)的父级元素。如果都没有则返回body。(当position:static是没作用)
<div id="parent"  style = “position: relative;”>
    <div id="son">
        <div id="outer">
            <div id="inner"></div>
        </div>
    </div>
</div>
<script>
    var outer = document.getElementById('outer');
    console.log(outer.offsetParent);  //<div id =‘parent>...</div>
</script>
2:offsetLeft: 获取元素相对具有定位属性的父级元素的左侧偏移距离。(子元素的marginLeft + left + 父元素的paddingLeft)
3:offsetTop: 获取元素相对就有定位属性的父级元素的顶部偏移距离。(子元素的marginTop + top + 父元素的paddingTop)
4:scrollLeft/scrollTop: 滚动条最顶端和窗口中可见内容的最顶端之间的距离。
6:clientWidth/clientHeight :元素视窗宽度/高度。
5:offsetWidth/offsetHeight: 元素实际宽度/高度。
6:scrollWidth/scrollHeight: 获取对象的滚动宽度/高度。
<div id="a">
   <div id="b">1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>1<br>3<br>2<br>1<br>3<br>2<br>2<br>1<br>
    </div>
</div>
<style>
#a {
    width: 100px;
    height: 100px;
    border: 1px solid #ccc;
    overflow: auto;
}
#b {
    height: 300px;
}
</style>
<script>
    var a = document.getElementById('a');
    a.onscroll = function () {
        console.log(a.scrollTop);
        console.log(a.clientWidth);
        console.log(a.clientHeight);
        console.log(a.offsetWidth);
        console.log(a.offsetHeight);
        console.log(a.scrollWidth);
        console.log(a.scrollHeight);
    };
</script>

7:获取FORM表单

一:通过直接定位的方式来获取
document.getElementById();
document.getElementsByName();
document.getElementsByTagName();
二:通过集合的方式来获取引用
<button id="submit-form">提交FORM表单</button>
<form name="login">
              <div>账号:<input type="text" name="account" value="你好"></div>
              <div>密码:<input type="password" name="password"></div>
              <div>
                     性别:<input type="radio" name="sex" value="1">男<input type="radio" name="sex" value="0">女<input type="radio" name="sex" value="-1">保密
              </div>
              <div>爱好:<input type="checkbox" name="hobby" value="basketball">篮球<input type="checkbox" name="hobby" value="football">足球<input type="checkbox" name="hobby" value="pingpang">乒乓球<input type="checkbox" name="hobby" value="baseball">棒球<input type="checkbox" name="hobby" value="volleyball">排球</div>
              <div>地区:<select name="area">
                     <option value="0">请选择</option>
                     <optgroup>
                            <option value="4">西安市</option>
                            <option value="7" selected>渭南市</option>
                            <option value="8">宝鸡市</option>
                            <option value="9">咸阳市</option>
                     </optgroup>
                     <optgroup>
                            <option value="4">西安市</option>
                            <option value="7" selected>渭南市</option>
                            <option value="8">宝鸡市</option>
                            <option value="9">咸阳市</option>
                     </optgroup>
              </select></div>
              <input type="submit" value="提交" name="btn">
       </form>
1.通过下标的形式
document.forms[下标]
console.log( document.forms[0] );  //<form name="login">...</form>
2.通过name形式
document.forms["name"]       document.forms.name
console.log( document.forms['login'] );   //<form name="login">...</form>
三:通过name直接获取(只适用于表单)
document.name
console.log(document.login);  //<form name="login">...</form>

8:获取FORM表单元素

一:通过直接定位的方式来获取
document.getElementById();
document.getElementsByName();
document.getElementsByTagName();
二:通过集合来获取
表单对象.elements      // 获得表单里面所有元素的集合
表单对象.elements[下标]
var login = document.login;
console.log(login.elements[1]);   //<input type="password" name="password">
表单对象.elements["name"]
var login = document.login;
console.log(login.elements['password']);  //<input type="password" name="password">
表单对象.elements.name
三:直接通过name的形式
表单对象.name          // name指的是元素的name
var login = document.login;
console.log(login.account);  //<input type="text" name="account" value="你好">

9:表单元素共同的属性和方法

一:获取表单元素的值
表单元素对象.value    // 获取或是设置值
var login = document.login;
console.log(document.login.account.value); //你好
document.login.account.value = '早上好';
console.log(document.login.account.value);  //早上好
二:属性
disabled   // 获取或设置表单控件是否禁用 true false
var login = document.login;
console.log(document.login.password.disabled); //false
document.login.password.disabled = true;
console.log(document.login.password.disabled); //true
form        // 指向包含本元素的表单的引用。(通过表单中元素找到相应的表单)
var login = document.login;
console.log(document.login.password.form);  ///<form name="login">...</form>
三:方法   表单元素是否获得焦点
blur()   // 失去焦点
focus()  // 获得焦点
var login = document.login;
document.login.password.focus();
document.login.password.blur();

10:操作FORM表单元素

document.login.btn.onclick = function () {
              console.log(document.login.sex.value);
              document.login.sex.value = '-1';
              console.log(document.login.sex);
              for(var i = 0; i < document.login.sex.length; i++) {
                     var oInput = document.login.sex[i];
                     console.log(oInput.checked);
              }
              console.log(document.login.hobby);
              var hobbies = [];
              for(var i = 0; i < document.login.hobby.length; i++) {
                     var hobby = document.login.hobby[i];
                     if(hobby.checked == true) {
                       hobbies.push(hobby.value);
                     }
              }
              console.log(hobbies);
              console.log(document.login.area.value);
              document.login.area.value = 4;
              console.log(document.login.area.selectedIndex);
              document.login.area.selectedIndex = 3;
              var options = document.login.area.children;
              for(var i = 0; i < options.length; i++) {
              console.log(options[i].selected);
              }
       };
一:文本域
     value属性: 设置或者获取值。
二:单选按钮
    checked属性: 返回或者设置单选的选中状态。true 选中,false 未选中。
    value属性:获取选中的值,必须先判断单选按钮是否被选中。
三:多选按钮
     checked属性: 返回或者设置单选的选中状态。true 选中,false 未选中。
     value属性: 获取选中的值,必须先判断选中状态。
四:下拉框
     selected属性: 给option设置或返回下拉框的选中状态。true 选中,false 未选中。
    selectedIndex属性: 设置或返回下拉框被选中的索引号。
五:文本区域
    value属性: 设置或者获取值。
六:验证表单
 1:事件        
onsubmit  当表单提交的时候触发的事件。
document.login.onsubmit = function () {
    console.log(1);
    return false;
}
onblur    失去焦点。
onfocus   获得焦点
document.login.account.onfocus = function () {
       this.value = '';
}
onchange  下拉框改变值的时候。
document.login.area.onchange = function () {
    console.log(this.value);
}
2:return false;  // 阻止事件的默认行为(适用于所有事件)。
七:提交方法
表单对象.submit();
document.getElementById('submit-form').onclick = function () {
                   document.login.submit();
            };

应用:

2:简易年历。
<table id="calendar" border="1">
    <tr>
        <td>1月</td>
        <td>2月</td>
        <td>3月</td>
        <td>4月</td>
    </tr>
    <tr>
        <td>5月</td>
        <td>6月</td>
        <td>7月</td>
        <td>8月</td>
    </tr>
    <tr>
        <td>9月</td>
        <td>10月</td>
        <td>11月</td>
        <td>12月</td>
    </tr>
</table>
<div id="show"></div>
<style>
* {
    margin: 0;
    padding: 0;
}
#calendar {
    margin: 50px auto 0;
    width: 600px;
    border-collapse: collapse;
    border-color: pink;
    line-height: 40px;
    text-align: center;
}
#show {
    margin: 0 auto;
    width: 600px;
    padding: 40px 0;
    border: 1px solid #ccc;
    border-top: none;
    text-align: center;
}
.active {
    color: #fff;
    background: skyblue;
}
</style>

<script>
    var poetry = [
        '爆竹声中一岁除,春风送暖入屠苏!',
        '不知细叶谁裁出,二月春风似剪刀!',
        '故人西辞黄鹤楼,烟花三月下扬州!',
        '人间四月芳菲尽,山寺桃花始盛开!',
        '五月天山雪,无花只有寒!',
        '毕竟西湖六月中,风光不与四时同!',
        '七月七日长生殿,夜半无人私语时!',
        '八月秋高风怒号,卷我屋上三重茅!',
        '可怜九月初三夜,露似真珠月似弓!',
        '庭中栽得红荆树,十月花开不待春!',
        '夜阑卧听风吹雨,铁马冰河入梦来!',
        '忽如一夜春风来,千树万树梨花开!'
    ];
    var show = document.getElementById('show');
    var tds = document.getElementsByTagName('td');
    // 页面初始化
    var date = new Date();
    var month = date.getMonth();
    show.innerHTML = poetry[month];            
    // 初始化class
    tds[month].className = 'active';
    for(var i = 0; i < tds.length; i++) {
        tds[i].index = i;
        tds[i].onclick = function () {
            show.innerHTML = poetry[this.index];
            // 重置class
            for(var j = 0; j < tds.length; j++) {
                tds[j].className = '';
            }
            this.className = 'active';
        }
    }
</script>

3:自动登录勾选。

综合应用:

1:点击按钮换图片。
2:tab切换案例。
扩展案例 :QQ延迟提示框。

周六作业:

1:苹果菜单。
2:扩展案例:密码强度。
                           
  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值