JSDom、事件

2016-10-14  本文已影响153人  泰格_R
1.dom对象的innerText和innerHTML有什么区别?

Node.innerText返回获取到的目标元素节点内的文本内容,如果目标节点有嵌套,文本内容会自动按层拼接。Node.innerHTML返回获取到的目标元素节点的HTML结构(包括文本内容)。注意:通过Node.innerText="str...."/Node.innerHTML="<img src='' alt='' />"方法修改的只是在内存中的Node节点对象的文本内容/HTML,并不能修改实际HTML页面上的内容。Node.innerText方法修改时输入的内容为文本格式,即使有HTML标签也会当成文本。Node.innerHTML方法修改时当有HTML标签时会当成HTML标签处理

<body>
 <div>
  123
  <p>
      456
      <span>789</span></p></div><scripttype="text/javascript">var str=document.getElementsByTagName("div")[0];
console.log(str.innerText);//返回结果123 456 789
str.innerText="cc kk ee dd"console.log(str.innerText);//返回修改后的innerText内容为"cc kk ee dd",内存中的原内容被替换,实际页面不会被修改
str.innerHTML="<img src='' alt=''>";//修改innerHTML内容,内存中的原内容被替换,实际页面不会被修改console.log(str);//返回修改后的innerHTML:<div><img src='' alt=''></div></script>

2.elem.children和elem.childNodes的区别?

Node.children:返回子元素列表(返回HTMLCollection),只包括HTML元素不包括文本元素
Node.childNodes:返回子元素列表(返回NodeList),包括所有子元素(文本元素和HTML元素)

<!DOCTYPE html>
<html><head>
<title></title>
</head>
<body>
<divid="content">dddd
        <divclass="left"><p>aaaa</p></div>
        <divclass="right"><p>bbbbb</p></div>
</div>
<scripttype="text/javascript">
var chil1 =document.querySelector("div").children;
var child2 = document.querySelector("div").childNodes;
console.log(chil1); //返回[div.left, div.right] 只有两个html元素构成的类数组对象
console.log(child2);//返回[text, div.left, text, div.right, text]返回包含文本元素构成的类数组对象
</script>
</body>
</html>

3.查询元素有几种常见的方法?

document.getElementById("test") //返回匹配指定id的元素节点,Element单数哦因为id是唯一的
document.getElementsByClassName("red,test") //返回匹配指定类名的元素节点(搜索范围包括本身),返回的是类数组对象,不仅可以在document对象上调用,也可以在任何元素节点上调用。参数可为多个哦
document.getElementsByTagName("p");//返回所有指定标签的元素(搜索范围包括本身)
getElementsByName("kkk") //返回匹配元素有name属性,且name属性名为kkk的元素
querySelector(".classname/#id") //ES5新方法,如果有多个节点满足匹配条件,则返回第一个匹配的节点。
querySelectorAll() //返回匹配指定的CSS选择器的所有节点,返回结果不是动态集合,不会实时反映元素节点的变化。

<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
<divid="content">
        dddd
        <divclass="left"><p>aaaa</p></div>
      <divclass="right"><p>bbbbb</p></div>
</div>
    <form action=""name="fm001">
      <input type="text"id="ccc">
    </form><divid="content"></div>
<script type="text/javascript">
var quersela=document.querySelectorAll("#content,#ccc,.right")//这里可用逗号分隔多个选择器
console.log(quersela)//多个选择器选中返回的结果是多个不同node对象构成的类数组对象[div#content, div.right, input#ccc, div#content]
</script>
</body>
</html>

4.如何创建一个元素?如何给元素设置属性?

创建元素:
document.createElement("标签名称tagName") //document对象中创建HTML元素节点
document.createTextNode("文本节点内容") //创建文本节点
Node.cloneNode(true/false)//克隆节点,true深复制,false只复制自身节点

Paste_Image.png

创建元素返回结果:

Paste_Image.png

设置元素属性:
Node.setAttribute("class/id","name")

Paste_Image.png

设置属性后返回结果:

Paste_Image.png
5.元素的添加、删除?

