js中最容易被忽视的事件问题大总结


Posted in Javascript onMay 15, 2016

什么叫跨平台事件?即在不同的浏览器上执行同一事件,所使用的方法不同。

什么是EventUtil对象?有什么作用?即将所有与事件相关的函数,融合在一起的一个容器,方便管理事件对象,它没有属性。主要处理DOM事件和IE事件的磨合,使其尽可能的相似。

下面我们来看一下DOM和IE之间的对象属性和方法做个对比(这里只指出两者之间不同的属性和方法),主要有以下五大点:

DOM属性和方法 IE属性和方法
charcode keycode
preventDefault returnValue=false
relatedTarget fromobj|toobj
stopPropation cancelBuble=true
target srcobj
   

我们用一个小demo看一下,能够很好的解决事件跨平台的兼容问题:

<html>
<head>
  <title>eventUtil</title>
  <script eventType="text/javascript">
    var eventUtil = {
      //监听事件
      addListener: function(obj, eventType, fn) {
        if (obj.addEventListener) {
          obj.addEventListener(eventType, fn, false);
        } else if (obj.attachEvent) {
          obj.attachEvent('on' + eventType, fn);
        } else {
          obj['on' + eventType] = fn;
        }
      },
      //返回event对象
      getEvent: function(event) {
        return event || window.event;
        //return event ? event : window.event;
      },
      //返回目标事件对象
      getTarget: function(event) {
        return event.target || event.srcobj;
      },
      preventDefault: function(event) {
        if (event.preventDefault) {
          event.preventDefault();
        } else {
          event.returnValue = false;
        }
      },     
      removeListener: function(obj, eventType, fn) {
        if (obj.removeEventListener) {
          obj.removeEventListener(eventType, fn, false);
        } else if (obj.deattachEvent) {
          obj.detachEvent(eventType, fn);
        } else {
          obj['on' + eventType] = null;
        }
      },
      
      stopPropagation: function(event) {
        if (event.stopPropagation) {
          event.stopPropagation();
        } else {
          event.cancelBubble = true;
        }
      }
    };
  </script>
</head>
<body>
  <input eventType="button" value="click me" id="btn" />
  <p>event</p>
  <a>Hello word!</a>
  <script eventType="text/javascript">
  function addBtnListen(event)
  {
    var event = eventUtil.getEvent(event);
    var target = eventUtil.getTarget(event);
    alert("my name is kock");
    alert(event.eventType);
    alert(target);
    eventUtil.stopPropagation(event);

  }
  function getBodyListen(event)
  {
      alert("click body");
  }
  function getLinkListen(event)
  {
       alert("prevent default event");
       var event = eventUtil.getEvent(event);
       eventUtil.preventDefault(event);
  }
  window.onload=function()
  {
      var btn = document.getobjById("btn");
      var link = document.getobjsByTagName("a")[0];
      eventUtil.addListener(btn, "click", addBtnListen);
      eventUtil.addListener(document.body, "click", getBodyListen);
      eventUtil.addListener(link, "click",getLinkListen);
  }   
</script>
</body>
</html>

上面的方法能够解决事件跨平台问题,接下来,我们看下charCode的属性。

首先给eventUtil定义一个新方法,formatEvent,接受一个参数,即Event对象。

eventUtil.formatEvent=function(event)
{
  if(isIE&&isWin)
  {
   event.charCode=(event.type=="keypress")?event.keycode:0;
   event.eventphase=2;--表示冒泡阶段,IE仅支持冒泡阶段
  }
  return event;
}

二:关于冒泡中的target和currentTarget

target在事件流的目标阶段;currentTarget在事件流的捕获,目标及冒泡阶段。只有当事件流处在目标阶段的时候,两个的指向才是一样的, 而当处于捕获和冒泡阶段的时候,target指向被单击的对象而currentTarget指向当前事件的父级。

