易被忽视的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 相关文章推荐
Convert Seconds To Hours
Jun 16 Javascript
JavaScript类和继承 constructor属性
Mar 04 Javascript
深入探究JavaScript中for循环的效率问题及相关优化
Mar 13 Javascript
如何理解jQuery中的ajaxSubmit方法
Mar 13 Javascript
详解用node.js实现简单的反向代理
Jun 26 Javascript
vue微信分享出来的链接点开是首页问题的解决方法
Nov 28 Javascript
jQuery内容选择器与表单选择器实例分析
Jun 28 jQuery
vue 兄弟组件的信息传递的方法实例详解
Aug 30 Javascript
webpack 如何解析代码模块路径的实现
Sep 04 Javascript
Layer UI表格列日期格式化及取消自动填充日期的实现方法
May 10 Javascript
vue2和vue3的v-if与v-for优先级对比学习
Oct 10 Javascript
实现一个简单得数据响应系统
Nov 11 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
初学CAKEPHP 基础教程
2009/11/02 PHP
URL编码转换,escape() encodeURI() encodeURIComponent()
2006/12/27 Javascript
javascript调试说明
2010/06/07 Javascript
firefox下input type=&quot;file&quot;的size是多大
2011/10/24 Javascript
JQuery的自定义事件代码,触发,绑定简单实例
2013/08/01 Javascript
jquery中的常用事件bind、hover、toggle等示例介绍
2014/07/21 Javascript
jQuery validate+artdialog+jquery form实现弹出表单思路详解
2016/04/18 Javascript
js原生实现FastClick事件的实例
2016/11/20 Javascript
bootstrap手风琴折叠示例代码分享
2017/05/22 Javascript
详解Angular 自定义结构指令
2017/06/21 Javascript
Js中async/await的执行顺序详解
2017/09/22 Javascript
微信小程序 确认框的实现(附代码)
2019/07/23 Javascript
如何在Vue.JS中使用图标组件
2020/08/04 Javascript
详解JavaScript 高阶函数
2020/09/14 Javascript
使用python Django做网页
2013/11/04 Python
一篇文章入门Python生态系统(Python新手入门指导)
2015/12/11 Python
利用python代码写的12306订票代码
2015/12/20 Python
Python 数据结构之堆栈实例代码
2017/01/22 Python
python通过opencv实现批量剪切图片
2017/11/13 Python
python爬取拉勾网职位数据的方法
2018/01/24 Python
python3.x实现发送邮件功能
2018/05/22 Python
详解Python3 对象组合zip()和回退方式*zip
2019/05/15 Python
Python 类属性与实例属性,类对象与实例对象用法分析
2019/09/20 Python
Pyinstaller 打包发布经验总结
2020/06/02 Python
Python自省及反射原理实例详解
2020/07/06 Python
Python调用jar包方法实现过程解析
2020/08/11 Python
米兰必去买手店排行榜首位:Antonioli
2016/09/11 全球购物
荷兰家电销售网站:Welhof
2020/12/08 全球购物
大学军训感言800字
2014/02/27 职场文书
安全负责人任命书
2014/06/06 职场文书
2014优秀党员事迹材料
2014/08/14 职场文书
2014年班主任德育工作总结
2014/12/05 职场文书
2014年语文教师工作总结
2014/12/18 职场文书
2015年简历自我评价范文
2015/03/11 职场文书
婚礼家长致辞
2015/07/27 职场文书
浅谈怎么给Python添加类型标注
2021/06/08 Python