Javascript添加监听与删除监听用法详解

本文实例讲述了Javascript添加监听与删除监听的用法。分享给大家供大家参考。具体分析如下:

js中事件监听就是利用addEventListener来绑定一个事件,这个用法在jquery中非常常用并且简单,但在原生js中比较复杂,这里整理了addEventListener事件各方法的测试与例子供大家参考学习。

在前两天做播放器的时候添加监听后删除监听遇到了一点麻烦,删不掉,后来看了一下才发现,参数需要完全对应,什么叫完全对应呢,换句话说:

代码如下:

$('.video')[0].addEventListener('timeupdate', currentTimeHandler, true);

比如这句,需要传入三个参数,这样才能够删除,为什么一定要这样,没错,蛋疼的地方就在这里:
在add和remove时,第三个参数确实可以不写,但此时他们的默认情况是不一样的!!

通常情况下addEventListener是false…
1、 添加自定义事件监听


代码如下:

var eventHandlesCounter=1;//统计添加事件监听的个数,0作为预留位
    function addEvent(obj,evt,fn){
       if(!fn.__EventID){ fn.__EventID=eventHandlesCounter++;}
       if(!obj.__EventHandles){ obj.__EventHandles=[]; }
       if(!obj.__EventHandles[evt]){
           obj.__EventHandles[evt]=[];
           if(obj["on"+evt] instanceof Function){
              obj.__EventHandles[evt][0]=obj["on"+evt];
              obj["on"+evt]=handleEvents;
           }
       }
       obj.__EventHandles[evt][fn.__EventID]=fn;
 
       function handleEvents(){
         var fns = obj.__EventHandles[evt];
         for (var i=0;i<fns.length;i++)
            fns[i].call(this);
       }
}

2、自定义删除事件监听


代码如下:

function delEvent(obj,evt,fn){
   if(!obj.__EventHandles || !obj.__EventHandles[evt] || !fn.__EventID){
      return false;
   }
   if(obj.__EventHandles[evt][fn.__EventID]==fn){
      delete obj.__EventHandles[evt][fn.__EventID];
   }
}

3. 对上述方法进行修正


代码如下:

function addEvent(obj,evt,fn,useCapture){
    if(obj.addEventListener){//优先使用W3C事件注册
       obj.addEventListener(evt,fn,!!useCapture);
    }else{
       if(!fn.__EventID){fn.__EventID = addEvent.__EventHandlesCounter++;}
       if(!obj.__EventHandles){ obj.__EventHandles=[];}
       if(!obj.__EventHandles[evt]){
           obj.__EventHandles[evt]=[];
           if(obj["on"+evt]){
              (obj.__EventHandles[evtype][0]=obj["on"+evtype]).__EventID=0;
           }
           obj["on"+evtype]=addEvent.execEventHandles;
       }
    }
}
addEvent.__EventHandlesCounter=1;
addEvent.execEventHandles = function(evt){
    if(!this.__EventHandles) {return true;}
    evt = evt || window.event;
    var fns = this.__EventHandles[evt.type];
    for (var i=0;i<fns.length;i++){
       if(fns[i] instanceof Function){
           fns[i].call(this);
       }
    }
};
function delEvent(obj,evt,fn,useCapture){
   if (obj.removeEventListener) {//先使用W3C的方法移除事件处理函数        
       obj.removeEventListener(evt,fn,!!useCapture);
   }else {
      if(obj.__EventHandles){
         var fns = obj.__EventHandles[evt];
         if(fns){delete fns[fn.__EventID];}
      }
}

4、标准化事件对象


代码如下:

function fixEvent(evt){
   if(!evt.target){
      evt.target = evt.srcElement;
      evt.preventDefault=fixEvent.preventDefault;
      evt.stopPropagation = fixEvent.stopPropagation;
      if(evt.type == "mouseover"){
         evt.relatedTarget = evt.fromElement;
      }else if(evt.type == "mouseout"){
         evt.relatedTarget = evt.toElement;
      }
      evt.charCode =(evt.type == "keypress")?evt.keyCode:0;
      evt.eventPhase = 2;
      evt.timeStamp = (new Date()).getTime();
   }
return evt;
}
fixEvent.preventDefault=function(){ this.returnValue=false;}
fixEvent.stopPropagation=function(){this.cancelBubble = true;};

fixEvent函数不是单独执行的,它必须有一个事件对象参数,而且只有事件发生时它才被执行!最好的方法是把它整合到addEvent函数的execEventHandles里面。

代码如下:

addEvent.execEventHandles = function (evt) {//遍历所有的事件处理函数并执行
if (!this.__EventHandles) {return true;}
evt = fixEvent(evt || window.event);//在这里对其进行标准化操作
var fns = this.__EventHandles[evt.type];
for (var i=0;i< fns.length;i++) {
if (fns[i] instanceof Function) {
fns[i].call(this,evt);//并且将其作为事件处理函数的第一个参数
//这样在事件处理函数内部就可以使用统一的方法访问事件对象了 } } };

上面是高手写了,下面整理几个实际的监听事情的例子

代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>test6.html</title>
 <script type="text/javascript">
  function test(){
   window.alert("您投了一次票");
   document.getElementById("1").detachEvent("onclick",test);
  }
 </script>
  </head>
 
  <body>
    <input type="button" value="投票" id="1"/>
    <script type="text/javascript">
     document.getElementById("1").attachEvent("onclick",test);
    </script>
  </body>
</html>

这里使用document.getElementById("1").attachEvent("onclick",test);进行动态的事件绑定,使用

代码如下:

document.getElementById("1").detachEvent("onclick",test)

进行动态的时间的取消,这样就实现了这个事件只能相应一次,下次再点击这个按钮的时候就不会再产生什么效果。
下面再演示一个时时监听键盘事件,判断输入的是否是数字,如果不是数字直接动态提示,然后拒绝其输入

代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>test7.html</title>
 <script type="text/javascript">
  function test(event){
   //用户每按下一个按键,就去判断是不是数字
   if(event.keyCode<48 || event.keyCode > 57){
    window.alert("您输入的不是一个数字");
    return false;
   }
  }
 </script>
  </head>
 
  <body>
    <input type="text" onkeypress="return test(event);" />请输入数字
  </body>
</html>

这里的event就是一个事件对象,他能返回很多的信息,具体请参考相关文档。
 
补充:事件监听方面的兼容

1. IE使用attachEvent/detachEvent方法来添加和删除事件监听器;w3c使用addEventListener/removeEventListener方法。
2. IE对其事件使用onevent的命名方式,而w3c的是event的命名方式。
3. IE事件监听器内使用的是一个全局的Event对象,而w3c是将event对象作为参数传递给监听器。
4. 为了避免触发默认的事件行为,IE的做法是要求程序员设置Event对象中的returnValue属性值为false,而w3c的做法是执行preventDefault方法。
5. IE没有提供对事件捕获阶段的支持。
6. 要停止事件的传递,IE的做法是设置event对象的cancelBubble为true,而w3c的做法是设置执行stopPropagation方法。
7. IE将事件监听器当做一个独立的函数来调用,而w3c中它是作为对象的方法来调用的,这表示在ie中事件监听器中的this关键字指向的不是事件发生对象而是一个没用的全局对象(window对象)。
8. IE在使用事件监听器方面存在内存泄露问题。在IE浏览器中,如果要为某个元素创建一个事件监听器,并且在监听器中使用该元素,则在用户进入其他页面之前,该监听器以及相关的DOM节点作占据的内存空间不会被释放。

希望本文所述对大家的javascript程序设计有所帮助。

(0)

相关推荐

  • javascript下过滤数组重复值的代码

    <script language="javascript">    function getNoRepeat() {        return arguments[0].join('|').match(/(\b[^|]+\b)(?!.*|\1\b)/ig);    }    var tmpArr = [1, 'a', 'ab', 'abc', 'd', 1.2, 'a+b', 'd', 'e', 5, 'a', 1, 'h', 'c', 'ab'];    var ret

  • 有道JavaScript监听浏览器的问题

    但不知道大家有没遇到这样一种情况,新开的窗口是通过<a href="" />打开 的,而不是window.opener或showModalDialog打开的. 尤其是需要注意的是:这个href指向的地址(页面)不是我们开发的,譬如,我们将href指向www.cnblogs.com. OK,问题来了:假如我们在a 所在的页面有个按钮,可以触发点击事件并进行一些操作. 而这个点击事件需要在href打开的IE窗口关闭后触发... 这个时候,我们如何监视href打开的窗口呢?(通过

  • JavaScript监听和禁用浏览器回车事件实例

    js监听浏览器回车事件,可以支持ie6+,火狐,谷歌等浏览器. 复制代码 代码如下: <html> <head> <script type="text/javascript"> //注册键盘事件 document.onkeydown = function(e) {  //捕捉回车事件  var ev = (typeof event!= 'undefined') ? window.event : e;  if(ev.keyCode == 13) {  

  • 在JavaScript中监听IME键盘输入事件

    输入法应当如何触发键盘事件呢?是每一下击键都触发一次事件,还是选词完毕才触发事件呢?整句输入又该如何触发事件呢?不同的操作系统和不同的浏览器对此有不同的看法.在最糟糕的情况下,用户使用输入法后浏览器就只触发一次 keydown ,之后就没有任何的键盘事件了.这对于 Suggestion 控件的实现来说是个大问题,因为 Suggestion 控件需要监听文本输入框的变化,而事件是最准确也最节省计算资源的做法,如果换成轮询的话性能就可能受到影响. 首先,要监听启用输入法后的击键事件应当使用 keyd

  • javascript监听鼠标滚轮事件浅析

    我们都见到过这些效果,用鼠标滚轮实现某个表单内的数字增加减少操作,或者滚轮控制某个按钮的左右,上下滚动.这些都是通过js对鼠标滚轮的事件监听来实现的.今天这里介绍的是一点简单的js对于鼠标滚轮事件的监听. 不同浏览器不同的事件 首先,不同的浏览器有不同的滚轮事件.主要是有两种,onmousewheel(firefox不支持)和DOMMouseScroll(只有firefox支持),关于这两个事件这里不做详述,想要了解的朋友请移步:鼠标滚轮(mousewheel)和DOMMouseScroll事件

  • JavaScript监听文本框回车事件并过滤文本框空格的方法

    本文实例讲述了JavaScript监听文本框回车事件并过滤文本框空格的方法.分享给大家供大家参考.具体如下: <script type="text/javascript" language="javascript"> var username = null; var password = null; //获取文本框 onload = function() { username = document.getElementById("txtUser

  • javascript在事件监听方面的兼容性小结

    1,IE使用attachEvent/detachEvent方法来添加和删除事件监听器:w3c使用addEventListener/removeEventListener方法. 2,IE对其事件使用onevent的命名方式,而w3c的是event的命名方式. 3,IE事件监听器内使用的是一个全局的Event对象,而w3c是将event对象作为参数传递给监听器. 4,为了避免触发默认的事件行为,IE的做法是要求程序员设置Event对象中的returnValue属性值为false,而w3c的做法是执行

  • javascript过滤危险脚本方法

    下面是他们的字符串规则: 1.<(script|link|style|iframe)(.|\n)*<\/\1>\s* 2.\s*on[a-z]+\s*=\s*("[^"]+"|'[^']+'|[^\s]+)\s*(?=>) 3.\s*(href|src)\s*=\s*("\s*(javascript|vbscript):[^"]+"|'\s*(javascript|vbscript):[^']+'|(javascript|

  • JavaScript对象字面量和构造函数原理与用法详解

    本文实例讲述了JavaScript对象字面量和构造函数.分享给大家供大家参考,具体如下: 对象中只有两种属性:(一种比较细的分法) 属性(数据属性)比如:名字,年龄,性别,出版社,地址等信息: 方法(封装代码的属性:函数 ,在这也是一种属性). 在JS中对象的字面量和构造函数是非常的重点,其实在其他的语言中,是没有对象字面量的. 一.对象的字面量的语法: { 属性名: 属性值, 属性名: 属性值, 方法名: 你们函数 } 这个大括号括起来的整个代码块就是叫做对象. var p1 = { } ①访

  • JavaScript的DOM与BOM的区别与用法详解

    目录 1. 简述:何为DOM,何为BOM? 2. DOM及其相关操作 2.1DOM树 2.2DOM的一些常见的操作元素方法 获取节点的DOM方法 获取/设置元素的属性值的DOM方法 创建节点(Node)的DOM方法 增添节点的DOM方法 删除节点的DOM方法 DOM常见的一些属性 3. BOM及其相关操作 3.1 BOM总述 3.2 BOM常见对象的介绍 window对象 location对象 history对象 navigator对象 总结 1. 简述:何为DOM,何为BOM? 在文章开始之初

  • JavaScript封装的常用工具类库bee.js用法详解【经典类库】

    本文实例讲述了JavaScript封装的常用工具类库bee.js.分享给大家供大家参考,具体如下: bee.js下载地址: github下载地址:https://github.com/shadowOfCode/bee.js 或点击此处本站下载. 使用: <!--area.js存放区域编码的一个常量.由于bee.js里面的getPersonInfo18()方法需要调用这个常量,所以在bee.js之前引入.如果不需要用到这个方法也可以不引入area.js--> <script type=&q

  • JavaScript进阶(三)闭包原理与用法详解

    本文实例讲述了JavaScript闭包原理与用法.分享给大家供大家参考,具体如下: 为了更好的理解,在阅读此文之前建议先阅读上一篇<JavaScript词法作用域与作用域链> 1.什么是闭包 闭包的含义就是闭合,包起来,简单的来说,就是一个具有封闭功能与包裹功能的结构.所谓的闭包就是一个具有封闭的对外不公开的,包裹结构,或空间. 在JS中函数构成闭包.一般函数是一个代码结构的封闭结构,即包裹的特性,同时根据作用域规则只允许函数访问外部的数据,外部无法访问函数内部的数据,即封闭的对外不公开的特性

  • Javascript添加监听与删除监听用法详解

    本文实例讲述了Javascript添加监听与删除监听的用法.分享给大家供大家参考.具体分析如下: js中事件监听就是利用addEventListener来绑定一个事件,这个用法在jquery中非常常用并且简单,但在原生js中比较复杂,这里整理了addEventListener事件各方法的测试与例子供大家参考学习. 在前两天做播放器的时候添加监听后删除监听遇到了一点麻烦,删不掉,后来看了一下才发现,参数需要完全对应,什么叫完全对应呢,换句话说: 复制代码 代码如下: $('.video')[0].

  • Angular中使用$watch监听object属性值的变化(详解)

    Angular中的$watch可以监听属性值的变化,然后并做出相应处理. 常见用法: $scope.$watch("person", function(n, o){ //todo something... }) 但是对于一个对象中的某个属性值变化时,$watch似乎不管用了. 示例代码: <body> <div ng-controller="mainCtrl"> <input id="myText" type=&qu

  • npm script 的文件监听和自动刷新的命令详解

    文件监听的作用是为了实现自动化,释放双手和精力,提高效率,让开发者更加关注于开发.npm script 文件监听和 grunt.gulp 功能类似. 自动刷新,意思就是改动文件保存后,页面自动刷新,减少日常开发的操作. 代码检查的监听和自动化 代码检查工具 stylelint.eslint.jsonlint 这些对 watch 支持很弱,所以就需要引入工具包 onchange 安装命令依赖包 npm i onchange -D // 或 yarn add onchange -D 编写命令 "sc

  • android studio按钮监听的5种方法实例详解

    1.匿名内部类 public class MainActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn1 = fin

  • Android 监听软键盘状态的实例详解

    Android 监听软键盘状态的实例详解 近日遇到要检测软键盘是否显示或隐藏的问题,搜了一下网上,最后找到一个很简单的,记录一下. activityRoot是activity的根view,就是xml里面的第一个view,给它设置一个id. final View activityRootView = findViewById(R.id.activityRoot); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(ne

  • 微信小程序 监听手势滑动切换页面实例详解

    微信小程序 监听手势滑动切换页面实例详解 1.对应的xml里写上手势开始.滑动.结束的监听: <view class="touch" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" ></view> 2.js: var touchDot = 0;//触摸时的原点 var time = 0;// 时

随机推荐