Firefox的行为跟其浏览器架构有关。
Firefox浏览器本身就是由其浏览器核心渲染呈现的,所以其右键的上下文菜单的
原理与网页一致,即由鼠标事件触发,然后判断如果显示上下文菜 单,则继续触
发contextmenu,否则跳过。
而Chrome和IE的浏览器本身并不是由浏览器核心渲染的,所以只好把一切都做成事
件,然后在决定是否处理事件。
于 2012/3/16 13:35, Gray Zhang 写道:
根据昨天在#javascript罗浮宫2群#与@可乐 同学的讨论,浏览器在处理鼠标右
键的MosueEvent序列时存在一些不同,在此摘录并邀请大家讨论:
测试页面如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello World</title>
</head>
<body>
<div style="width: 400px; height: 400px; background: red;"></div>
<script>
var div = document.getElementsByTagName('div')[0];
div.addEventListener('mousedown', function() {
console.log('mousedown on div'); }, false);
div.addEventListener('up', function() {
console.log('mousedown on div'); }, false);
div.addEventListener('click', function() {
console.log('mousedown on div'); }, false);
div.addEventListener('contextmenu', function() {
console.log('mousedown on div'); }, false);
document.addEventListener('mousedown', function() {
console.log('mousedown on document'); }, false);
document.addEventListener('up', function() {
console.log('mousedown on document'); }, false);
document.addEventListener('click', function() {
console.log('mousedown on document'); }, false);
document.addEventListener('contextmenu', function() {
console.log('mousedown on document'); }, false);
</script>
</body>
</html>
在红色的<div>元素上右键单击一次后,出现的事件顺序在各浏览器中如下:
Chrome 17:
mousedown on div
mousedown on document
mouseup on div
mouseup on document
contextmenu on div
contextmenu on document
Firefox 11:
mousedown on div
mousedown on document
mouseup on div
mouseup on document
click on document
contextmenu on div
contextmenu on document
IE 9:
mousedown on div
mousedown on document
mouseup on div
mouseup on document
contextmenu on div
contextmenu on document
可以看到,Chrome和IE行为相同,而Firefox会额外在document上触发一个click
事件,且该事件不 捕获(有使用useCapture参数测试)不冒泡。
如果给所有的事件处理函数加上preventDefault行为,则各浏览器中的结果如下:
Chrome 17:
mousedown on div
mousedown on document
mouseup on div
mouseup on document
contextmenu on div
contextmenu on document
不弹出菜单
Firefox 11:
mousedown on div
mousedown on document
mouseup on div
mouseup on document
click on document
不弹出菜单
IE 9:
mousedown on div
mousedown on document
mouseup on div
mouseup on document
contextmenu on div
contextmenu on document
不弹出菜单
同样Chrome和IE9有相同的结果,Firefox则会因为click事件中的
preventDefault行为影响 contextmenu事件的触发
根据DOM Event Level3(http://www.w3.org/TR/DOM-Level-3-Events/#event-
type-click) 中的描述:
The default action of the click event type varies based on the
proximal event target of the event and the value of the
MouseEvent.button or MouseEvent.buttons attributes. Typical
default actions of the click event type are as follows:
Left click (MouseEvent.button value is 0, MouseEvent.buttons value
is 1):
If the proximal event target has associated activation
behavior, the default action must be to execute that activation
behavior (see Activation triggers and behavior).
If the proximal event target is focusable, the default action
must be to give that element document focus.
Right click (MouseEvent.button value is 1, MouseEvent.buttons
value is 2):
The default action must be to provide a context menu of
options related to that proximal event target.
Middle click (MouseEvent.button value is 2, MouseEvent.buttons
value is 4):
If the proximal event target has associated activation
behavior, the default action must be to execute that activation
behavior in an alternate fashion (such as opening a link in a new
tab or window).
If the proximal event target has no associated activation
behavior, the default action must be device- and user-defined, but
when associated with a device wheel, is often to activate an
alternate scrolling or panning mode.
可以有以下结论:
1. click事件的default action根据按键的不同有不同的行为,并且明确定义了
右键(Right click)时的行为,因此认为鼠标右键应当能触发click事件。在这
一点上,Firefox更靠近标准实现,但仅在document上触发一个不捕获 不冒泡的
事件,行为较为怪异。在关于右键与click事件的关系上,请大家提供更多的资
料或讨论。
2. 鼠标右键click事件的default action是“提供contextmenu”,因此在click事
件中使用preventDefault,会阻止contextmenu的出现,这一点 所有浏览器一
致。但是“不提供contextmenu”是否意味着同时“不触发contextmenu”事件,在这
点上各浏览器 理解不同,Chrome和IE都选择触发contextmenu但不显示菜单,这
一点类似HTML标准中由tabindex引起 不可聚焦元素变为可聚焦时
(http://www.whatwg.org/specs/web-apps/current-work/multipage
/editing.html#focus) 的相关行为(activation behavior which will fire
a xxx event but does nothing)。但是Firefox选择同时阻止contextmenu事件
的触发。在这两者之间哪一个正为准确,邀请大家讨论。
--------------------------------------------------------
Gray Zhang
Mail: [email protected]
Blog: http://www.otakustay.com
Weibo: http://www.weibo.com/otakustay
--
Regards
Hawkeyes Wind