Node.appendChild() //在元素末尾添加,如果参数节点是DOM中已经存在的节点,appendChild方法会将其从原来的位置,移动到新位置。
Node.insertBefore()//将目标节点插入当前节点的指定位置,有两个参数,第一个参数是所要插入的节点,第二个参数是当前节点的一个子节点,新的节点将插在这个节点的前面。
Node.removeChild() //父元素上删除其子元素,从当前节点移除该子节点。
1.增加元素node.appendChild(newnode//将新增的元素newnode插入到父元素node中的最后位置

Paste_Image.png
var newnod1=document.createElement("a");
var nod1=document.getElementById('content');
newnod1.setAttribute("class","wrap ccc");
nod1.appendChild(newnod1);

增加元素appendChild()返回结果

Paste_Image.png

2.增加元素node.inserBefore(newnode,node.fristChild)//将新增的元素newnode插入到父元素node下的指定位置

Paste_Image.png
var newnod1=document.createElement("a");
var nod1=document.getElementById('content');
newnod1.setAttribute("class","wrap ccc");
nod1.insertBefore(newnod1,nod1.lastChild);
console.log(nod1);

增加元素insertBefore()返回结果:

Paste_Image.png

3.删除元素node.parentNode.removeChild(node)//删除元素自身,参考父元素的位置

Paste_Image.png
var nod1=document.getElementsByClassName("right");//nod1是类数组对象 ,要删除的目标元素
nod1[0].parentNode.removeChild(nod1[0]);//删除类数组对象中的第一个 。删除目标元素的父元下的某子元素,参考父元素位置
var nod2=document.getElementById("content");
console.log(nod2);
删除元素返回结果:类名=right的元素被删除了
Paste_Image.png
6.DOM0 事件和DOM2级在事件监听使用方式上有什么区别?

DOM0 事件方法指定的事件处理程序是元素的方法,事件处理程序是在元素的作用域中运行,即程序中的this引用当前元素。如果要删除DOM0 级事件处理程序,只要将事件处理程序设置为null即可。
DOM2 定义的事件方法有两种addEventListener()和removeEventListener(),接受三个参数:1.事件名称 2.事件处理函数 3.布尔值,调用事件处理函数的方式(true在事件捕获阶段调用,false在事件冒泡阶段处理),所有DOM节点都支持这两种方法。通过addEventListener()添加的事件只能通过removeEventListener()来删除,删除时传入的参数与添加时相同,这也就意味着添加的匿名函数是无法删除的。
DOM0和DOM2的区别:1.DOM2级的事件可绑定多个事件处理函数。2.DOM0级事件只能在冒泡阶段响应,无法选择其他方式,而DOM2级可以选择。

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<divid="content">
    <ahref="#"id="link1">点击1</a>
        <divclass="left">
                <ahref="#"id="link2">点击2</a>
        </div>
        <divclass="right">
                <p>点击3</p>
        </div>
</div>
<script>
var str1=document.querySelector("#link1");
functionk2(){
    console.log(this);
}
str1.addEventListener("click",k2,false);//DOM2级事件var str2=document.querySelector("#link2");
str2.onclick=functionk3(){//DOM0级事件console.log(this)
}
</script>
</body>
</html>

点击1/点击2运行结果

Paste_Image.png
7.attachEvent与addEventListener的区别?

【1】接受的参数:
attachEvent接受2个参数:事件名称,事件处理函数,只支持事件冒泡。
addEventListener接受3个参数:事件名称,事件处理函数,布尔值(选择是事件冒泡时执行,还是事件获取时执行)
【2】事件名称:
attachEvent事件名称前面要加“on”,如“onclick”,
addEventListener不需要,如“click”。
【3】作用域:
attachEvent会在全局作用域中运行,即this = window。
addEventListener是在元素作用域中运行,this指的是当前元素。
【4】事件处理程序的顺序:
addEventListener是按照添加顺序执行。
attachEvent是按照添加顺序相反执行。
【5】删除方法:
attachEvent使用detachEvent删除添加事件。
addEventListener使用removeEventListener删除添加事件。
【6】兼容:
IE8以及IE8以下只支持attachEvent,
IE9开始支持addEventListener。


8.解释IE事件冒泡和DOM2事件传播机制?

DOM2事件传播机制:当一个事件发生以后,它会在不同的DOM节点之间传播(propagation)。这种传播分成三个阶段:
第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。这种三阶段的传播模型,会使得一个事件在多个节点上触发。事件传播的最上层对象是window,接着依次是document,html(document.documentElement)和body(document.dody)。也就是说,如果body元素中有一个div元素,点击该元素。事件的传播顺序,在捕获阶段依次为window、document、html、body、div(由外层向内层找,由不具体到具体),在冒泡阶段依次为div、body、html、document、window(由内层向外层,有具体到不具体)。

<div>
  <p>Click Me</p>
</div>

如果对这两个节点的click事件都设定监听函数,则click事件会被触发四次。
捕获阶段:事件从div向p传播时,触发div的click事件;
目标阶段:事件从div到达p时,触发p的click事件;
目标阶段:事件离开p时,触发p的click事件;
冒泡阶段:事件从p传回div时,再次触发div的click事件。

IE事件冒泡:指的是IE的事件流,事件开始时由最具体的元素(文档嵌套层次最深的那个节点)接受,然后逐渐向上传播到较为不具体的节点(文档)
DOM2的事件传播机制:指的是DOM2级事件的事件流,包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标收到事件。最后一个是冒泡阶段,事件作出相应。


9.如何阻止事件冒泡? 如何阻止默认事件?

阻止事件冒泡:
stopPropagation()方法阻止事件在DOM中继续传播,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上新定义的事件监听函数。

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<divid="content">
    <divid="link1">点击1
        <divclass="left">
                <divhref="#"id="link2">点击2</div>
        </div>
    </div>
</div>
<script>
    var str1 = document.querySelector("#link1")
  var str2 = document.querySelector("#link2")
    var str3 = document.querySelector("#content")

  str1.addEventListener("click",function(){
      console.log(this.id+"冒泡到我这");
  },false);

    str3.addEventListener("click",function(){
      console.log(this.id+"冒泡到我这");
  },false);

  str2.addEventListener("click",function(mousev){
      console.log(this.id);
      //mousev.stopPropagation();
  },false);

</script>
</body>
</html>

点击2时执行结果:

Paste_Image.png

点击2事件监听函数中增加mousev.stopPropagation()后,事件不会冒泡,执行结果为

Paste_Image.png

阻止默认事件:
preventDefault()方法取消浏览器对当前事件的默认行为,比如点击链接后,浏览器跳转到指定页面,或者按一下空格键,页面向下滚动一段距离。该方法生效的前提是,事件的cancelable属性为true,如果为false,则调用该方法没有任何效果。该方法不会阻止事件的进一步传播(stopPropagation方法可用于这个目的)。只要在事件的传播过程中(捕获阶段、目标阶段、冒泡阶段皆可),使用了preventDefault方法,该事件的默认方法就不会执行。

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<divid="content">
    <ahref="#"id="link1">点击1</a>
        <divclass="left">
                <ahref="http://www.baidu.com"id="link2">点击2</a>
        </div>
        <divclass="right">
                <p>点击3</p>
        </div>
</div>
<script>
var str1=document.querySelector("#link1")
var str2=document.querySelector("#link2")
str1.addEventListener("click",functionk2(e){
    this.setAttribute("href","http://cn.bing.com/");//这里this是元素本身
},false)

str2.addEventListener("click",functionk3(e){
    console.log(e);//这里的e是鼠标对象事件MouseEvent,与this不一样console.log(this);
    e.preventDefault();//阻止了鼠标事件MouseEvent的默认跳转到目标链接的行为
},false)
</script>
</body>
</html>

点击1执行效果:更改link1的href值,并跳转到目标网址bing
点击2执行效果(不跳转到目标网址):

Paste_Image.png
10.有如下代码,要求当点击每一个元素li时控制台展示该元素的文本内容。不考虑兼容
<ul class="ct">
    <li>这里是</li>
<li>饥人谷</li>
<li>前端6班</li>
</ul>
<script>//todo ...</script>

代码如下:

<!DOCTYPE html>
<html>
<head><title></title>
</head>
  <body>
<ul class="ct">
<li>这里是</li>
<li>饥人谷</li>
<li>前端6班</li>
</ul>
<script>
var str1=document.querySelectorAll("li")//这里str1是类数组对象for(var i=0;i<str1.length;i++){
    for(var i=0;i<str1.length;i++){
      str1[i].addEventListener("click",function(mousev){//循环遍历类数组对象成员,为每个成员绑定点击事件console.log(this.innerText)
      console.log(mousev.target.innerText)
      },false)
    }

</script>
  </body>
</html>

预览地址


11.补全代码,要求:

1.当点击按钮开头添加时在<li>这里是</li>元素前添加一个新元素,内容为用户输入的非空字符串;当点击结尾添加时在<li>前端6班</li>后添加用户输入的非空字符串.
2.当点击每一个元素li时控制台展示该元素的文本内容。

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
    <title></title>
</head>
<body>
    <ul class="ct">
        <li>这里是</li>
        <li>饥人谷</li>
        <li>前端6班</li>
    </ul>
    <input class="ipt-add-content" placeholder="添加内容"/>
    <button id="btn-add-start">开头添加</button>
    <button id="btn-add-end">结尾添加</button>
    <script>
    var str1=document.querySelector(".ct"),
     str2=document.querySelectorAll("li"),
    str3=document.querySelector(".ipt-add-content"),
    str4=document.querySelector("#btn-add-start"),
    str5=document.querySelector("#btn-add-end")

    str5.addEventListener("click",function(mousev){
        var newnode=document.createElement("li");
        if(!str3.value){
            console.log("没输入内容")
            return
        }
            newnode.innerText=str3.value;
            str1.appendChild(newnode)//目标元素插入到父元素下的最后一个子元素位置处
    },false)

    str4.addEventListener("click",function(mousev){
        var newnode=document.createElement("li");
        if(!str3.value){
            console.log("没输入内容")
            return
        }
        newnode.innerText=str3.value;
        str1.insertBefore(newnode,str1.firstChild)//目标元素插入到父元素str1下的指定位置
    },false)

    str1.addEventListener("click",function(mousev){
        console.log(mousev.target.innerText)//事件委托,在li父元素ct上添加事件委托就能监听到所有子元素的点击事件
    },false)
    </script>
</body>
</html>

预览地址


12.补全代码,要求:当鼠标放置在li元素上,会在img-preview里展示当前li元素的data-img对应的图片。
<ul class="ct">
    <li data-img="1.png">鼠标放置查看图片1</li>
    <li data-img="2.png">鼠标放置查看图片2</li>
    <li data-img="3.png">鼠标放置查看图片3</li>
</ul>
<div class="img-preview"></div>
<script>
//todo ...
</script>

代码如下:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<ul class="ct">
<li>鼠标放置查看图片1</li>
<li>鼠标放置查看图片2</li>
<li>鼠标放置查看图片3</li>
</ul>
<div class="img-preview"></div>
<script>
var str1=document.querySelectorAll("li")
    var str2=document.querySelector(".img-preview")
    for(var i=0;i<str1.length;i++){
        (functiont1(m){//生成闭包,参数m由外层i传入return str1[m].addEventListener("mouseenter",function(mousev){
                var newnode=document.createElement("img");
                str2.innerHTML="<img src=http://cdn.jirengu.com/book.jirengu.com/img/1"+[m]+".jpg>"
            },false)
        }(i))
        }
    </script>
