事件检测
作者:手气不错 来源:gracecode.com 发布时间:2009-04-11 18:03:00
给浏览器绑定事件有时候是非常痛苦的事情,不同的浏览器提供不尽相同的功能的同时,也提供了不同的事件。例如,IE 系列的浏览器支持 mouseenter/mouseleave 事件;Opera 不支持 contextmenu 以及 input 相关的 onbeforepaste、onbeforecut 等事件。
浏览器之间不同程度的事件支持情况,会加重编写跨浏览器的开发成本。而在某种“无奈”的情况下(特别针对 IE),我们都会采用浏览器嗅探来决定绑定不同的事件,例如绑定鼠标滚轮事件:
if (Env.ua.ie) { Event.on(document, 'mousewheel', callback);} else { Event.on(document, 'DOMMouseScroll', callback);}
或者另外中做法就是干脆绑定两个事件。虽然这也能很正常的工作,但我们都了解,无论是基于浏览器嗅探还是重复绑定无用的事件,这都是不完美的解决方案。
Juriy Zaytsev 的代码给了我们解决这个问题的些启示,他利用 DOM 的特性,来判断针对某元素是否支持具体事件。例如
var el = document.createElement('div');el.setAttribute('onclick', 'return;');typeof el.onclick; // "function"el.setAttribute('onclick2', 'return;');typeof el.onclick2; // "undefined"
那么,根据这一特性,就可以编写出不依赖浏览器嗅探的事件检测脚本,原文的最终例子
var isEventSupported = (function() { // 根据特有的事件创建对应的 HTML 元素 var TAGNAMES = { 'select':'input','change':'input', 'submit':'form','reset':'form', 'error':'img','load':'img','abort':'img' } function isEventSupported(eventName) { var el = document.createElement(TAGNAMES[eventName] || 'div'); eventName = 'on' + eventName; // 检测元素是否已经包含了对应的事件 var isSupported = (eventName in el); // 如果没有对应事件,则尝试增加对应事件,然后判断是否为回调 if (!isSupported) { el.setAttribute(eventName, 'return;'); isSupported = typeof el[eventName] == 'function'; } el = null; return isSupported; } return isEventSupported;})();
那么,判断是否为 Opera 浏览器使用
isEventSupported("contextmenu")
就好过
navigator.userAgent.indexOf('Opera') > -1
而且,以后如果 Opera“修复”了该问题,由于 isEventSupported("contextmenu") 返回的是 true,从而也可保证代码健壮的运行。
最后,原文作者写了个简单的测试页面,用于检测具体浏览器的 DOM Level2 的支持情况。


猜你喜欢
- 今天在项目中向数据库的CLOB属性插入一段篇文章(1000~2000)字就会报一个字符串过长的错误。网上说用流来处理,没有这么做。这像是一个
- 本文实例讲述了Python实现字典排序、按照list中字典的某个key排序的方法。分享给大家供大家参考,具体如下:1.给字典按照value按
- python2.7yum install -y zlib zlib-devel openssl openssl-devel mysql-de
- super().__ init__ ()有什么用?super().__init__() 、 super(B,self).__init__()
- 在python3的sorted中去掉了cmp参数,转而推荐“key+lambda”的方式来排序。如果需要对python的list进行多级排序
- 1.安装anaconda(anaconda内置python在内的许多package,所以不用另外下载python)可以点击下面的清华开源软件
- 最近有朋友问js 如何打印预览,今天就来讲解一下,首先了解一下打印原理,其实局部打印页面很简单。就是把你需要打印的部分做一个起始标记,至于标
- 前言以前版本的 Celery 需要一个单独的库(django-celery)来与 Django 一起工作,但从 3.1 开始不再是这种情况。
- 基数排序法又称桶子法(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些"桶&
- 本文实例讲述了Python mutiprocessing多线程池pool操作。分享给大家供大家参考,具体如下:python — mutipr
- 起因修改了表结构以后执行python3 manage.py migrate 报错:django.db.utils.OperationalEr
- 方法在 Golang 中没有类,不过我们可以为结构体定义方法。我们看一个例子:package main import ( 
- 如果值没有重复的情况,可以先用array_flip()来交换键和值,然后krsort(),最后再array_flip()交换回来,就可以比较
- 由MySQL支持的列类型列在下面。下列代码字母用于描述中: M 指出最大的显示尺寸。最大的合法的显示尺寸是 255 。 D 适用于浮点类型并
- 1 简介在日常运行程序的过程中常常涉及到循环迭代过程,对于执行时间很短的程序来说倒无所谓,但对于运行过程有明显耗时的涉及循环迭代的程序,为其
- 本文实例讲述了php实现的日历程序。分享给大家供大家参考。具体如下:<?php /* * php 输出日历程序 */ header(&
- pycharm是一款高效的python IDE工具,它非常强大,且可以跨平台,是新手首选工具!下面我给第一次使用这款软件的朋友做一个简单的使
- 我想从文件读数据的话,要比直接从数据库快一些吧(个人观点),昨天测试了读出6000条新闻,读数据库用了23579毫秒,读文件只用了123毫秒
- 本节内容:1.前言2.相关概念3.Python中的默认编码4.Python2与Python3中对字符串的支持5.字符编码转换一、前言Pyth
- 思考一下下面的代码片段: def foo(numbers=[]): numbers.append(9) p