易被忽视的js事件问题总结


Posted in Javascript onMay 14, 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;
}

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
JS/jQuery实现默认显示部分文字点击按钮显示全部内容
May 13 Javascript
Jquery 切换不同图片示例代码
Dec 05 Javascript
js使用栈来实现10进制转8进制与取除数及余数
Jun 11 Javascript
js实现手机拍照上传功能
Jan 17 Javascript
xmlplus组件设计系列之文本框(TextBox)(3)
May 03 Javascript
详解使用Vue Router导航钩子与Vuex来实现后退状态保存
Sep 11 Javascript
微信页面弹出键盘后iframe内容变空白的解决方案
Sep 20 Javascript
Angularjs按需查询实例代码
Oct 30 Javascript
Vue 将后台传过来的带html字段的字符串转换为 HTML
Mar 29 Javascript
React组件内事件传参实现tab切换的示例代码
Jul 04 Javascript
使用JS实现动态时钟
Mar 12 Javascript
three.js 实现露珠滴落动画效果的示例代码
Mar 01 Javascript
jQuery防止重复绑定事件的解决方法
May 14 #Javascript
jQuery基于扩展简单实现倒计时功能的方法
May 14 #Javascript
jquery动态切换背景图片的简单实现方法
May 14 #Javascript
jQuery基于$.ajax设置移动端click超时处理方法
May 14 #Javascript
jQuery基于扩展实现的倒计时效果
May 14 #Javascript
Angularjs中UI Router的使用方法
May 14 #Javascript
两种js监听滚轮事件的实现方法
May 13 #Javascript
You might like
织梦sitemap地图实时推送给百度的教程
2015/08/03 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
2015/11/04 PHP
浅析Yii2 gridview实现批量删除教程
2016/04/22 PHP
Laravel重写用户登录简单示例
2016/10/08 PHP
laravel执行php artisan migrate报错的解决方法
2019/10/09 PHP
CSS+JS构建的图片查看器
2006/07/22 Javascript
javascript实现的动态添加表单元素input,button等(appendChild)
2007/11/24 Javascript
javascript十个最常用的自定义函数(中文版)
2009/09/07 Javascript
javascript 操作select下拉列表框的一点小经验
2010/03/20 Javascript
javascript判断非数字的简单例子
2013/07/18 Javascript
javascript自动改变文字大小和颜色的效果的小例子
2013/08/02 Javascript
JS实现拖动示例代码
2013/11/01 Javascript
快速学习jQuery插件 Cookie插件使用方法
2015/12/01 Javascript
jQuery+ajax的资源回收处理机制分析
2017/01/07 Javascript
如何写好你的JavaScript【推荐】
2017/03/02 Javascript
使用jQuery实现动态添加小广告
2017/07/11 jQuery
详解key在Vue列表渲染时究竟起到了什么作用
2019/04/20 Javascript
深入解析koa之中间件流程控制
2019/06/17 Javascript
JS中如何轻松遍历对象属性的方式总结
2019/08/06 Javascript
如何基于JS截获动态代码
2019/12/25 Javascript
Vue props中Object和Array设置默认值操作
2020/07/30 Javascript
[01:05:07]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第一场2月1日
2021/03/11 DOTA
Python学习之asyncore模块用法实例教程
2014/09/29 Python
Python实现获取某天是某个月中的第几周
2015/02/11 Python
python监控网站运行异常并发送邮件的方法
2015/03/13 Python
Python语言描述KNN算法与Kd树
2017/12/13 Python
解决python3 安装完Pycurl在import pycurl时报错的问题
2018/10/15 Python
Python3.5 Json与pickle实现数据序列化与反序列化操作示例
2019/04/29 Python
python global和nonlocal用法解析
2020/02/03 Python
浅谈图像处理中掩膜(mask)的意义
2020/02/19 Python
Chicco婴儿用品美国官网:汽车座椅、婴儿推车、高脚椅等
2018/11/05 全球购物
升职自荐信范文
2013/10/05 职场文书
旅行社优秀创业计划书
2014/08/16 职场文书
2019年聘任书的写作格式及范文!
2019/07/03 职场文书
《时代广场的蟋蟀》读后感:真挚友情,温暖世界!
2020/01/08 职场文书
JavaScript 语句之常用 for 循环详解
2021/03/29 Javascript