Dom、事件

2016-10-08  本文已影响90人  饥人谷_任磊

问题

1.dom对象的innerText和innerHTML有什么区别?

<body>
    <div id="content">
        <p>This is a <strong>test</strong> paragraph</p>
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
    </div>
</body>
<script>
    var oDiv = document.getElementById("content");
    console.log(oDiv.innerText);
    oDiv.innerText = "<h2>Hello & <strong>hunger</strong></h2>";
innerText运行结果
<body>
    <div id="content">
        <p>This is a <strong>test</strong> paragraph</p>
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
    </div>
</body>
<script>
    var oDiv = document.getElementById("content");
    console.log(oDiv.innerHTML);
    oDiv.innerHTML = "<h2>Hello & <strong>hunger</strong></h2>";
innerHTML运行结果.png

那么总而言之:innerHTML是一种插入HTML字符的方法,所以它会根据标签生成DOM树,而innerText是一种插入文本的方法,所以它会过滤掉标签。

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

<body>
        <ul id="test">
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
</body>
<script>
    var oUl = document.getElementById("test");
    console.log(oUl.children.length);//返回7,包括3个元素节点和4个空白字符的文本节点
</script>
<body>
        <ul id="test">
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
</body>
<script>
    var oUl = document.getElementById("test");
    console.log(oUl.children.length);//返回3
</script>

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

刚开始接触HTMLCollection和NodeList时,对它们之间关系挺莫名其妙的,后来查阅了下资料才稍微有些明白。
具体可以参考这个回答:NodeList 和 HTMLCollection之间的关系?
简单来说就是由于历史原因,DOM规范分为2个部分:Core(最基础的XML解析说明)和HTML(HTML的特有API解析说明)。而NodeList是属于Core的,HTMLCollection 是属于HTML的。
它们返回的都是实时的Node合集,并且可以Node[取索引]来返回子节点。
不同的是NodeList是node节点集合(即包含元素节点,文档节点和注释节点等12种节点类型),而HTMLCollection只包含元素节点集合,所以在HTML文档中,getByElement系列都是HTMLCollection集合。
而有的书上说这些查询元素的方法都是NodeList集合,有的说是HTMLCollection合集,看起来很矛盾,其实是讨论的使用环境不一样罢了 。
另外动态集合虽然很实用,但是在循环它们的时候要特别小心,不要因为忽略了实时变化而造成死循环。
参考:深入理解javascript中的动态集合——NodeList、HTMLCollection和NamedNodeMap

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

<body>
    <div></div>
</body>
<script>
    var oDiv = document.getElementsByTagName("div")[0];
    var oImg = document.createElement("img");
    var txt = document.createTextNode("my images")
    oImg.setAttribute("alt","A cup of coffee");
    oImg.setAttribute("src","images/coffee.jpg");
    oDiv.appendChild(oImg);
    oDiv.appendChild(txt);
</script>
运行结果

5.元素的添加、删除。

<body>
    <ul id="test">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</body>
<script>
    var oUl = document.getElementById("test");
    var oLi = document.createElement("li");
    oUl.appendChild(oLi);
</script>
运行结果
<body>
    <ul id="test">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</body>
<script>
    var oUl = document.getElementById("test");
    var oLi = document.createElement("li");
    oUl.insertBefore(oLi,oUl.firstChild);
</script>
运行结果
<body>
    <ul id="test">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
</body>
<script>
    var oUl = document.getElementById("test");
    var oLi = document.querySelectorAll("li")[0];
    oUl.removeChild(oLi);
</script>
运行结果

6.DOM0 事件和DOM2级在事件监听使用方式上有什么区别?

<body>
<input id="myBtn" type="button" value="点击我"/>
</body>
<script>
    var oBtn = document.getElementById("myBtn");
    oBtn.onclick = function(){
        console.log(this.id);
    }
</script>
运行结果

使用DOM0 级方法指定的事件处理程序被认为是元素的方法,因此,这个时候的事件处理程序是在元素的作用域中运行,换句话说,程序中的this引用当前元素,所以,上述例子点击按钮后显示的是元素的ID。
另外如果要删除DOM0 级事件处理程序,只要将事件处理程序设置为null即可。

看例子:

