`
andysofan
  • 浏览: 12107 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类

检测浏览器对事件不同的处理方式

阅读更多
目前西方很多WEB开发工作者对浏览器的研究几乎达到一个狂热的程度,这归根到底还是源于jQuery搞出特性侦探这个属性。但是由于浏览器内核的不同,导致不同的浏览器对事件的处理方式是有区别的,比如在IE浏览器下是支持mouseenter与mouseleave,Opera支持右键菜单但不允许你用contextmenu类似的API操作它,还有onbeforepaste, onbeforecut这些与input元素相关的事件,IE浏览器与WebKit支持,但FF不支持。当然还有一些像“阻止事件冒泡”以及“取消浏览器默认行为”等,不同浏览器也有不同的处理方式,如果我们要使JavaScript在不同的浏览器下能正常处理事件代码,就要分别进行判断处理。而jQuery类库为我们提供了屏蔽浏览器的差异的办法。


jQuery是一种让开发和设计者在他们的网页中添加交互内容的工具,它的核心命令让你在网页中定位或创建对象并对之进行操作,它事实上是一种更容易使用的JavaScript,可以不必强迫页面刷新而对页面进行各种操作。

JavaScript为设计拓宽了视野,而jQuery让这一切变得更简单。对那些通晓CSS的设计师来说,编写jQuery代码很类似,而对于那些拥有Flash经验的设计师来说,jQuery是一种标准化的,开放的技术,它可以实现类似Flash的交互效果,让网页能够在浏览器中呈现更加多样化的效果。

在以前javascript与DOM遍地是bug,美工主宰前端的年代,人们只有两种极端方式,用户禁止脚本运行,浏览器商狂升级(IE6之前也很积极的)。这年头,也就Base2与Prototype2做得最好,当然dojo与YUI也不错。不过最近五年,Opera与Safari都建立了对DOM完整的支持后,世界分两半,一半是IE浏览器统治的混乱世界,它是拥有如此丰富的私有特征,CSS表达式,HTC,CSS滤镜,VML,userData,XML数据岛,最早的AJAX支持,以及DHTML最好的支持API(innerHTML,innerText,outerHTML,outerText,insertAdjactentXXX,offsetXXX,clientXXX,scrollXXX,Range,designMode,sertRow和insertCell等动态操作表格API……),难怪IE会赢的!不过IE也埋下了许多地雷,加之IE浏览器不会像其他游览器升级那么快,许多Bug都要我们亲手修正。这么多浏览器,这么多版本,特性侦探是很有必要。现在我们看到那一套关于事件的API,基本上是微软从桌面搬过来,后来W3C又加一大堆与DOM开头的事件,不过除了DOMMouseScroll基本没什么人用。N多事件,与逐个嗅探浏览器那样成了个头痛的问题。

一般我们可以用for…in循环把它遍历一下,或者像以下简单地检测:

‘onclick’ in document.documentElement; // true
‘onclick2′ in document.documentElement; // false
很不幸,这不准确,因为我们可以添加一些同名的自定义属性。有人说,赶在用户添加之前检测它们,但也行不通,因此有些事件是只有特定元素才有的。

‘onreset’ in document.documentElement; // false
‘onreset’ in document.createElement(’input’); // true
在标准浏览器我们可以用setAttrubute为元素赋以已知事件名一个值,这个值会自动包装成一个函数,如果非事件名,则不会改变其类型。那么我检测它是否为函数就是!

var el = document.createElement(’div’);

el.setAttribute(’onclick’, ‘return;’);
alert(typeof el.onclick); // “function”

el.setAttribute(’onclick2′, ‘return;’);
alert(typeof el.onclick2); // “undefined”
同样很不幸,基于众所周知的原因,IE的setAttribute与W3C是有很大的差别,IE会原样输出,加之,IE不存在所谓的泛化函数(原生对象的方法),它的API没有name,call,apply与toString,因此也无法判定它们是否为函数。综合以上两种方式,看看外国人搞出什么怪物来……

var isEventSupported = (function(){//使用模块模式

var TAGNAMES = {//特定元素上的特定事件
’select’:’input’,’change’:’input’,
’submit’:’form’,’reset’:’form’,
‘error’:’img’,’load’:’img’,’abort’:’img’
}

function isEventSupported(eventName, element) {

element = element || document.createElement(TAGNAMES[eventName] || ‘div’);
eventName = ‘on’ + eventName;

// When using `setAttribute`, IE skips “unload”, WebKit skips “unload” and “resize”, whereas `in` “catches” those
var isSupported = (eventName in element);//DOM0

if (!isSupported) {
// if it has no `setAttribute` (i.e. doesn’t implement Node interface), try generic element
if (!element.setAttribute) {
element = document.createElement(’div’);
}
if (element.setAttribute && element.removeAttribute) {
element.setAttribute(eventName, ”);
isSupported = typeof element[eventName] == ‘function’;

// if property was created, “remove it” (by setting value to `undefined`)
if (typeof element[eventName] != ‘undefined’) {
element[eventName] = void 0;
}
element.removeAttribute(eventName);
}
}

element = null;
return isSupported;
}
return isEventSupported;
})();

<!doctype html>
<html dir=”ltr” lang=”zh-CN”>
<head id=”head”>
<meta charset=”utf-8″/>
<title>司徒正美 </title>

<script type=”text/javascript” charset=”utf-8″>
window.onload = function(){

var isEventSupported = (function(){//使用模块模式

var TAGNAMES = {//特定元素上的特定事件
’select’:’input’,’change’:’input’,
’submit’:’form’,’reset’:’form’,
‘error’:’img’,’load’:’img’,’abort’:’img’
}

function isEventSupported(eventName, element) {

element = element || document.createElement(TAGNAMES[eventName] || ‘div’);
eventName = ‘on’ + eventName;

// When using `setAttribute`, IE skips “unload”, WebKit skips “unload” and “resize”, whereas `in` “catches” those
var isSupported = (eventName in element);//DOM0

if (!isSupported) {
// if it has no `setAttribute` (i.e. doesn’t implement Node interface), try generic element
if (!element.setAttribute) {
element = document.createElement(’div’);
}
if (element.setAttribute && element.removeAttribute) {
element.setAttribute(eventName, ”);
isSupported = typeof element[eventName] == ‘function’;

// if property was created, “remove it” (by setting value to `undefined`)
if (typeof element[eventName] != ‘undefined’) {
element[eventName] = void 0;
}
element.removeAttribute(eventName);
}
}

element = null;
return isSupported;
}
return isEventSupported;
})();
function w(name, element) {
document.write(name + ‘: ‘ + (
isEventSupported(name, element)
? ‘<span style=”background-color:green;color:white;”>true</span>’
: ‘<span style=”background-color:red;color:white;”>false</span>’
) + ‘<br>’);
}

document.write(’<pre>’ + isEventSupported + ‘</pre><br><br>’);

document.write(’<h2>Mouse events:</h2>’);

w(’click’);
w(’dblclick’);
w(’mousedown’);
w(’mouseup’);
w(’mouseover’);
w(’mousemove’);
w(’mouseout’);

document.write(’<h2>Key events:</h2>’);

w(’keypress’);
w(’keydown’);
w(’keyup’);

document.write(’<h2>HTML events</h2>’);

w(’load’);
w(’unload’, window);
w(’abort’);
w(’error’);

document.write(’<h2>View events</h2>’);

w(’resize’, window);
w(’scroll’);

document.write(’<h2>Form events:</h2>’);

w(’submit’);
w(’reset’);

document.write(’<h2>Form controls\’ events:</h2>’);

w(’select’);
w(’change’);

document.write(’<h2>Activation events:</h2>’);

w(’focus’);
w(’blur’);

document.write(’<h2>MSHTML DOM events:</h2>’);

w(’cut’);
w(’copy’);
w(’paste’);
w(’beforecut’);
w(’beforecopy’);
w(’beforepaste’);
w(’afterupdate’);
w(’beforeupdate’);
w(’cellchange’);
w(’dataavailable’);
w(’datasetchanged’);
w(’datasetcomplete’);
w(’errorupdate’);
w(’rowenter’);
w(’rowexit’);
w(’rowsdelete’);
w(’drag’);
w(’dragstart’);
w(’dragenter’);
w(’dragover’);
w(’dragleave’);
w(’dragend’);
w(’drop’);
w(’selectstart’);
w(’mouseenter’);
w(’mouseleave’);
w(’activate’);
w(’beforeactivate’);
w(’deactivate’);
w(’beforedeactivate’);
w(’focusin’);
w(’focusout’);
w(’stop’, document);
w(’readystatechange’);
w(’beforeprint’, document.body);
w(’afterprint’, document.body);
w(’beforeunload’, window);

document.write(’<h2>Unexistent (most likely) events:</h2>’);

w(’click2′);
w(’foobarbaz’);

document.write(’<h2>Unexistent in Opera <=10a</h2>’);

w(’contextmenu’);

document.write(’<h2>iPhone touch/gesture events</h2>’);

w(’touchstart’);
w(’touchend’);
w(’touchmove’);
w(’touchcancel’);

document.write(’<br>’);

w(’gesturestart’);
w(’gesturechange’);
w(’gestureend’);

document.write(’<h2>HTML5 events</h2>’);

w(’hashchange’, document.body);
w(’online’, document.body);
w(’offline’, document.body);
w(’message’, window);
w(’undo’, document.body);
w(’redo’, document.body);
w(’storage’, window);
w(’popstate’, window);

w(’canplay’, document.createElement(’video’));
w(’seeking’, document.createElement(’video’));
w(’seekend’, document.createElement(’video’));

document.write(’<h2>Proprietary</h2>’);

w(’pageshow’, window);
w(’pagehide’, window);

};
</script>

</head>
<body>

</body>
</html>

连HTML5与iPhone touch的一些专有事件也能检测到。

在jQuery1.4α2中也支持这种特性侦探了,不过用的是早期版本,不如上面写出来的那个!

//jQuery1.4α2
var eventSupported = function( eventName ) {
var el = document.createElement(”div”);
eventName = “on” + eventName;

var isSupported = (eventName in el);
if ( !isSupported ) {
el.setAttribute(eventName, “return;”);
isSupported = typeof el[eventName] === “function”;
}
el = null;

return isSupported;
};
在未来jQuery技术方面,如果我们无法摆脱那些旧浏览器的话,事情可能没多少改变,不过,即使现在,在那些更好的浏览器身上,我们也已经看到一些令人振奋的东西,我期待看到一些全新的东西。

Webkit引擎开发团队已经做在CSS动画方面做了很多工作,他们甚至将触角伸向图形硬件来实现炫目的视觉效果。Firefox, Safari, and Chrome 正在 JavaScript引擎方面你追我赶,而众多JavaScript 库也在性能上大幅提升。我们会开到越来越多的 HTML 5元素的使用,如 Canvas, 音频,视频。Web 字体方面也将更加完善,不管从技术方面还是版权方面。可以肯定的是,未来的Web会让人惊异。
分享到:
评论

相关推荐

    javascript打造跨浏览器事件处理机制[Blue-Dream出品]

    在讨论如何使用JavaScript来创建一个跨浏览器的事件处理机制时,我们首先需要了解不同浏览器之间在事件处理方面的差异性,以及为了兼容这些差异,开发者们采取了哪些策略。以下是从给出的文件内容中提取出来的相关...

    JS针对浏览器窗口关闭事件的监听方法集锦

    在JavaScript中,监听浏览器窗口关闭...然而,现代浏览器可能对`onbeforeunload`事件的处理有所限制,可能不再允许自定义警告消息,而是显示默认的确认对话框。因此,在实际应用中,需要考虑这些限制并做出相应的调整。

    使用js检测当前浏览器版本,多浏览器类型和版本号检测

    本文将深入探讨如何使用JavaScript来检测浏览器版本,特别关注IE(Internet Explorer)的各种版本。 1. **获取浏览器信息的基础方法** JavaScript提供了`navigator`对象,该对象包含了关于用户浏览器的信息。我们...

    js跨浏览器是正对目前各浏览器标准不同

    `XMLHttpRequest`是最早的异步通信方式,但不同浏览器对其API的实现略有差异。现在,多数浏览器支持`fetch` API,它提供了更简洁的接口,但对旧浏览器需通过polyfill进行兼容。 8. **动画和过渡**: CSS3的动画和...

    跨浏览器事件处理程序

    通过恰当地使用能力检测,保证处理事件的代码在大多数浏览器下一致地运行。

    浏览器检测的多种方式-javascript代码

    通过上述方法,我们可以有效地检测出用户的浏览器类型及版本,并根据浏览器的特性选择合适的事件绑定方式。然而,需要注意的是,虽然`User-Agent`字符串可以提供关于浏览器的信息,但它并不是一个可靠的检测方法,...

    浏览器检测脚本

    10. **响应式设计**:检测浏览器窗口大小变化的`resize`事件,以及媒体查询的支持,以实现不同屏幕尺寸下的适配。 在实际开发中,`detect.js`这样的脚本可以作为工具,帮助我们创建跨浏览器的解决方案。不过,现代...

    巧用Behaviors检测浏览器

    ### 巧用Behaviors检测浏览器 #### 背景与挑战 随着互联网技术的发展,不同的浏览器不断涌现,但至今尚未形成一个统一的标准。这导致了同一个网页在不同浏览器中的显示效果差异巨大,甚至可能出现布局错乱的情况。...

    浏览器兼容问题处理

    以上列举的是前端开发中常见的浏览器兼容性问题及其解决方案,实践中可能还会遇到其他问题,如CSS样式在不同浏览器中的表现差异等,解决这些问题通常需要对各种浏览器的特性有深入理解,并利用条件注释、特性检测库...

    不同浏览器之间路径问题Demo

    这其中包括文件路径解析方式的差异,导致在不同浏览器上加载资源时可能会遇到问题。 2. **路径表示法**: 在Web开发中,文件路径有几种常见的表示方法: - **绝对路径**:从根目录开始的完整路径,如`/users/...

    不同浏览器跳转.rar

    标题“不同浏览器跳转.rar...总的来说,解决“不同浏览器跳转”的问题需要对Web开发有深入的理解,包括JavaScript、浏览器兼容性和用户代理检测等技术。同时,这样的解决方案应尽可能地优雅,兼顾功能实现和用户体验。

    个浏览器对css属性的不同支持

    在网页设计和开发中,CSS(层叠样式表)是不可或缺的一部分,用于控制网页元素的...总之,理解和处理浏览器对CSS属性的不同支持是Web开发中的一项关键技能,通过适当的策略和工具,我们可以创建出既美观又兼容的网页。

    检测浏览器是否支持UpdatePanel控件

    1. **JavaScript检测**:使用JavaScript代码检测浏览器是否支持必要的AJAX功能,如XMLHttpRequest对象和JSON解析。如果浏览器不支持,可以切换到传统的全页面刷新方式或者提供其他反馈。 2. **服务器端检查**:在...

    检测浏览器版本提示升级js插件

    `jQuery` 是一个广泛使用的JavaScript库,简化了DOM操作、事件处理、动画以及Ajax交互等任务。在`badbrowser.js`的场景中,jQuery可能被用作基础工具,帮助实现跨浏览器的兼容性,提供更流畅的用户体验。jQuery的API...

    前端不同浏览器兼容性解决办法

    2. reset.css 或 normalize.css:每个浏览器对默认样式处理不同,引入reset.css或normalize.css可以消除浏览器默认样式带来的差异,使页面在不同浏览器中表现一致。 3. Box Model:IE与其他浏览器对Box Model的处理...

    用JAVASCRIPT修正12个常见的浏览器问题

    6. **CSS3属性的兼容处理**:使用JavaScript库(如Modernizr)检测浏览器对CSS3属性的支持,然后为不支持的浏览器提供备选样式。 7. **盒模型差异**:由于不同浏览器对盒模型的解析方式不同,可以使用JavaScript来...

    【JavaScript源代码】如何用JavaScript检测当前浏览器是无头浏览器.docx

    console.log("可能是无头浏览器,图片加载错误处理不同"); }; img.src = "http://nonexistent.url/404.jpg"; ``` 总结来说,检测无头浏览器通常需要结合多种方法,包括检查 User Agent、浏览器插件、语言设置、...

    javascript经典特效---检测浏览器支持的js版本.rar

    4. 使用polyfill库:如Modernizr,这类库可以检测浏览器对特定特性的支持情况,并提供缺失功能的模拟实现。这样可以在旧版浏览器中实现新特性,同时避免了手动检测。 总的来说,检测浏览器支持的JavaScript版本是...

    浏览器检测的js实现

    可以加入此JS来检测各种浏览器,对多浏览器开发有很大帮助。

    C#源码自动检测手机浏览器

    5. **多平台兼容性**:在检测手机浏览器时,需要考虑不同操作系统(如iOS、Android、Windows Phone)以及多种浏览器(如Chrome、Firefox、Safari、Edge等)的User-Agent格式差异。 6. **异常处理**:由于User-Agent...

Global site tag (gtag.js) - Google Analytics