奥门威尼斯网址【JavaScript】js动态添加dom,如何绑定事件

首先,比如我们使用JavaScript来加强我们的网页,但是我们要考虑到,如果用户的浏览器不支持JavaScript,或者用户disable了JavaScript的功能,那我们的网页能不能正常显示呢?例如下面的例子,

首先要明白浏览器在加载页面的时候是按顺序来加载的,这样以来就很清楚了,js动态添加dom以后,这些dom并没有绑定事件,这个时候最简单的一个办法就是:将绑定事件的方法封装到一个函数A中,在动态添加完dom以后立即执行一次函数A即可。

浏览器事件概述

    var addHandler = function(element,type,handler){
        //被绑定的dom对象,绑定类型,事件处理函数
        if(element.addEventListener){
            //非ie中的处理 
            element.addEventListener(type,handler,false);//false表示在冒泡阶段调用函数
        }
        else if(element.attachEvent)
        {
            //ie中的处理
            element.attachEvent("on" + type,handler);
        }
        else
        {
            //如果该浏览器对DOM2级不支持,则使用DOM0级方式。
            element["on" + type] = handler;
        }
    }

    var content = document.getElementById("content");
    if (content != null && content != undefined){
        var handler = function(){
            alert("ok");
        }
        addHandler(content,"mouseover",handler);
    }

复制代码 代码如下:

需要注意的是,在你可能同时需要添加许多的dom,不要添加一个就执行一次函数A,这样会增加浏览器的负载,你需要在所有dom添加完以后在执行函数A,例如你用一个for循环遍历dom组合并拼接成一个字符串,然后添加到某个父级dom里面,这个时候你需要在循环外添加一次就可以了。

  技术一般水平有限,有什么错的地方,望大家指正。

 

<a href = “#” onclick = “popUp(”) ; return
false;”>

代码如下:

  当我们在浏览网页的时候,浏览器可以在视觉上为我们展示出页面还可以在行为上响应用户的操作,浏览器响应用户的操作就是通过事件来完成的,浏览器提供了事件注册接口和事件监听接口这样浏览器就可以接收用户的行为并且进行处理了。浏览器已经提供很多的事件包括页面加载、鼠标事件以及键盘事件等,我们只需要定义好事件处理函数即可,当用户的操作触发这些事件时就会执行我们预先定义好的处理函数。一个行为的完整过程如下:

其中popUp这个函数是自定义的,新打开一个窗口来限制URL中的网页。但是如果当客户端不支持时,那这个网页就不能正常工作了。所以我们在这样做的使用,也考虑到更多,使用如下的代码就会显得更加合适。

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>添加div并绑定点击事件</title>
    <style>
        div.btn{
            width: 200px;
            height: 50px;
            line-height: 50px;
            text-align: center;
            border: solid 1px #000;
            cursor: pointer;
        }
        div.innerDiv{
            width: 50px;
            height: 50px;
            background-color: black;
            margin: 10px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <div class="aa">
        <div class="btn">添加div并绑定点击事件</div>
        <div class="outerDiv"></div>
    </div>
    <script>
        function getClass(classname) {
            return document.getElementsByClassName(classname);
        }
        getClass('btn')[0].onclick=function () {
            addDom();
        }
        //    将点击事件封装为函数
        function funA() {
            for(var i=0;i<getClass('innerDiv').length;i++){
                getClass('innerDiv')[i].onclick=function () {
                    alert(this.innerText);
                }
            }
        }
        //    将添加dom封装为函数
        function addDom() {
            var oldHtml='';
            for(var j=0;j<6;j++){
                oldHtml+='<div class="innerDiv">'+j+'</div>'
            }
            getClass('outerDiv')[0].innerHTML=oldHtml;
            funA();
        }
        //    如果将函数A放在这里就不会起作用的
        //    funA();
    </script>
</body>
</html>

奥门威尼斯网址 1

复制代码 代码如下:

个人博客:午后南杂

  浏览器在交互的过程中基本的功能就是通过事件+AJAX来完成的,浏览器通过事件来响应用户的行为,如果是有关数据的操作在通过AJAX来与服务器完成交互。

<a href = “” onclick = “popUp(this.href) ; return
false;”> 

事件的基本使用

接着,作者以CSS为例子。在我们使用CSS的过程中,我们发现,除了我们使用了<link>把CSS文件给加载进来外,我们没有在我们的网页内容中加入任何css相关的代码,这样就能很好的把structure和style分开了,即我们的css的代码没有侵入我们的主要代码里面。这样就算客户端不知道css,但是我们的主要内容客户还是可以看到的,我们的内容结构也能在客户那里显示出来。所以JavaScript相当于behavior层,css相当于presentation层。JavaScript也能像CSS一样做到没有侵入性。下面是书上的一个例子。

  首先事件有三种不同的绑定方式,分别为在DOM元素中直接绑定、在JavaScript中绑定,绑定事件监听函数。

复制代码 代码如下:

  在DOM元素中直接绑定形式如下:

<a href = “” onclick = “popUp(this.href) ; return
false;”>

<button id="demo" onclick="test('test')">button</div>

上面这段代码已经能保证在客户端不支持JavaScript的情况下仍然可以正常的工作,但是上面的代码中出现了onclick这样的event
handler。所以现在我们使用像CSS中的方式来完成我们所要的功能。如下:

  在一般情况下这可以说是最不好的一种绑定方法了,首先表现层和行为层耦合在一起,对于后期的维护带来了极大的不便,其次必须使用全局函数,我们都知道要尽可能的减少全局变量的声明,而且这种绑定方式是可以被覆盖的,如果我们在JS中在为该元素绑定一个点击处理函数,那么在DOM元素中绑定的事件处理函数都不会执行。

复制代码 代码如下:

function test(){
  console.log("DOM");
}
window.onload = function(){
  var demo = document.getElementById("demo");
  demo.onclick = function(){
      console.log("JS");
  }
}
//只打印JS

<a href = “” class = “popup”>

  在JavaScript中绑定形式如下:

这样,我们能在这个页面加载完成的时候,执行window.onload中,来检测哪些<a>是使用了class,然后统一使用popUp的方法。如下代码

window.onload = function(){
  var demo = document.getElementById("demo");
  demo.onclick = function(){
      console.log("JS");
  }
}

复制代码 代码如下:

  这种绑定方式的缺点在于只能注册一个监听函数,后面的监听函数会覆盖前面的监听函数假如我们有如下的代码:

var links = document.getElementsByTagName(“a”);
for (var i=0 ; i<links.length ; i++) {
 if (links[i].getAttribute(“class”) == “popup”) {
  links[i].onclick = function() {
   popUp(this.getAttribute(“href”));  //Attention use this in  this
place. Because this is equals onClick = “popUp(this.href)”
   //so we cann’t use links[i].
   return false;
  }
 }
}

window.onload = function(){
  var demo = document.getElementById("demo");
  demo.onclick = function(){
      console.log("JS");
  }
  demo.onclick = function(){
      console.log("change");
  }
}
//打印change

这样就能更少地侵入我们html代码了。

  绑定事件监听函数形式如下:

 
最后,作者讲了我们要做到向后兼容和JavaScript的最小化。向后兼容,我们可以使用类似if(document.getElementById)来测试这个方法时候存在,存在了才能使用。JavaScript代码的最小化主要是为了减少JavaScript,这样能加快我们网页的加载。

window.onload = function(){
  var demo = document.getElementById("demo");
  demo.addEventListener("click",function(){console.log("handler1")},false);
  demo.addEventListener("click",function(){console.log("handler2")},false);
}
//打印handler1 handler2

  下面我在看书的时候碰到不懂的问题,希望大虾们能帮忙解决一下。

  这种绑定方法可以满足我们的要求,表现层行为层分离,一个事件可以绑定多个处理函数,除了兼容方面的问题好像就没什么问题了,兼容问题后面再介绍首先看一下addEventListener的用法。

   对于<script>应该放在哪里?JavaScript
DOM编程艺术中所说的,我们可以把<script>放在</body>之前,不要放在<head></head>里,这样可以加快我们加载page的速度。不是很理解。

  addEventListener接收三个参数,第一个参数表示事件名称,第二个参数表示事件处理函数,第三个参数表示事件是捕获或冒泡。

  

  第一个参数表示事件名称在使用时就是”click”、”mousemove”不要带有on,第二个参数表示事件的处理函数,一般称为回调函数,可以是一个匿名函数表达式或者函数名称,第三个参数是一个布尔值为true时表示事件捕获为false表示事件冒泡,一般第三个参数我们都设置为false,因为在IE浏览器下只支持事件冒泡。

原文:

addEventListener兼容问题处理

The placement of your scripts in the markup also plays a big part in
initial load times. Traditionally,
we were told to always place scripts in the <head> portion of the
document, but there’s a problem with
that. Scripts in the <head> block the browser’s ability to
download additional files (such as images or
other scripts) in parallel. In general, the HTTP specification suggests
that browsers download no more
than two items at the same time per hostname. While a script is
downloading, however, the browser
won’t start any other downloads, even on different hostnames, so
everything must wait until the script
has finished.
If you’re following the progressive enhancement and unobtrusive
methodologies discussed earlier
in the chapter, then moving your <script> tags shouldn’t be an
issue. You can make your pages load
faster simply by including all your <script> tags at the end of
the document, directly before the </body>

  在非IE浏览器中addEventListener是可以正常使用的在IE9及以上的版本中也是可以使用的,IE提供了一个相同功能的API就是attachEvent来保证在IE8及以下可以正常使用。attachEvent接收两个参数第一个参数表示事件名称需要加上on比如”onclick”、”onmousemove”,第二个参数表示事件处理函数可以是一个匿名函数表达式或者函数名称,基本使用方式如下:

tag. When the scripts load, your window load events will still apply
your changes to the document.

window.onload = function(){
  var demo = document.getElementById("demo");
  demo.attachEvent("onclick",function(){console.log("handler1")});
  demo.attachEvent("onclick",function(){console.log("handler2")});
}

  所以在绑定事件时要同时考虑这两种情况,我们可以自行封装一个事件绑定函数(ele:DOM对象,e:事件名称,callback:事件处理函数):

window.onload = function(){
    var demo = document.getElementById("demo");
    addEvent(demo,"click",function(){console.log("兼容测试")});
    function addEvent(ele,e,callback){
        ele.addEventListener?ele.addEventListener(e,callback,false):ele.attachEvent("on"+e,callback);
    }
}

  也可扩展Element的原型函数:

window.onload = function(){
    var demo = document.getElementById("demo");
    demo.addEventListener("click",function(){console.log("handler test")},false);
}
Element.prototype.addEventListener = Element.prototype.addEventListener || function(e,cb){
    this.attachEvent("on"+e,cb)
}

取消事件绑定

  如果我们绑定事件函数之后想取消事件函数的绑定,实现起来也很简单,如果我们使用的是JavaScript的事件绑定方式,直接给事件处理函数设置为null即可:

window.onload = function(){
    var demo = document.getElementById("demo");
    demo.onclick = function(){
        console.log("11111")
    }
    demo.onclick = null;
}

  如果我们使用事件监听函数绑定的事件可以调用取消绑定的API每一种绑定方式都有它对应的解绑方式:

  addEventListener绑定的监听函数用removeEventListener来解除绑定,该函数接同样收三个参数第一个参数表示事件名称,第二个参数表示事件函数的名称,第三个参数是一个布尔值表示冒泡阶段或者捕获阶段。如果绑定事件函数时第二个参数是一个匿名函数表达式的话是不能解除绑定的,只有第二参数是一个以声明的函数的名称才可以使用removeEventListener来解除绑定。下面的这段代码的事件处理函数是不能解除绑定的:

window.onload = function(){
    var demo = document.getElementById("demo");
    demo.addEventListener("click",function(){console.log("aaaa")},false);
}

  要想移除事件处理函数必须使用函数声明:

window.onload = function(){
    var demo = document.getElementById("demo");
    demo.addEventListener("click",handler,false);
    demo.removeEventListener("click",handler);
    function handler(){
        console.log("aaaa");
    }
}

  attachEvent绑定的监听函数要使用detachEvent来解除绑定使用方式和addEventListener基本一致,不同点就是IE浏览器只支持事件冒泡所以省略了第三个参数,事件名称要加上on使用方式为:

window.onload = function(){
    var demo = document.getElementById("demo");
    demo.attachEvent("onclick",handler);
    demo.detachEvent("onclick",handler);
    function handler(){
        console.log("aaaa");
    }
}

访问事件对象

  在事件处理函数中,存在一个对象记录着事件的各种信息,这个对象只存在于事件函数执行的过程中,我们可以在事件处理函数中使用一个参数来代理事件对象,在非IE浏览器中我们可以直接使用参数作为事件对象,在IE浏览器中我们需要使用window.event来获取事件对象,使用方式如下:

window.onload = function(){
    var demo = document.getElementById("demo");
    demo.onclick = function(e){//事件处理函数是由浏览器来调用的,在调用时会把事件对象作为参数传递给事件处理函数
        var e = e || window.event;
        console.log(e);
    }
}

  我们在事件处理函数中如果需要阻止默认事件和停止冒泡就需要用到事件对象。

  在非IE浏览器中:

e.preventDefault();//阻止默认行为
e.stopPropagation();//停止冒泡

  在IE浏览器中:

e.returnValue = false;//阻止默认行为
e.cancelBubble = true;//停止冒泡

  欢迎关注我的公众号互相交流:

奥门威尼斯网址 2

发表评论

电子邮件地址不会被公开。 必填项已用*标注