JS中级知识点

JS中级课程

(一)DOM元素的具体操作

DOM的概念及节点类型

DOM:全称Document Object Model 文档对象模型
  • 文档HTML页面
  • 文档对象HTML页面里面的元素
  • 文档对象模型: 一套定义,准则为了能够让JS去操作页面中的元素而定义出来的标准
DOM会把文档看做是一棵树,页面中的每一个元素就是树上的节点,同时DOM定义了很多方法,属性来操作这棵树中的每一个元素(节点)---每一个节点称为DOM节点

DOM节点


获取第一级子元素,也就是说孙子节点获取不了
有兼容性问题(空白节点,换行),用了childNodes必须使用nodeType


获取子元素里面的第一个


获取子元素里面的最后一个


1.childNodes

元素.childNodes:只读属性,子节点列表合集
childNodes包含一级子节点,不包含后背孙子及其下面的节点
childNodes的兼容性

  • childNodes包含了文本注释元素类型的节点,并且也包含了非法嵌套的节点
  • 非标准浏览器下面,包含元素类型的节点,IE7以下不包含非法节点
<ul id="ul1">
    <li>111</li>
    <li>111</li>
    <li>111</li>
    <li>111</li>
</ul>

上面是布局,下面是代码

var ul = document.getElementById("ul1");
window.alert(ul.childNodes.length);  
//标准浏览器弹出来9;IE67弹出来4因为标准浏览器换行也属于文本节点
for(var i=0;i<ul.childNodes.length;i++)
{
  ul.childNodes[i].style["background"] = "red";
  //这里标准浏览器下面会报错误,因为有文本节点
}
//解决方案
for(var i=0;i<ul.childNodes.length;i++)
{
      if(ul.childNodes[i].nodeType==1)
      {
       ul.childNodes[i].style["background"] = "red";
      }
}
这样就去掉了文本节点

PS:childNodes必须和nodeType一起使用,涉及到空白节点的问题:元素节点的nodeType就是1,属性节点就是2,文本节点nodeType就是3,注释节点就是8,document节点就是9

2.children

元素.children 只读子节点的列表合集。她找的只是元素节点。不包括文本节点,注释节点等等

for(var i=0;i<ul.children.length;i++)
{
   ul.children[i].style["background"] = "red";
   //这样不会报错误
}

3.nodeType

元素.nodeType:只读,当前元素的节点类型
nodeName:获取的就是节点的名称

4.attributes

元素.attributes:只读属性
属性节点

<div id="div1"></div>
元素.attributes[0].nodeType 就是数字2 找的就是id属性
元素.attributes[0].nodeValue 就是属性值 div1
元素.attributes[0].nodeName 就是节点属性名 id
注释节点要是获取值就是 xxx.childNodes[0].nodeValue 获取的就是注释里面的文字

子节点和兄弟节点

firstChild

她会包含文本节点和注释节点。在IE678下只包含元素节点,9以上全部包括

firstElementChild,IE678不支持,需要写兼容性

元素.firstElementChild只读属性

var Ofirst = ul.firstElementChild||firstChild;
if(Ofirst){
  Ofirst.style.background = "red";
}else
{
  window.alert("没有节点可以选择")
}

以上这段代码会报错。因为在oUl下面没有子元素节点,因此oUl.firstElementChild会返回为null,null不会传给变量oFirst,所以oFirst等于oUl.firstChild,而在标准浏览器下,oUl.firstChild是存在的,是一个文本节点,因此在下面的判断中,oFirst存在,因此走if语句的第一句,但是oFirst是文本节点,没有style可以设置,因此会报错。因此最好的做法是如下:

Ofirst.children[0].style["background"] = "red";

lastChild,lastElementChild

表示最后一个。同firstChild

nextSibling,previousSibling

元素.nextSibling下一个节点要是元素的是nextElementSibling
元素.previousSibling下一个节点要是元素的是previousSibling

父节点

元素.parentNode

offsetParent

找到当前元素最近的一个有定位的父节点

  • 要是没有定位父级,默认就是body

offsetLeft ,offsetTop

元素.offsetLeft\offsetTop外边框到有定位父级的内边框的距离(找到最近的)
要是没有定位他找的就是距离body

getBoundingClientRect()

结果就是获取到这个元素的所有信息,返回的就是一个对象。然后在left,top之类的。这里特别注意的就是获取的值会根据滚动条变化的

offsetWidth,offsetHeight

  • 元素.style.width :样式宽就是width值带单位
  • clientWidth:样式宽+padding,不带单位
  • offsetWidth:样式宽+padding+border
  • 高度一样

操作元素的属性的多种方式

  • 通过.点的形式 OText.value
  • 通过中括号[]的形式:OText['value']当属姓名用变量表示,用中括号

getAttribute,setAttribute,removeAttribute

  • 元素.getAttribute(属性名称) 获取指定元素指定属性的值
  • 元素.setAttribute(属性名称) 给指定元素指定的属性设置值
  • 元素.removeAttribute(属性名称) 移除指定元素的指定属性

