易被忽视的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的试卷自动排版系统实现代码
Jan 06 Javascript
JQuery判断子iframe何时加载完成解决方案
Aug 20 Javascript
node.js中的favicon.ico请求问题处理
Dec 15 Javascript
JavaScript列表框listbox全选和反选的实现方法
Mar 18 Javascript
前端性能优化及技巧
May 06 Javascript
vue2.0 中#$emit,$on的使用详解
Jun 07 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
Jun 28 Javascript
JavaScript实现创建自定义对象的常用方式总结
Jul 09 Javascript
Vue Autocomplete 自动完成功能简单示例
May 25 Javascript
浅析Angular 实现一个repeat指令的方法
Jul 21 Javascript
javascript实现fetch请求返回的统一拦截
Dec 22 Javascript
微信小程序中使用vant框架的具体步骤
Feb 18 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
PHP网页游戏学习之Xnova(ogame)源码解读(十五)
2014/06/30 PHP
php通过array_unshift函数添加多个变量到数组前端的方法
2015/03/18 PHP
php随机获取金山词霸每日一句的方法
2015/07/09 PHP
JSON两种结构之对象和数组的理解
2016/07/19 PHP
PHP实现微信支付(jsapi支付)流程步骤详解
2018/03/15 PHP
基于laravel Request的所有方法详解
2019/09/29 PHP
UI Events 用户界面事件
2012/06/27 Javascript
JavaScript的模块化:封装(闭包),继承(原型) 介绍
2013/07/22 Javascript
JS中typeof与instanceof之间的区别总结
2013/11/14 Javascript
JavaScript伸缩的菜单简单示例
2013/12/03 Javascript
常规表格多表头查询示例
2014/02/21 Javascript
javascript操作excel生成报表全攻略
2014/05/04 Javascript
Bootstrap每天必学之附加导航(Affix)插件
2016/04/25 Javascript
jQuery实现边框动态效果的实例代码
2016/09/23 Javascript
bootstrap table小案例
2016/10/21 Javascript
微信小程序之小豆瓣图书实例
2016/11/30 Javascript
nodejs读写json文件的简单方法(必看)
2017/03/09 NodeJs
微信小程序实现动态改变view标签宽度和高度的方法【附demo源码下载】
2017/12/05 Javascript
vue.js打包之后可能会遇到的坑!
2018/06/03 Javascript
Vue3项目打包后部署到服务器 请求不到后台接口解决方法
2020/02/06 Javascript
ES6中的类(Class)示例详解
2020/12/09 Javascript
Centos部署django服务nginx+uwsgi的方法
2019/01/02 Python
Python实现的矩阵转置与矩阵相乘运算示例
2019/03/26 Python
python循环定时中断执行某一段程序的实例
2019/06/29 Python
解决Django连接db遇到的问题
2019/08/29 Python
python GUI库图形界面开发之PyQt5输入对话框QInputDialog详细使用方法与实例
2020/02/27 Python
html5中svg canvas和图片之间相互转化思路代码
2014/01/24 HTML / CSS
澳大利亚最好的电动自行车:Leon Cycle
2020/12/19 全球购物
先进个人事迹材料
2014/01/25 职场文书
投标授权委托书范文
2014/08/02 职场文书
2016年圣诞节活动总结范文
2016/04/01 职场文书
什么是求职信?求职信应包含哪些内容?
2019/08/14 职场文书
使用springboot暴露oracle数据接口的问题
2021/05/07 Oracle
MySQL面试题讲解之如何设置Hash索引
2021/11/01 MySQL
PHP获取学生成绩的方法
2021/11/17 PHP
从结婚开始的恋爱故事。小说《我的美好婚事》TV动画化决定
2022/04/07 日漫