易被忽视的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 相关文章推荐
JQUERY 对象与DOM对象之两者相互间的转换
Apr 27 Javascript
扩展Jquery插件处理mouseover时内部有子元素时发生样式闪烁
Dec 08 Javascript
javascript中打印当前的时间实现思路及代码
Dec 18 Javascript
js+css实现超简洁的二级下拉菜单效果代码
Sep 07 Javascript
javaScript之split与join的区别(详解)
Nov 08 Javascript
js断点调试心得分享(必看篇)
Dec 08 Javascript
angularJs 表格添加删除修改查询方法
Feb 27 Javascript
详解如何用babel转换es6的class语法
Apr 03 Javascript
安装Node.js并启动本地服务的操作教程
May 12 Javascript
javascript和php使用ajax通信传递JSON的实例
Aug 21 Javascript
vue主动刷新页面及列表数据删除后的刷新实例
Sep 16 Javascript
JQuery使用属性addClass、removeClass和toggleClass实现增加和删除类操作示例
Nov 18 jQuery
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
phpmyadmin操作流程
2006/10/09 PHP
NO3第三帝国留言簿制作过程
2006/10/09 PHP
比较简单的百度网盘文件直链PHP代码
2013/03/24 PHP
php中fsockopen用法实例
2015/01/05 PHP
php无限级分类实现评论及回复功能
2019/02/18 PHP
laravel-admin自动生成模块,及相关基础配置方法
2019/10/08 PHP
MooTools 页面滚动浮动层智能定位实现代码
2011/08/23 Javascript
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
2013/11/03 Javascript
AngularJS入门教程(零):引导程序
2014/12/06 Javascript
Ajax清除浏览器js、css、图片缓存的方法
2015/08/06 Javascript
jquery实现图片预加载
2015/12/25 Javascript
浅谈JavaScript中小数和大整数的精度丢失
2016/05/31 Javascript
AngularJS 模块详解及简单实例
2016/07/28 Javascript
jQuery实现产品对比功能附源码下载
2016/08/09 Javascript
百度地图JavascriptApi Marker平滑移动及车头指向行径方向
2017/03/13 Javascript
浅谈jquery中ajax跨域提交的时候会有2次请求的问题
2017/11/10 jQuery
基于滚动条位置判断的简单实例
2017/12/14 Javascript
关于react-router/react-router-dom v4 history不能访问问题的解决
2018/01/08 Javascript
Vue2.0实现调用摄像头进行拍照功能 exif.js实现图片上传功能
2018/04/28 Javascript
koa-router路由参数和前端路由的结合详解
2019/05/19 Javascript
使用vue for时为什么要key【推荐】
2019/07/11 Javascript
vue a标签点击实现赋值方式
2020/09/07 Javascript
python抓取网站的图片并下载到本地的方法
2018/05/22 Python
python实现简单聊天室功能 可以私聊
2019/07/12 Python
基于Django统计博客文章阅读量
2019/10/29 Python
python爬虫库scrapy简单使用实例详解
2020/02/10 Python
Python线程threading模块用法详解
2020/02/26 Python
html5本地存储之localstorage 、本地数据库、sessionStorage简单使用示例
2014/05/08 HTML / CSS
Ibatis如何使用动态表名
2015/07/12 面试题
教你怎样写好自我评价
2013/10/05 职场文书
成人大专自我鉴定范文
2013/10/19 职场文书
八荣八耻的活动方案
2014/08/16 职场文书
明星邀请函
2015/02/02 职场文书
小学数学教师研修感悟
2015/11/18 职场文书
2016学雷锋优秀志愿者事迹材料
2016/02/25 职场文书
Java Socket实现Redis客户端的详细说明
2021/05/26 Redis