<body>
<input id="myBtn" type="button" value="点击我"/>
</body>
<script>
    var oBtn = document.getElementById("myBtn");
    oBtn.addEventListener("click",function(){
        console.log(this.id);
    },false);
    oBtn.addEventListener("click",function(){
        console.log("Hello world")
    },false);
</script>
运行结果
与DOM0 级的区别在于,使用DOM2 级方法可以添加多个事件处理程序。

另外,通过addEventListener()添加的事件只能通过removeEventListener()来删除,删除时传入的参数与添加时相同,这也就意味着添加的匿名函数是无法删除的。

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事件传播机制?

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

<body>
    <div id="test">
        <input id="myBtn" type="button" value="点击我"/>
    </div>
</body>
<script>
    var oDiv = document.getElementById("test");
    var oBtn = document.getElementById("myBtn");
    oDiv.addEventListener("click",function(){
        console.log(this.id+"我被冒泡了");
    },false);
    oBtn.addEventListener("click",function(ev){
        console.log(this.id);
        ev.stopPropagation();
    },false);
</script>
运行结果
<body>
    <div id="test">
        <a id="myLink" href="http://www.baidu.com">点击我</a>
    </div>
</body>
<script>
    var link = document.getElementById("myLink");
    link.addEventListener("click",function(ev){
        ev.preventDefault();//取消a链接点击转跳到指定的URL的默认行为。
    },false);
</script>
运行结果

代码

1.有如下代码,要求当点击每一个元素li时控制台展示该元素的文本内容。不考虑兼容

<ul class="ct">
    <li>这里是</li>
    <li>饥人谷</li>
    <li>前端6班</li>
</ul>
<script>
//todo ...
</script>

解答代码:
方法一, 循环子元素 :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>任务1</title>
</head>
<body>
<ul class="ct">
    <li>这里是</li>
    <li>饥人谷</li>
    <li>任务6班</li>
</ul>
<script>
    var oUl = document.getElementsByClassName("ct");
    var aLi = oUl[0].getElementsByTagName("li");
    for(var i=0,len=aLi.length; i<len; i++){
        aLi[i].addEventListener("click",function(){
            console.log(this.innerText);
        },false);
    }
</script>
</body>
</html>

代码1-方法1效果预览
方法二,事件代理:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>任务1</title>
</head>
<body>
<ul class="ct">
    <li>这里是</li>
    <li>饥人谷</li>
    <li>任务6班</li>
</ul>
<script>
    var oUl = document.getElementsByClassName("ct")[0];
    oUl.addEventListener("click",function(ev){
        console.log(ev.target.innerText)
    })
</script>
</body>
</html>

代码1-方法2效果预览

2.补全代码,要求:

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

<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>
//todo ...
</script>

解决代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>任务2</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 oUl = document.getElementsByClassName("ct")[0];
    var oLi = document.getElementsByTagName("li");
    var startBtn = document.getElementById("btn-add-start");
    var endBtn = document.getElementById("btn-add-end");
    var addContent = document.getElementsByClassName("ipt-add-content")[0];
    startBtn.addEventListener("click",function(){
        if(!addContent.value){
            alert("请输入内容");
        }
        else {
            var newLi = document.createElement("li");//注意逻辑顺序,是点击之后再创建一个新的li元素
            newLi.innerText = addContent.value;
            oUl.insertBefore(newLi,oLi[0]);
        }
    },false)
    endBtn.addEventListener("click",function(){
        if(!addContent.value){
            alert("请输入内容")
        }
        else{
            var newLi = document.createElement("li");
            newLi.innerText = addContent.value;
            oUl.appendChild(newLi);
        }
    },false)
    oUl.addEventListener("click",function(ev){
        console.log(ev.target.innerText);
    },false)
</script>
</body>
</html>

代码2效果预览

3.补全代码,要求:当鼠标放置在li元素上,会在img-preview里展示当前li元素的date-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 lang="en">
<head>
    <meta charset="UTF-8">
    <title>任务2</title>
</head>
<body>
<ul class="ct">
    <li data-img="1.jpg">鼠标放置查看图片1</li>
    <li data-img="2.jpg">鼠标放置查看图片2</li>
    <li data-img="3.jpg">鼠标放置查看图片3</li>