</body>
</html>

预览地址(for循环)
用事件代理


<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <ul class="ct">
    <li data-img="http://cdn.jirengu.com/book.jirengu.com/img/11.jpg">鼠标放置查看图片1</li>
    <li data-img="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg">鼠标放置查看图片2</li>
    <li data-img="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg">鼠标放置查看图片3</li>
    </ul>
    <div class="img-preview"></div>
    <script>
    var str1=document.querySelectorAll("li");
    var str2=document.querySelector(".img-preview");
    var str3=document.querySelector(".ct");
    str3.addEventListener("mouseenter",function(mousev){//父元素.ct上绑定时间代理能监听到所有子元素的事件
        var newnode=mousev.target.getAttribute('data-img')
        str2.innerHTML="<img src="+newnode+">"
    },true)//mouseenter即鼠标移入,移入过程是由外向内即ul到li,如果为false冒泡响应,内部元素li事件还没发生ul就已经完成了事件响应。
    //改为true即事件捕获时响应,定位到准确的元素后再做响应,此例中当移入到ul上时会返回错误信息,移动到li上无影响。
    </script>
</body>
</html>

预览地址(事件代理)


13.实现如下图Tab切换的功能
Paste_Image.png

代码如下:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style>
html,body,ul,li{
    padding:0px;
    margin:0px;
}
    ul,li{
    list-style: none;
    }
    #container{
        margin:0 auto;
        width:604px;
        min-width:400px;
        border-left:1px solid #ccc;

    }
    .tabs>li{
        height:30px;
        width:200px;
        float:left;
        text-align:center;
        border-right:1px solid #ccc;
        border-left:none;
        line-height:24px;
        cursor: pointer;
    }

    .tabs>li{

    }

    .clearfix:after{
    content:"";
    display: block;
    clear: both;
    }

        .tabactive{
            background:#eee;
        }

        .cont{
            border:1px solid #ccc;
            border-left:none;
            height:200px;
            padding-top:20px;
            padding-left:20px;
            display:none;
        }

        .cont.ctactive{
            display:block;
        }
    </style>
