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

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

<button onclick="click_fn()">click</button>
   <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 tag</p>
   <button id="btn">click</button>
</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">click</button>
</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">click</button>
   //点击一次之后会先显示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">click</button>
</body>



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

   <script>
      $(document).ready(function(){
         $("button").on("click",function(){
            //动态在button后面加一个新的p标签
            $("<p>this is a new p tag.</p>").insertAfter("button");
         });

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

结果:
普通事件绑定
这就是普通的事件绑定,它对动态增加的标签无法进行事件绑定


我们再来看看下面的代码

   <script>
      $(document).ready(function(){
         $("button").on("click",function(){
            //动态在button后面加一个新的p标签
            $("<p>this is a new p tag.</p>").insertAfter("button");
         });

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

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

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

   <script>
      $(document).ready(function(){
         $("button").on("click",function(){
            //动态在button后面加一个新的p标签
            $("<p>this is a new p tag.</p>").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">click</button>
   </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(){
            $("<p>this is a new p tag.</p>").insertAfter("button");
         });
      });
</script>

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

   <script>
      $(document).ready(function(){
         $("button").click(function(){
            $("<p>this is a new p tag.</p>").insertAfter("button");
         });
      });
   </script>

而委托事件绑定的写法:

   <script>
      $(document).ready(function(){
         $("button").click(function(){
            $("<p>this is a new p tag.</p>").insertAfter("button");
         });
         //委托事件绑定
         $("div").on("click","p",function(){
            console(this);
         });
      });
   </script>

参考资料:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值