标题可能不是一读让人容易明白,上张图(转载的)
需要实现如下的效果,有一个浮动层,需要层级在它之下的一个元素也能照常响应相应的事件
一个100*100的元素,边框为1px solid #406c99,它有两个事件(鼠标移入、鼠标移出):
onmouseover="this.style.borderColor=‘#f00‘;"
onmouseout="this.style.borderColor=‘#406c99‘;"
在不做特殊处理的情况下,它的事件将会是无法触发的,现在想让它正常触发,效果如下:
解决这样的问题有以下方案:
1、纯使用CSS的属性pointer-events,设置其为none (默认为auto)
优点:无需额外的代码
缺点:不支持IE(IE不支持此属性,IE9是否支持有待考评..)
2、捕捉事件获取鼠标的位置X、Y,然后触发层级较低元素的相应事件 (平时我们用调试工具选取页面中的元素,高亮显示的区域就是依据这个原理)
优点:兼容各浏览器
缺点:需要编写Javascript,效率并不高
这样获取有也有两种处理方法:
循环获取每一个元素的位置,然后对比鼠标的X、Y,效率低,不推荐;这里推荐使用elementFromPoint(浏览器都支持),直接传入X、Y,便可直接获取相应的DOM元素
比较折中的办法是,针对非IE的浏览器直接使用方案1,IE使用方案2进行优化。这种应用场景,可能会是一个新的产品上线了,需要引导用户如何去使用,会使用蒙板遮住整个页面,然后让某一元素可点击。
elementFromPoint的使用例子(移动鼠标时,如果那一点在某一元素的占位区域则添加3像素的红色边框,鼠标移开该元素时清除边框)
<!DOCTYPE html><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script type="text/javascript" >var selElem =null;var origBorder =""; function OnMouseMove (event) { var posX = event.clientX, posY =event.clientY; var ua = navigator.userAgent, isIE = /msie/i.test(ua), isFF = /firefox/i.test(ua); if(!isIE && !isFF) { posX = event.pageX; posY = event.pageY; } var info = document.getElementById("info"); info.innerHTML = event.clientX + ", " + event.clientY; var overElem = document.elementFromPoint(posX, posY); if(overElem && !overElem.tagName) { overElem = overElem.parentNode; } if (selElem) { if (selElem == overElem) { return ; } selElem.style.border = origBorder; selElem = null; } if (overElem && !/^(html|body)$/.test(overElem.tagName.toLowerCase()) ) { selElem = overElem; origBorder = overElem.style.border; overElem.style.border = "3px solid red" ; }} </script> </head> <body onmousemove="OnMouseMove (event);"> <div style="height:200px"> test test test test test test test </div> <div style="position:absolute; right:20px; top:30px;"> The current mouse position: <span id="info" style="border:1px solid #606060; padding:5px;"></span> </div> <br/><br/> <textarea rows="4" style="width:200px; height:100px;"> test test test test test test test test test test test test test test </textarea> <div style="height:100px; margin-top:20px;"> test test test test test test testtest test test test test test testtest test test test test test testtest test test test test test test </div></body></html>
遍历元素,然后找到相应的元素示例(效率比较低的一种)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <title>Sandbox</title> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <style type="text/css" media="screen"> body { padding: 0px; line-height: 1.8; color: rgb(0, 128, 0);">#000; }.box {width: 50px; height: 50px; border: 1px solid white}.highlight {}#controls {position:absolute; top: 300px; color: white;}</style> </head> <body> <div id="container"> <div class="box" style="position:absolute; top: 25px; left: 25px;"></div> <div class="box" style="position:absolute; top: 50px; left: 125px;"></div> <div class="box" style="position:absolute; top: 100px; left: 25px;"></div> <div class="box" style="position:absolute; top: 125px; left: 180px;"></div> <div class="box" style="position:absolute; top: 225px; left: 25px;"></div> <div class="box" style="position:absolute; top: 185px; left: 125px;"></div> <div id="shield" style="position: absolute; width: 200px; top: 0px; opacity: 0.5; filter:alpha(opacity=50);"></div> </div> <div id="controls"> <input type="checkbox" checked="checked">Pass pointer events through</input> Try clicking </div> <script> $(".box").click(function(){ $(this).toggleClass("highlight");}); function passThrough(e) { $(".box").each(function() { // check if clicked point (taken from event) is inside element var mouseX = e.pageX; var mouseY = e.pageY; var offset = $(this).offset(); var width = $(this).width(); var height = $(this).height(); if (mouseX > offset.left && mouseX < offset.left+width && mouseY > offset.top && mouseY < offset.top+height) $(this).click(); // force click event });} $("#shield").click(passThrough); var dthen = new Date(); setInterval(function(){ dNow = new Date(); $(‘#shield‘).css(‘height‘, ((dNow.getSeconds()+(dNow.getMilliseconds()/1000))*50)%300 +‘px‘);},10) var doPassThrough = true;$(‘input‘).click(function(){ doPassThrough = !doPassThrough; if (doPassThrough){ $("#shield").click(passThrough); } else { $(‘#shield‘).unbind(‘click‘, passThrough); }}); </script></body> </html>
在非IE浏览器中,控制pointer-events来达到想要的效果的示例
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html> <head> <title>pointer-events test</title> <meta name="generator" content="editplus" /> <meta name="author" content="" /> <meta name="keywords" content="" /> <meta name="description" content="" /> <meta http-equiv="content-Type" content="text/html;charset=utf-8"> <style type="text/css"> * {margin:0; padding:0;} body {width:100%; height:100%;} </style> </head> <body> <div style="border:1px solid #406c99; width:100px; height:100px; margin-top:300px; margin-left:300px;" onmouseover="this.style.borderColor=‘#f00‘;" onmouseout="this.style.borderColor=‘#406c99‘;" title="hahaniu"></div> <div style="position:absolute; top:0; left:0; width:100%; height:100%; opacity:.3; filter:alpha(opacity=30); overflow:hidden;" id="mask"></div> <button style="position:absolute; z-index:9999; left:100px; top:80px; padding:2px;">开启pointer-events支持</button> <script type=‘text/javascript‘> var isOpen = false; document.getElementsByTagName("button")[0].onclick = function(evt) { evt = evt || window.event; this.innerHTML = (isOpen ? "开启" : "关闭") + "pointer-events支持"; document.getElementById("mask").style.pointerEvents = isOpen ? "" : "none"; isOpen = !isOpen;} </script> </body></html>