</head>
<body>
    <div id="container">
        <ul class="tabs clearfix">
            <li class="tabactive">tab1</li>
            <li>tab2</li>
            <li>tab3</li>
        </ul>
        <div class="cont ctactive">内容1</div>
        <div class="cont">内容2</div>
        <div class="cont">内容3</div>
    </div>

    <script>
var str1=document.querySelectorAll("li"),
        str2=document.querySelectorAll(".cont");
        for(var i=0;i<str1.length;i++){//外层循环后开始,遍历li元素绑定事件
            //str1[i].count=i;
            str1[i].addEventListener("click",function(mousev){
                for(var i=0;i<str1.length;i++){//内层循环先开始,将li,div的样式重置
                    str1[i].className="";
                    str2[i].style.display="none";
                }
                mousev.target.className="tabactive";//对事件目标元素修改属性(加背景色)
                //str2[this.count].style.display="block";
                //console.log(this)
                var contindex=parseInt(mousev.target.innerText.match(/\d$/g))//通过事件目标元素找到里面的文本内容匹配返回数字1,2,3作为索引
                str2[contindex-1].style.display="block"//str2类数组对象中按contindex提供的索引号找到对应的div元素并设置其样式
            },false);
        }

    </script>
</body>
</html>

预览地址


14.实现下图的模态框功能

