易被忽视的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 相关文章推荐
javascript 浏览器检测代码精简版
Mar 04 Javascript
Jquery取得iframe下内容的方法
Nov 18 Javascript
jquery toolbar与网页浮动工具条具体实现代码
Jan 12 Javascript
jQuery的图片滑块焦点图插件整理推荐
Dec 07 Javascript
js下拉选择框与输入框联动实现添加选中值到输入框的方法
Aug 17 Javascript
jQuery横向擦除焦点图特效代码分享
Sep 06 Javascript
用Vue.js实现监听属性的变化
Nov 17 Javascript
js实现旋转木马效果
Mar 17 Javascript
微信小程序倒计时功能实例代码
Jul 17 Javascript
浅谈Redux中间件的实践
Jul 27 Javascript
Vue实现左右菜单联动实现代码
Aug 12 Javascript
解决vue安装less报错Failed to compile with 1 errors的问题
Oct 22 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
《一拳超人》埼玉一拳下去,他们存在了800年毫无意义!
2020/03/02 日漫
Extended CHM PHP 语法手册之 DIY
2006/10/09 PHP
php empty函数 使用说明
2009/08/10 PHP
Thinkphp搜索时首页分页和搜索页保持条件分页的方法
2014/12/05 PHP
php构造函数的继承方法
2015/02/09 PHP
php实现用已经过去多长时间的方式显示时间
2015/06/05 PHP
使用PHP生成图片的缩略图的方法
2015/08/18 PHP
理解PHP中的Session及对Session有效期的控制
2016/01/08 PHP
CL vs ForZe BO5 第一场 2.13
2021/03/10 DOTA
jquery scroll()区分横向纵向滚动条的方法
2014/04/04 Javascript
Jquery的each里用return true或false代替break或continue
2014/05/21 Javascript
jQuery的context属性用法实例
2014/12/27 Javascript
JS模仿腾讯图片站的图片翻页按钮效果完整实例
2016/06/21 Javascript
JavaScript 网页中实现一个计算当年还剩多少时间的倒数计时程序
2017/01/25 Javascript
node.js中grunt和gulp的区别详解
2017/07/17 Javascript
微信小程序自定义模态对话框实例详解
2017/08/16 Javascript
基于vue组件实现猜数字游戏
2020/05/28 Javascript
vue路由导航守卫和请求拦截以及基于node的token认证的方法
2019/04/07 Javascript
详解vuex持久化插件解决浏览器刷新数据消失问题
2019/04/15 Javascript
vue cli使用融云实现聊天功能的实例代码
2019/04/19 Javascript
Vue配置marked链接添加target=&quot;_blank&quot;的方法
2019/07/19 Javascript
vue实现简单计算商品价格
2020/09/14 Javascript
如何使用七牛Python SDK写一个同步脚本及使用教程
2015/08/23 Python
python实现装饰器、描述符
2018/02/28 Python
Python使用Phantomjs截屏网页的方法
2018/05/17 Python
使用python实现快速搭建简易的FTP服务器
2018/09/12 Python
使用Python如何测试InnoDB与MyISAM的读写性能
2018/09/18 Python
pycharm中成功运行图片的配置教程
2018/10/28 Python
使用python接入微信聊天机器人
2020/03/31 Python
如何通过python画loss曲线的方法
2019/06/26 Python
彪马香港官方网上商店:PUMA香港
2020/12/06 全球购物
学生个人求职自荐信格式
2013/09/23 职场文书
大学生求职简历的自我评价
2013/10/21 职场文书
电气工程师岗位职责
2014/01/01 职场文书
协议书的格式
2014/04/23 职场文书
考试没考好检讨书
2015/05/06 职场文书