<div id="outer" style="background:#099"> 
      <p>我是目标div</p>  ----点击这部分,输出:e.target.tagName : P || e.currentTarget.tagName : DIV      <p id="inner" style="background:#9C0">我是目标p</p> ----点击这部分,输出:e.target.tagName : P || e.currentTarget.tagName : DIV

      <br> ----点击这部分,输出:e.target.tagName : DIV || e.currentTarget.tagName : DIV

</div>

//看下第二个变列:
<div id="outer" style="background:#099"> 
      <div>我是目标div</div>  ----点击这部分,输出:e.target.tagName : DIV || e.currentTarget.tagName : DIV      <p id="inner" style="background:#9C0">我是目标p</p> ----点击这部分,输出:e.target.tagName : P || e.currentTarget.tagName : DIV

      <br> ----点击这部分,输出:e.target.tagName : DIV || e.currentTarget.tagName : DIV

</div>
function getObj(id)
{ 
  return document.getElementById(id);   
} 
function addEvent(obj, event, fn)
{ 
  if(window.attachEvent)
  { 
   obj.attachEvent("on" + event, fn); 
  }
  else if(window.addEventListener)
  {  
   obj.addEventListener(event, fn, false); 
  } 
} 
function test(e)
{ 
  alert("e.target.tagName : " + e.target.tagName + "\n e.currentTarget.tagName : " + e.currentTarget.tagName); 
 } 
   var outer = getObj("outer"); 
   var inner = getObj("inner"); 
   //addEvent(inner, "click", test); 
   addEvent(outer, "click", test);

三:IE和DOM区别

DOM IE
获取目标 event.target event.srcElement
获取字符代码 event.charCode event.keyCode
阻止默认行为 event.prevetDefault() event.returnvalue=false
冒泡 event.stopPropagation() event.cancelBubble=true

 关于阻止默认行为,比如,当用户右击鼠标时,如果你不想菜单弹出,则可以使用阻止默认行为:

document.body.oncontextmenu=function(event)
{
  if(isIE)
  {
     var oEvent=window.event;
     oEvent.returnValue=false; //也可以直接是return false;阻止默认行为
  }
  else
  {
    oEvent.preventDefault();
  }
}

四:鼠标事件

<p>use your mouse to click and double click the red square</p>
<div style="width:100px;height:100px;background:red"
    onmouseover="handleEvent(event)"
    onmouseout="handleEvent(event)"
    onmousedown="handleEvent(event)" 
    onmouseup="handleEvent(event)"  
    onclick="handleEvent(event)" 
    ondblclick="handleEvent(event)" id="div1"
   >       
</div>
<p><textarea id="txt1" rows="5" cols="45"></textarea></p>
<!--检测键盘事件-->
<p><input type="text" id="textbox" 
      onkeydown="handle(event)"
      onkeypress="handle(event)"
      onkeyup="handle(event)"
     ></p>
<p><textarea id="txt2" rows="10" cols="45"></textarea></p>

js文件如下:

function handleEvent(event)
{
  var oText=document.getElementById('txt1');
  oText.value+= "\n"+event.type;
  oText.value+= "\n target is "+(event.srcElement||event.target).id;
  oText.value+="\n at ("+event.clientX+","+event.clientY+")in the client";
  oText.value+="\n at ("+event.screenX+","+event.screenY+")in the client";
  oText.value+="\n button down is"+event.button;
  var arrKeys=[];
  oText.value+="\n relatedTarget is"+event.relatedTarget.tagName;
  //event.relatedTarget.tagName可以判断鼠标的来源和出处
}
function handle(event)
{
  var oText2=document.getElementById('txt2');
  oText2.value+="\n"+event.type;
  var arrKeys=[];
 if(event.shiftKey){arrKeys.push("Shift");}
 if(event.ctrlKey){arrKeys.push("Ctrl");}
 if(event.altKey){arrKeys.push("Alt");}
  oText2.value+="\n keydown is "+arrKeys;
}

