firebug查看元素功能最困难的地方就是当用户点击某个元素的时候,阻止绑定在这个元素上的点击事件,或者当这个元素是一个链接时,阻止链接的释放。也许你首先想到的是鼠标移入的时候,在鼠标底下浮动一个元素,该元素带有1像素的蓝色边框。但这样一来,鼠标事件的e.target就成了底下浮动的元素了。
方法一
比较笨的一个方式是在鼠标的四周各浮动一个元素,分别表示当前元素的四条边,四条边的中间也就是鼠标底下是空的。为了阻止事件、链接的促发,当mousedown的时候,在鼠标底下浮动一个看不见的元素,从而阻断click事件,当mouseup后,又将这个浮动的元素移开,从而让mouseover的e.target恢复成鼠标底下的元素。
Demo
var getXY = function(node){
return {"x": node.getBoundingClientRect().left + Math.max(document.body.scrollLeft, document.documentElement.scrollLeft), "y": node.getBoundingClientRect().top + Math.max(document.body.scrollTop, document.documentElement.scrollTop)};
}
$(document).mouseover(function(e) {
var target = e.target,
width = target.offsetWidth,
height = target.offsetHeight,
p = getXY(target),
x = p.x,
y = p.y;
$('#abs-1').css({"left":x+"px","top":y+"px","width":width+"px","height":0,"border-top":"1px solid blue"});
$('#abs-2').css({"left":x+width+"px","top":y+"px","width":0,"height":height+"px","border-left":"1px solid blue"});
$('#abs-3').css({"left":x+"px","top":y+height+"px","width":width+"px","height":0,"border-top":"1px solid blue"});
$('#abs-4').css({"left":x+"px","top":y+"px","width":0,"height":height+"px","border-left":"1px solid blue"});
});
$(document).mousedown(function(e) {
$('#abs-mask').css({"left":0,"top":0,"right":0,"bottom":0});
});
$(document).mouseup(function(e) {
$('#abs-mask').css({"left":0,"top":0,"right":"auto","bottom":"auto"});
});
方法二
第二个方法就比较优雅了,CSS有一个让事件穿透某个元素的属性——pointer-events,有了它我们只需要改变这个属性的值就可以了。当mouseover的时候,属性值为auto,事件可以穿透元素,鼠标的底下浮动的元素就像不存在了一样,e.target始终是我们想要的元素;而当mousedown的时候,将属性值修改为none,让事件不能穿透元素,这样鼠标底下的浮动的元素就阻止了目标元素的click事件;当mouseup后,又将属性值修改为auto。
Demo
var getXY = function(node){
return {"x":node.getBoundingClientRect().left+Math.max(document.body.scrollLeft,document.documentElement.scrollLeft),"y":node.getBoundingClientRect().top+Math.max(document.body.scrollTop,document.documentElement.scrollTop)};
}
$(document).mouseover(function(e) {
var target = e.target,
width = target.offsetWidth,
height = target.offsetHeight,
p = getXY(target),
x = p.x,
y = p.y;
$('#abs-mask').css({"left":x+"px","top":y+"px","width":width+"px","height":height+"px","pointer-events":"none"});
});
$(document).mouseup(function(e) {
$('#abs-mask').css({"pointer-events":"none"});
});
$(document).mousedown(function(e) {
$('#abs-mask').css({"pointer-events":"auto"});
});
方法三
第二个方法虽然比第一种幽雅一些,但是当你快速点击的时候,偶尔会失效,不知道是不是事件来不及执行导致的。这里要介绍第三种更加规范、稳定的方法:事件捕获。不了解的朋友可以google一下“事件流”。简单的说,事件有2种传播的方式,一种是我们常用的“事件冒泡”,即当我们点击一个按钮时,这个点击事件,会根据dom结构,一级一级往上传播,直到document对象(chrome、safari、opera、firefox浏览器都将冒泡至window对象);另一种就是“事件捕获”,与前者相反,在事件捕获中,document对象(chrome、safari、opera、firefox都是从window对象开始捕获)首先接受到事件,然后沿着DOM树,依次往下传播,一直到目标按钮,当需要在事件到达目标之前截获时就需要它了,这正是我们需要的。
Demo
var getXY = function(node){
return {"x":node.getBoundingClientRect().left+Math.max(document.body.scrollLeft,document.documentElement.scrollLeft),"y":node.getBoundingClientRect().top+Math.max(document.body.scrollTop,document.documentElement.scrollTop)};
};
document.documentElement.addEventListener('mouseover', function(e) {
e.preventDefault();
var target = e.target,
width = target.offsetWidth,
height = target.offsetHeight,
p = getXY(target),
x = p.x,
y = p.y;
document.getElementById('abs-mask').style.cssText = 'left:'+x+'px;top:'+y+'px;width:'+width+'px;height:'+height+'px;';
}, false);
document.body.addEventListener('click', function(e){
e.preventDefault();
e.stopPropagation();
//console.log(e.target);
}, true);