关于点击click事件以及事件绑定的方式

Javascript简单地为一个标签绑定事件写法(不单针对button标签):

<button onclick="click_fn()">clickbutton>
   <script>
      function click_fn(){
         console.log(this);
      }
   script>

另一种是用DOM Document对象来绑定事件:
(注:这种写法须先调用$(document).ready(fucntion(){//code…)来防止文档在未完全加载(就绪)之前就运行脚本)

   <script>
      $(document).ready(function(){//jquery写法
          //js写法:window.onload=function(){}
         document.getElementById("btn").onclick=function(){
            console.log(this);
         }
         document.getElementsByTagName("p")[0].onclick=function(){
         //getElementsByTagName获得的是一种类型的标签数组集合
         //你必须明确告诉onclick,你要绑定在第几个标签上
            console.log(this);
         }
      });
   script>
head>
<body>
   <p>this is a p tagp>
   <button id="btn">clickbutton>
body>

上面这种简单的绑定有个局限:
重复监听某一事件,后者会覆盖前者,而不会两者先后触发

   <script>
      $(document).ready(function(){
         document.getElementById("btn").onclick=function(){
            console.log("first click function");
         }
         //重写会覆盖原有function
         //点击只显示second click function
         document.getElementById("btn").onclick=function(){
            console.log("second click function");
         }
      });
   script>
head>
<body>
   <button id="btn">clickbutton>
body>

于是就有了addEventListener(event,function,useCapture):

  • 它允许给一个事件注册多个监听器
  • 它提供了一种更精细的手段控制事件监听器的触发阶段(可选择冒泡或捕获)
    • 事件冒泡:事件流从特定的目标到最不特定的事件目标(document对象)顺序触发
    • 事件捕获:事件从未精确的对象(document对象)开始触发
  • .它对任何DOM元素都是有效的,而不仅仅是HTML元素
  • 参数useCapture(使用捕获)为true时,使用事件捕获;为false时,使用事件冒泡(默认选项为false)
    • IE浏览器只支持事件冒泡,不支持W3C标准,因此它也不支持addEventListener,但它提供了另一个函数attachEvent(event,fucntion)
   <script>
      $(document).ready(function(){
         document.getElementById("btn").addEventListener("click",function(){
            console.log("first click function")
         },false);
         document.getElementById("btn").addEventListener("click",function(){
            console.log("second click function")
         },false);
      });
   script>
head>
<body>
   <button id="btn">clickbutton>
   //点击一次之后会先显示first click function,然后再显示second click function
body>

jQuery写法(作用同上面的addEventListener):

   <script>
      $(document).ready(function(){
         $("#btn").on("click",function(){
            console.log("first click function");
         });
         $("#btn").on("click",function(){
            console.log("second click function");
         });
      });
   script>
head>
<body>
   <button id="btn">clickbutton>
body>



以上的事件绑定方式都称为普通事件绑定
而还有一种绑定,叫委托事件绑定
先看一下一个代码例子:

   <script>
      $(document).ready(function(){
         $("button").on("click",function(){
            //动态在button后面加一个新的p标签
            $("

this is a new p tag.

"
).insertAfter("button"); }); $("p").on("click",function(){ console.log(this); }) });
script> head> <body> <div> <p>this is a p tag.p> <button id="btn">clickbutton> div> body>

结果:
关于点击click事件以及事件绑定的方式_第1张图片
这就是普通的事件绑定,它对动态增加的标签无法进行事件绑定


我们再来看看下面的代码

   <script>
      $(document).ready(function(){
         $("button").on("click",function(){
            //动态在button后面加一个新的p标签
            $("

this is a new p tag.

"
).insertAfter("button"); }); $("div").delegate("p","click",function(){ console.log(this); }); });
script> head> <body> <div> <p>this is a p tag.p> <button id="btn">clickbutton> div> body>

结果:
关于点击click事件以及事件绑定的方式_第2张图片
这就是委托事件绑定
$(selector).delegate(childSelector,event,data,function)
它是利用冒泡的原理,把事件加到父级上,触发执行效果。
什么意思呢?
当你点击一个新增的标签时,原始加载的DOM结构是没有这个新增标签的,就也就是事件监听是与原始DOM结点进行绑定的。
而你用delegate将要绑定的元素委托给其父元素,也就是当你点击新增元素时,其实响应的是其父元素(逐一向上冒泡,看哪个元素已经被绑定监听事件),而父元素会重新解析一下自己的DOM结构,这时候新增的元素标签就能被解析到了。

上面的delegate方法,我用原生的Javascript简单模拟一下:

   <script>
      $(document).ready(function(){
         $("button").on("click",function(){
            //动态在button后面加一个新的p标签
            $("

this is a new p tag.

"
).insertAfter("button"); }); //为父元素绑定监听事件 document.getElementsByTagName("div")[0].addEventListener("click",function(e){ //console.log(e.target.nodeName); if(e.target&&e.target.nodeName=="P"){ //若不限定e.target.nodeName, //则点击div内的所有对象都能触发该方法 //e.target指的是点击的对象 console.log(e.target); } }); });
script> head> <body> <div > <p>this is a p tag.p> <button id="btn">clickbutton> div> body>

jQuery1.9以前的版本用$(selector).live(event,data,function)对delegate()进行了封装,使得看似对新增元素依旧能够绑定成功。但这也使得程序员用得不明不白,我想这也是jQuery后来版本废弃它的原因。

jQuery现在的版本用$(selector).on(event,childSelector,data,function)就可以实现以上的各种功能。
如普通的事件绑定:

<script>
      $(document).ready(function(){
         $("button").on("click",function(){
            $("

this is a new p tag.

"
).insertAfter("button"); }); });
script>

对于这种普通的事件绑定,jQuery还提供一种简化版写法(其实就是封装):

   <script>
      $(document).ready(function(){
         $("button").click(function(){
            $("

this is a new p tag.

"
).insertAfter("button"); }); });
script>

而委托事件绑定的写法:

   <script>
      $(document).ready(function(){
         $("button").click(function(){
            $("

this is a new p tag.

"
).insertAfter("button"); }); //委托事件绑定 $("div").on("click","p",function(){ console(this); }); });
script>

参考资料:

  • 浅谈Jquery中的bind(),live(),delegate(),on()绑定事件方式
  • addEventListener和onclick的区别
  • JavaScript事件委托的技术原理探讨示例

你可能感兴趣的:(Javascript)