PS:set/get与.的区别

1.用.和中括号没办法操作自定义属性,比如abc="234";getAttribute可以操作自定义属性
2.用.和[]的形式来获取src的时候,获取的是一长串绝对路径,但是在IE8以上以及标准浏览器中,用getAttribute(‘src’)可以获取到相对路径(但是在IE7及以下,获取的src还是绝对路径)

节点创建

document.createElement(标签名)

  • 动态创建
  • 不会直接显示在页面中
  • 前面必须是document,不能是其他的

节点插入 appendChild()

父级.appendChild(要追加的元素)

  • 方法
  • 在指定父级子节点最后一个后面追加子元素

insertBefore

父级.insertBefore(新的元素.指定的被插入的元素)

var divnew = document.createElement("p");
    divnew.innerHTML = "今天天气不错";
    divnew.style["color"] = "yellow";
 document.getElementById("div1").insertBefore(divnew,document.getElementsByClassName("abc")[0]);
 相当于最外面是div1,然后在class是abc的前面插入p
  • 在父级的指定子元素前面插入一个新的元素
  • 在IE下要是第二个参数不存在会报错误
  • 在其他浏览器下。要是第二个参数不存在。则会用appendChild()来添加

removeChild

父级.removeChild(要删除的节点)

replaceChild

父级.replaceChild(新节点,要替换的节点)

appendChild,insertBefore,replaceChild既可以操作静态节点,也可以操作动态节点


因为在JS里面没有addclassName方法,和removeclassName方法所以我们需要自己写

添加className方法

   var liall = document.getElementsByTagName("li");
  for(var i=0;i<liall.length;i++)
  {
      addClassName(liall[i],"on");
  }
    /*添加类*/
    function addClassName(obj,className2)
    {
        if(obj.className=="")
        {
            obj.className="on";
        }else
        {
            var Name = obj.getAttribute("class");
            var arr = Name.split(" ");
            var flag = false; //开关
            for(var i=0;i<arr.length;i++)
            {
                if(arr[i]==className2)         //当数组里面这个元素要是找到了证明他的存在,所以就没必要添加了
                {
                 flag = true;
                }
            }
            if(!flag)        //表示全部都没找到
            {
                obj.className +=" "+className2;
            }
        }
    }
    /*添加类结束*/

移除className方法

    var liall = document.getElementsByTagName("li");
      for(var i=0;i<liall.length;i++)
      {
          removeClassName(liall[i],"on");
      }
    /*移除class类名*/
    function removeClassName(obj,className2)
    {
     if(obj.className!="")
     {
         var string = obj.className;  //获取到类名
         var arr = string.split(" ");  //切割成数组
         var arrnew = [] ;  //新的数组用来存储
         for(var i=0;i<arr.length;i++)
         {
             if(arr[i] != className2)
             {
               arrnew.push(arr[i]);
             }
         }
        obj.className = arrnew.join(" ");

     }
    }
    /*移除class类名方法*/

表格操作

<table width="100%" id="tab1" border="1px">
    <tr>
        <td>1</td>
        <td>leo</td>
        <td>男</td>
        <td><a href="javascript:;">删除</a></td>
    </tr>
    <tr>
        <td>1</td>
        <td>小美</td>
        <td>女</td>
        <td><a href="javascript:;">删除</a></td>
    </tr>
</table>

因为没有写tbody所以他根本没办法获取到值

var oTab = document.getElementById('tab1');
    alert(oTab.children[1].children[1].innerHTML); 
    //什么也弹不出来,提示显示oTab.children[1]未定义,这是因为如果在table中没有添加tbody的话,浏览器会自动隐形添加一个tbody出来。因此,写表格结构时,最好添加上tbody。

下面这个是最正规的写法
<table width="100%" id="tab1" border="1px">
    <thead>
        <tr>
            <th>编号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1</td>
            <td>leo</td>
            <td>男</td>
            <td><a href="javascript:;">删除</a></td>
        </tr>
        <tr>
            <td>1</td>
            <td>小美</td>
            <td>女</td>
            <td><a href="javascript:;">删除</a></td>
        </tr>
    </tbody>
</table>

因为写了tbody便可以弹出来

var oTab = document.getElementById('tab1');
    // alert(oTab.children[0].children[1].children[1].innerHTML); //这是就可以弹出“小美”
    alert(oTab.tBodies[0].rows[1].cells[1].innerHTML); //弹出小美,更为直观

表格属性

  • tHead:表格头(DOM规定thead只能有一个)

  • tBodies表格正文(DOM规定tbody可以有多个)

  • tFoot表格尾(DOM规定只能有一个)

  • rows:行
  • cells:列
表格数据的操作
<table width="100%" id="tab1" border="1px">
    <thead>
        <tr>
            <th>编号</th>
            <th>姓名</th>
            <th>性别</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>