Paste_Image.png

代码如下:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>任务5-2</title>
    <style type="text/css">
        html,body{
            margin:0px;
            padding:0px;
        }
        a{
            text-decoration:none;
      color:black;
        }

    .content{
      width:400px;
      border:1px solid #ccc;
      border-radius:5px;
      position:fixed;
      top:50%;
      left:50%;
      transform:translate(-50%,-50%);
      background:#fff;
      z-index:100;
      display:none;
    }

    .cover{
      position:fixed;
      top:0px;
      right:0px;
      bottom:0px;
      left:0px;
      background:#000;
      opacity:0.3;
      z-index:99;
      display:none;
    }

    .clearfix:after{
      content:"";
      display:block;
      clear:both;
    }

    .close{
      position: absolute;
      top: 0px;
      right: 15px;
    }

    .head{
      height:40px;
      line-height:40px;
      border-bottom:1px solid #ccc;
    }

    h3{
      margin:0px;
      margin-left:10px;
      font-size:20px;
    }

    .footer>a{
      float:right;
      padding:10px;
    }

    .middle{
      height:150px;
      border-bottom:1px solid #ccc;
    }

    .middle>p{
      padding-left:10px;
    }

    .footer{
      height:40px;
    }

    .active{
        display:block;
    }
    </style>
</head>
<body>
<button class="btn start">点我</button>
<div class="cover"></div>
    <div class="content">
        <div class="head">
                <h3>我是标题</h3>
                <a href="#" class="close">X</a>
        </div>
        <div class="middle">
                <p>内容1</p>
                <p>内容2</p>
        </div>
        <div class="footer clearfix">
                <a href="#" class="enter">确认</a>
                <a href="#" class="exit">取消</a>
        </div>
    </div>

        <script>
      function  hasClass(el,cl){
          var reg=new RegExp('\\b'+cl+'\\b','g');//不要使用字面量方式,字面量方式参数cl会被当成字符串
          return reg.test(el.className);
        }


        function addClass(el,cl){
          if(!hasClass(el,cl)){
            el.className += " "+cl;
          }
        }

      function  removeClass(el,cl){
          if(hasClass(el,cl)){
            el.className=el.className.replace(cl,"")
          }
        }

       var node_btn = document.querySelector(".btn"),
            node_cover = document.querySelector(".cover"),
            node_cont= document.querySelector(".content"),
            node_body=document.querySelector("body")

            node_btn.addEventListener("click",function(mousev){
                mousev.stopPropagation();//阻止事件冒泡,防止点击后冒泡到body上触发删除属性的事件
                addClass(node_cover,"active");
                addClass(node_cont,"active");
            },false);

            node_cont.addEventListener("click",function(mousev){
              mousev.stopPropagation();//阻止时间冒泡,防止冒泡到content上触发删除属性的时间
              if(hasClass(mousev.target,"close")||hasClass(mousev.target,"exit")){
                // 等同于if(mousev.target.className=="close"||mousev.target.className=="exit"){
                removeClass(node_cover,"active");
                removeClass(node_cont,"active");
              }
            },false)

            node_body.addEventListener("click",function(mousev){
              removeClass(node_cover,"active");
              removeClass(node_cont,"active");
            },false)
        </script>
</body>
</html>

预览地址

上一篇 下一篇

猜你喜欢

热点阅读