清除选择
ie在设置setCapture之后内容选择都会被禁止,但也因此不会清除在设置之前就已经选择的内容,而且设置之后也能通过其他方式选择内容, 例如用ctrl+a来选择内容。 ps:onkeydown、onkeyup和onkeypress事件不会受到鼠标捕获影响。 而ff在mousedown时就能清除原来选择的内容,但拖动鼠标,ctrl+a时还是会继续选择内容。 不过在丢弃了系统默认动作之后,这样的选择并不会对拖放操作造成影响,这里设置主要还是为了更好的体验。
以前我用禁止拖放对象被选择的方法来达到目的,即ie中设置拖放对象的onselectstart返回false,在ff中设置样式MozUserSelect(css:-moz-user-select)为none。 但这种方法只能禁止拖放对象本身被选择,后来找到个更好的方法清除选择,不但不影响拖放对象的选择效果,还能对整个文档进行清除:
- ie: document.selection.empty()
- ff: window.getSelection().removeAllRanges()
为了防止在拖放过程中选择内容,所以把它放到Move程序中,下面是兼容的写法:
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
margin
还有一个情况,当拖放对象设置了margin,那么拖放的时候就会错位(给SimpleDrag的拖放对象设置margin就可以测试)。 原因是在Start程序设置_x和_y时是使用offset获取的,而这个值是包括margin的,所以在设置left和top之前要减去这个margin。 但如果在Start程序中就去掉margin那么在Move程序中设置范围限制时就会计算错误, 所以最好是在Start程序中获取值:
this._marginLeft = parseInt(CurrentStyle(this.Drag).marginLeft) || 0; this._marginTop = parseInt(CurrentStyle(this.Drag).marginTop) || 0;
其中CurrentStyle是用来获取最终样式,详细看这里的最终样式部分。
在Move程序中设置值:
this.Drag.style.left = iLeft - this._marginLeft + "px"; this.Drag.style.top = iTop - this._marginTop + "px";
要注意margin要在范围修正只后再设置,否则会错位。
【透明背景bug】
在ie有一个透明背景bug(不知算不算bug),可以用下面的代码测试:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <body> <div onmousedown="alert(1)" style="border:10px solid #C4E3FD; width:50px; height:50px;position:absolute;"> </div> </body> </html>
会发现背景点击触发不了事件,不过点击边框的话还是可以触发。 为什么呢?再用下面的代码测试:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <body style="border:1px solid #FF0000;"> <style>div{width:100px; height:100px; border:1px solid #000;} </style> <div style="position:relative;"> <div onclick="alert(1)" style="border-color:#00f;margin:50px;"> </div> <div onclick="alert(2)" style="border-color:#6f0;position:absolute;top:50px;"> </div> </div> </body> </html>
应该能看出个大概了,下面两个div超出body(即超出红色框)的部分就触发不了事件。 也就是说当触发事件的点,在body以外,而背景又是透明的,那么就会误认为触发点是在了body外空白的地方,所以触发不了事件。 那解决的方法就是,使事件触发点保持在body内,或者设置一个非透明背景。
那程序中只要给拖放对象设一个背景色就可以解决了,但有时需求正好是要透明(例如切割效果),那怎么办呢? 首先想到的是加上背景色后设置完全透明,但这样连边框,容器内的对象等都完全透明了,这个不好。 我想到的一个解决方法是在容器里面加一个层,覆盖整个容器,并设置背景色和完全透明:
with(this._Handle.appendChild(document.createElement("div")).style){ width = height = "100%"; backgroundColor = "#fff"; filter = "alpha(opacity:0)"; }
当发现程序有这个bug出现,把程序可选参数Transparent设为true就会自动插入这样一个层了。 各位如果有更好的方法请多多指点。
暂时就研究到这里,不过还有iframe,滚屏等这些还没考虑到,等以后有需要了再来研究拉。
经典论坛交流: http://bbs.blueidea.com/thread-2896954-1-1.html
本文链接:http://www.blueidea.com/tech/web/2008/6292.asp
出处:蓝色理想
责任编辑:bluehearts
上一页 JavaScript 拖放效果分析 [4] 下一页
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|