以上这篇js中最容易被忽视的事件问题大总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery JSON的解析方式分享
Apr 05 Javascript
JQuery拖拽元素改变大小尺寸实现代码
Dec 10 Javascript
JQuery的read函数与js的onload不同方式实现
Mar 18 Javascript
完美解决AJAX跨域问题
Nov 01 Javascript
JavaScript 作用域链解析
Nov 13 Javascript
jquery判断至少有一个checkbox被选中的方法
Jun 05 Javascript
浅谈angularJS 作用域
Jul 05 Javascript
jQuery Easyui DataGrid点击某个单元格即进入编辑状态焦点移开后保存数据
Aug 15 Javascript
jQuery Ajax全解析
Feb 13 Javascript
如何使用Bootstrap创建表单
Mar 29 Javascript
vue todo-list组件发布到npm上的方法
Apr 04 Javascript
微信小程序仿抖音短视频切换效果的实例代码
Jun 24 Javascript
jquery点击改变class并toggle的实现代码
May 15 #Javascript
js停止冒泡和阻止浏览器默认行为的简单方法
May 15 #Javascript
浅析js绑定事件的常用方法
May 15 #Javascript
js添加事件的通用方法推荐
May 15 #Javascript
js阻止默认浏览器行为与冒泡行为的实现代码
May 15 #Javascript
JQuery validate插件Remote用法大全
May 15 #Javascript
js阻止浏览器默认行为触发的通用方法(推荐)
May 15 #Javascript
You might like
当海贼王变成JOJO风
2020/03/02 日漫
php 无限极分类
2008/03/27 PHP
基于flush()不能按顺序输出时的解决办法
2013/06/29 PHP
PHP将两个关联数组合并函数提高函数效率
2014/03/18 PHP
PHP小技巧之函数重载
2014/06/02 PHP
php die()与exit()的区别实例详解
2016/12/03 PHP
jquery 最简单的属性菜单
2009/10/08 Javascript
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
innerText和textContent对比及使用介绍
2013/02/27 Javascript
jQuery Form 页面表单提交的小例子
2013/11/15 Javascript
js使用Array.prototype.sort()对数组对象排序的方法
2015/01/28 Javascript
JS访问SWF的函数用法实例
2015/07/01 Javascript
黑帽seo劫持程序,js劫持搜索引擎代码
2015/09/15 Javascript
Javascript技术难点之apply,call与this之间的衔接
2015/12/04 Javascript
莱鸟介绍window.print()方法
2016/01/06 Javascript
JavaScript通过代码调用Flash显示的方法
2016/02/02 Javascript
XMLHttpRequest Level 2 使用指南
2016/08/26 Javascript
jQuery easyui刷新当前tabs的方法
2016/09/23 Javascript
r.js来合并压缩css文件的示例
2018/04/26 Javascript
记一次webpack3升级webpack4的踩坑经历
2018/06/12 Javascript
vue中eslintrc.js配置最详细介绍
2018/12/21 Javascript
12个提高JavaScript技能的概念(小结)
2019/05/09 Javascript
详解Python的Flask框架中的signals信号机制
2016/06/13 Python
Python 实现12306登录功能实例代码
2018/02/09 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
2018/06/09 Python
Linux下Python安装完成后使用pip命令的详细教程
2018/11/22 Python
pandas.DataFrame的pivot()和unstack()实现行转列
2019/07/06 Python
Numpy数组array和矩阵matrix转换方法
2019/08/05 Python
python正则爬取某段子网站前20页段子(request库)过程解析
2019/08/10 Python
Python基于Faker假数据构造库
2020/11/30 Python
宝宝满月酒主持词和仪式流程
2014/03/27 职场文书
商超业务员岗位职责
2015/02/13 职场文书
员工自我工作评价
2015/03/06 职场文书
妈妈再爱我一次观后感
2015/06/08 职场文书
大学毕业生自我鉴定范文
2019/06/21 职场文书
OpenCV-Python模板匹配人眼的实例
2021/06/08 Python