下面是动态创建表格

var data = [
    {id: 1, username: 'leo', sex: '男'},
    {id: 2, username: '小美', sex: '女'},
    {id: 3, username: '王亮', sex: '男'},
    {id: 4, username: '杜鹏', sex: '男'},
];

var oTab = document.getElementById('tab1');
var oTbody = oTab.tBodies[0];

for(var i=0; i<data.length; i++){ //表格的创建
    var oTr = document.createElement('tr');
    
    if(i%2 == 0){ //各行变色
        oTr.style.background = 'white';
    } else {
        oTr.style.background = 'gray';
    }
    
    var oTd = document.createElement('td');
    oTd.innerHTML = data[i].id;
    oTr.appendChild(oTd);
    
    oTd = document.createElement('td');
    oTd.innerHTML = data[i].username;
    oTr.appendChild(oTd);
    
    oTd = document.createElement('td');
    oTd.innerHTML = data[i].sex;
    oTr.appendChild(oTd);
    
    oTd = document.createElement('td');
    // oTd.innerHTML = ' '; //如果单元格中的内容为空,那么在IE7及以下,这个td不会被创建,为了好看,给最后一列td里面添加一个空格,这样在IE7下,最后一列td也会被创建
    oTr.appendChild(oTd);
    
    var oA = document.createElement('a');
    oA.innerHTML = '删除';
    oA.href = 'javascript:;';
    oA.onclick = function(){
        oTbody.removeChild(this.parentNode.parentNode);
        
        for(var i=0; i<oTbody.rows.length; i++){
            if(i%2 == 0) {
                oTbody.rows[i].style.background = 'white';
            } else {
                oTbody.rows[i].style.background = 'gray';
            }
        }
    }
    oTd.appendChild(oA);
    
    oTbody.appendChild(oTr);
}

表单操作

<form id="form1">
    <input type="text" name="text1" />

    <input type="radio" name="sex" value="男" checked />男
    <input type="radio" name="sex" value="女" />女

    <input type="checkbox" name="a" value="html" checked />html
    <input type="checkbox" name="a" value="css" />css
    <input type="checkbox" name="a" value="javascript" />javascript

    <select name="city">
        <option value="">请选择城市</option>
        <option value="北京">北京</option>
        <option value="上海">上海</option>
    </select>

    <input type="button" value="按钮" name="btn" />
</form>
var oForm = document.getElementById('form1');
oForm.text1.onchange = function(){
    alert(this.value); //注意,文本输入框onchange的触发,是在输入完毕之后,鼠标离开该文本框之后触发
}

oForm.sex[0].onchange = function(){
    // alert(1); 
    // alert(this.value);
} //注意:oForm.sex其实是一个元素集合,因为name为sex的单选按钮有两个

oForm.a[0].onchange = function(){
    alert(2);
}

// alert(oForm.city.value);
oForm.city.onchange = function(){
    alert(this.value);
}

oForm.btn.onclick = function(){
    
    //radio, checkbox 判断当前的选项是否被选中
    //alert(oForm.sex[0].checked);
    
    for(var i=0; i<oFrom.sex.length; i++){
        if(oForm.sex[i].checked){
            alert(oForm.sex[i].value + '被选中了');
        } else {
            alert(oForm.sex[i].value + '未被选中');
        }
    }
    
    for(var i=0; i<oFrom.a.length; i++){
        if(oForm.a[i].checked){
            alert(oForm.a[i].value + '被选中了');
        } else {
            alert(oForm.a[i].value + '未被选中');
        }
    }
}

表单中的name来获取元素父级.name


window.alert(document.getElementById("form1").sex.value);

onchange事件

  • onchange事件 :当值发生改变的时候触发
    在type = text里面 :当光标离开的时候,内容有变化就触发
    在type = radio/checkbox :
    在点击下的时候只要值发生改变,就是触发
    在非标准情况下焦点离开,值发生改变才触发
  • select 一选择不同的项就触发

onsubmit

  • onsubmit:当提交表单的时候触发
  • submit():方法提交表单

代码见下

<form id="form1" action="http://www.baidu.com">
        <input type="text" name="text1" />
        <input type="text" name="text2" value="111" />
        <input type="submit" name="dosubmit" value="提交" />
        <input type="reset" name="doreset" value="重置" />
    </form>

对应的JS代码

oForm.onsubmit = function(){
        if(this.text1.value == ''){
            alert('请输入内容');
            return false; //如果没有在文本框中填写任何内容,就写return false,那么点击“提交”按钮,也不会提交到http://www.baidu.com上
        }
    }
    /* 让页面等待一秒钟后自动提交
    setTimeout(function(){
        oForm.submit();
    }, 1000) 

onreset

PS:注意是重置,而不是清空,他的意思是恢复到默认值
onreset:当点击重置按钮的时候触发

oForm.onreset = function(){
  var re = window.confirm("你确定要重置吗?")
  return re;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容