</ul>
<div class="img-preview"></div>
<script>
    var oDiv = document.querySelector(".img-preview");
        newImg = document.createElement("img");
    oDiv.appendChild(newImg);
    //方法一:循环子元素,设置事件程序
    var oLi = document.getElementsByTagName("li");
    for(var i=0,len=oLi.length; i<len; i++){
        oLi[i].onmouseover = function(){
            var source = this.getAttribute("data-img");
            newImg.setAttribute("src",source);
        }
    }

    //方法2:对父元素进行事件监听
//    var oUl = document.querySelector(".ct");
//    oUl.addEventListener("mouseover",function(ev){
//        var source = ev.target.getAttribute("data-img");
//        newImg.setAttribute("src",source);
//    },false);
</script>
</body>
</html>

代码3-方法1效果预览
代码3-方法2效果预览
4.实现如下图Tab切换的功能
解决代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>任务2</title>
    <style type="text/css">
        body,ul,li,p{
            margin:0;
            padding:0;
        }
        .clearfix:after{
            content:'';
            display:block;
            clear:both;
        }
        .tab-switch *{
            box-sizing:border-box;
        }
        .tab-switch{
            width:600px;
            margin:auto;
            margin-top:40px;
            border:1px solid #ccc;
        }
        .tab li{
            list-style-type:none;
            float:left;
            width:200px;
            height:40px;
            line-height:40px;
            text-align:center;
            cursor:pointer;
            border-right:1px solid #ccc;
            border-bottom: 1px solid #ccc;
        }
        .tab li:last-child{
            border-right:none;
        }
        .tab .active {
            background-color:#eee;
        }
        .tab-switch div{
            display:none;
            height:300px;
            padding:20px;
        }
        .tab-switch .content{
            display:block;
        }
    </style>
</head>
<body>
    <div class="tab-switch">
        <ul class="tab clearfix">
            <li class="active">tab1</li>
            <li>tab2</li>
            <li>tab3</li>
        </ul>
        <div class="content">内容1</div>
        <div>内容2</div>
        <div>内容3</div>
    </div>
    <script>
        var oDiv = document.querySelector(".tab-switch");
            aLi = oDiv.getElementsByTagName("li");
            aDiv = oDiv.getElementsByTagName("div");
        for(var i=0,len=aLi.length; i<len; i++){
            aLi[i].index = i;//创建一个index属性来表示div的序列号。
            aLi[i].addEventListener("click",function(){
                for(var i=0,len=aLi.length; i<len; i++){
                    aLi[i].className= "";
                    aDiv[i].style.display = "none";
                }
                this.className = "active";
                aDiv[this.index].style.display="block";
            },false);
        }
    </script>
</body>
</html>

代码4效果预览

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

方法1,直接修改显示效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>任务5</title>
    <style type="text/css">
        #modal-1{
            display:none;
        }
        a{
            text-decoration: none;
            color: #333;
        }
        .cover{
            position:fixed;
            top:0px;
            left:0px;
            right:0px;
            bottom:0px;
            background-color: #000;
            opacity:0.4;
            z-index:99;
        }
        .modal-ct{
            position:fixed;
            top:50%;
            left:50%;
            transform: translate(-50%,-50%);
            width:400px;
            border-radius: 3px;
            background-color:#fff;
            z-index:100;
        }
        .header {
            position:relative;
            height:36px;
            line-height:36px;
            border-bottom: 1px solid #ccc;
        }
        h3{
            margin: 0;
            padding-left: 10px;
            font-size: 16px;
        }
        .close{
            position:absolute;
            right:10px;
            top: 10px;
            line-height:1;
        }
        .content{
            padding:10px;
        }
        .footer{
            padding:10px;
            border-top:1px solid #eee;
        }
        .footer:after{
            content:'';
            display:block;
            clear:both;
        }
        .btn{
            float:right;
            margin-left:10px;
        }
    </style>
