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轻松实现Ajax的实例代码
Aug 16 Javascript
javascript常用经典算法实例详解
Nov 25 Javascript
易操作的jQuery表单提示插件
Dec 01 Javascript
jQuery实现控制文字内容溢出用省略号(…)表示的方法
Feb 26 Javascript
jQuery焦点图轮播效果实现方法
Dec 19 Javascript
ES5学习教程之Array对象
Apr 01 Javascript
详解angularJs指令的3种绑定策略
Apr 13 Javascript
JS实现的邮箱提示补全效果示例
Jan 30 Javascript
微信小程序实现列表下拉刷新上拉加载
Jul 29 Javascript
基于vue 添加axios组件,解决post传参数为null的问题
Mar 05 Javascript
vue使用map代替Aarry数组循环遍历的方法
Apr 30 Javascript
JavaScript随机数的组合问题案例分析
May 16 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
多数据表共用一个页的新闻发布
2006/10/09 PHP
php+mysql开源XNA 聚合程序发布 下载
2007/07/13 PHP
探讨:php中在foreach中使用foreach ($arr as &amp;$value) 这种类型的解释
2013/06/24 PHP
php源码 fsockopen获取网页内容实例详解
2016/09/24 PHP
PHP实现RSA签名生成订单功能【支付宝示例】
2017/06/06 PHP
javascript 图片上一张下一张链接效果代码
2010/03/12 Javascript
CSS和Javascript简单复习资料
2010/06/29 Javascript
使用phantomjs进行网页抓取的实现代码
2014/09/29 Javascript
Jquery实现动态切换图片的方法
2015/05/18 Javascript
JavaScript中用getDate()方法返回指定日期的教程
2015/06/09 Javascript
js 动态添加元素(div、li、img等)及设置属性的方法
2016/07/19 Javascript
在微信、支付宝、百度钱包实现点击返回按钮关闭当前页面和窗口的方法
2016/08/05 Javascript
jQuery中get方法用法分析
2016/12/07 Javascript
js模仿微信朋友圈计算时间显示几天/几小时/几分钟/几秒之前
2017/04/27 Javascript
详解JavaScript中return的用法
2017/05/08 Javascript
详解webpack+angular2开发环境搭建
2017/06/28 Javascript
vue-ajax小封装实例
2017/09/18 Javascript
详解使用Next.js构建服务端渲染应用
2018/07/10 Javascript
手把手教你使用TypeScript开发Node.js应用
2019/05/06 Javascript
使用layui 的layedit定义自己的toolbar方法
2019/09/18 Javascript
[04:49]期待西雅图之战 2016国际邀请赛中国区预选赛WINGS战队赛后采访
2016/06/29 DOTA
Python基础篇之初识Python必看攻略
2016/06/23 Python
R vs. Python 数据分析中谁与争锋?
2017/10/18 Python
python基于socket函数实现端口扫描
2020/05/28 Python
世界上最受欢迎的钓鱼诱饵:Rapala
2019/05/02 全球购物
Tomcat Mysql datasource数据源配置
2015/12/28 面试题
销售简历自我评价
2014/01/24 职场文书
个人现实表现材料
2014/02/04 职场文书
应届生求职自荐信范文
2014/04/07 职场文书
派出所正风肃纪剖析材料
2014/10/10 职场文书
授权收款委托书范本
2014/10/10 职场文书
学校师德师风整改措施
2014/10/27 职场文书
党的群众路线教育实践活动个人整改落实情况汇报
2014/10/28 职场文书
2014年稽查工作总结
2014/12/20 职场文书
2015入党自传格式范文
2015/06/26 职场文书
mysql通过group by分组取最大时间对应数据的两种有效方法
2022/09/23 MySQL