</head>
<body>
    <button class="btn-modal">点我!</button>
    <div id="modal-1" class="modal-dialog">
        <div class="cover"></div>
        <div class="modal-ct">
            <div class="header">
                <h3>我是标题3</h3>
                <a class="close" href="#">X</a>
            </div>
            <div class="content">
                <p>我是内容1</p>
                <p>我是内容2</p>
            </div>
            <div class="footer">
                <a class="btn btn-confirm" href="#">确定</a>
                <a class="btn btn-cancel" href="#">取消</a>
            </div>
        </div>
    </div>
    <script>
        var btn = document.querySelector(".btn-modal"),
                modal = document.querySelector("#modal-1"),
                modalCt= document.querySelector("#modal-1 .modal-ct");
        btn.addEventListener("click",function(ev){
            ev.stopPropagation();
            showModal(modal);
        });
        modalCt.addEventListener("click",function(ev){
            ev.stopPropagation();
            if(hasClass(ev.target,"close") || hasClass(ev.target,"btn-cancel")){
                hideModal(modal);
            }
        });
        document.body.addEventListener("click",function(){
            hideModal(modal);
        })
        function showModal(modal){
            modal.style.display = "block";
        }
        function hideModal(modal) {
            modal.style.display = "none";
        }
        function hasClass(ele, cls){
            return ele.className.match(new RegExp('\\b'+cls+'\\b'));
        }
    </script>
</body>
</html>

代码5-方法1效果预览
方法2,通过添加和删除类名来改变显示效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>任务5-2</title>
    <style type="text/css">
        a{
            text-decoration: none;
            color: #333;
        }
        .cover{
            position:fixed;
            top:0px;
            left:0px;
            right:0px;
            bottom:0px;
            background-color: #000;
            opacity:0.4;
            z-index:99;
            display:none;
        }
        .modal-ct{
            position:fixed;
            top:50%;
            left:50%;
            transform: translate(-50%,-50%);
            width:400px;
            border-radius: 3px;
            background-color:#fff;
            z-index:100;
            display:none;
        }
        .header {
            position:relative;
            height:36px;
            line-height:36px;
            border-bottom: 1px solid #ccc;
        }
        h3{
            margin: 0;
            padding-left: 10px;
            font-size: 16px;
        }
        .close{
            position:absolute;
            right:10px;
            top: 10px;
            line-height:1;
        }
        .content{
            padding:10px;
        }
        .footer{
            padding:10px;
            border-top:1px solid #eee;
        }
        .footer:after{
            content:'';
            display:block;
            clear:both;
        }
        .btn{
            float:right;
            margin-left:10px;
        }
        .active{
            display:block;
        }
    </style>
</head>
<body>
    <button class="btn-modal">点我!</button>
    <div id="modal-1" class="modal-dialog ">
        <div class="cover"></div>
        <div class="modal-ct">
            <div class="header">
                <h3>我是标题3</h3>
                <a class="close" href="#">X</a>
            </div>
            <div class="content">
                <p>我是内容1</p>
                <p>我是内容2</p>
            </div>
            <div class="footer">
                <a class="btn btn-confirm" href="#">确定</a>
                <a class="btn btn-cancel" href="#">取消</a>
            </div>
        </div>
    </div>
    <script>
        var oBtn = document.querySelector(".btn-modal"),
            oCover = document.querySelector(".cover"),
            oModalCt= document.querySelector("#modal-1 .modal-ct");
        oBtn.addEventListener("click",function(ev){
            ev.stopPropagation();
            addClass(oCover,"active");
            addClass(oModalCt,"active");
        });
        oModalCt.addEventListener("click",function(ev){
            ev.stopPropagation();
            if(hasClass(ev.target,"close") || hasClass(ev.target,"btn-cancel")){
                removeClass(oCover,"active");
                removeClass(oModalCt,"active");
            }
        });
        document.body.addEventListener("click",function(ev){
            removeClass(oCover,"active");
            removeClass(oModalCt,"active");
        });
        function hasClass(ele, cls){
            var reg = new RegExp('\\b'+cls+'\\b','g');
            return reg.test(ele.className);
        };
        function addClass(ele, cls){
            if(!hasClass(ele,cls)){
                ele.className += " "+cls
            }
        };
        function removeClass(ele,cls){
            if(hasClass(ele,cls)){
                ele.className = ele.className.replace(cls,"")
            }
        };
    </script>
</body>
</html>

代码5-方法2效果预览


本文版权归本人和饥人谷所有,转载请注明来源。

上一篇 下一篇

猜你喜欢

热点阅读