当前位置: 代码迷 >> Web前端 >> 焦点压制与选择区域
  详细解决方案

焦点压制与选择区域

热度:261   发布时间:2012-11-05 09:35:11.0
焦点抑制与选择区域

之前关于焦点也有过探讨:


焦点与键盘监控


firefox中iframe焦点丢失问题


焦点相关事件兼容性问题


这次要说的则是焦点以及以及元素内选择的问题。


html中的某些元素 (a,button)或经过设置属性的元素(tabindex )可以获得焦点以及失去焦点,获得了焦点就可以响应键盘,读屏器等辅助设备了。


另一方面可以通过鼠标按下选定某段选择区域的开始位置,以及鼠标放开标志该选择区域的结束。


而焦点,选择区域与鼠标按下操作也有联系,鼠标按下不仅意味着接受元素可以有机会获得焦点,另一方面也可能导致一端新选择区域的开始。


1.正常情况


如下所示,高亮元素为黄色,鼠标在区域 2 按下会使得区域 2 获得焦点,若同时拖放则会使得区域 2 的内容部分选中


正常情况 demo



2.控制选择


标准浏览器:


css 存在 user-select 属性 ,目前firefox,wekit有对应的 -moz-user-select ,-webkit-user-select ,如果设置为 none,则该元素内的所有东西(包括子孙元素)都不能被选中了,但是元素还是可以获得焦点的。ctrl-a 都不会选择到区域 2 !


ie:

?

ie 比较另类,有着相似的 unselectable 属性,但是该属性和 css 属性 user-select 不同之处在于:


1.unselectable 仅仅是控制选择区域的开始和结束位置使得其不能位于设置属性的元素本身(文字节点),而对其子孙节点则不会限制。但 ctr-a 还是可以选择到区域 2 的 !


2.另一点需要注意的是 unselectable 会影响页面焦点的切换,设置了 unselectable 的元素即使被点击也不会获得焦点!


对应 ie 的这个属性,一般是对元素以及其子孙元素全部设置 unselectable ,使得不能从该元素开始选择以及焦点抑制:

?

PS : updated 2010-12-10

?

?

在 ie9 的超标准模式下,必须写成

?

element.setAttribute("unselectable", 'on');

?

而不是

?

elment.unselectable='on';

?

难道是因为 ie9 彻底分离了 attribute 与 property ?


unselectable 与 user-select


ie 设置 unselectable ,其他设置 user-select


PS2 : input 焦点抑制

?

updated 2011-01-26

?

对于 input 并不起作用,点了 input ,还是一定会使得当前焦点移到点击的 input 上面去,尝试 onbeforedeactivate onbeforeactivate 似乎也不起作用,只能通过一个绝对定位的 span 遮盖掉当前的 input:

?

<span class="ks-wrap">
<span class="ks-mask" style="opacity: 0;"></span>
<input id="sel"/>
</span>
?

设置? ks-wrap 与 ks-mask 为 unselectable ,并设置mask 样式遮盖input :

?

.ks-mask {    
    position:absolute;
    background-color:black;
    z-index:99;
    width:100%;
    height:100%;
    *width:expression(function(el){el.style.width=el.parentNode.offsetWidth;}(this));
    *height:expression(function(el){el.style.height=el.parentNode.offsetHeight;}(this));
}

?

PS3 : onselectstart

?

ie 上 和 user-select 效果最接近的应该是注册元素的 onselectstart 事件,使得不能从这个元素开始一段选择区域

?

?

el.onselectstart=function(){ return false;}

?

但是仍然可以 ctrl-a 选中,如果绑定在 body 上,那么整个文档就不能有选择区域了:

?

document.body.onselectstart=function(){ return false;}

3.焦点抑制


ie 下同 2 所说,设置 unselectable 不但会导致选择区域受影响,而且会导致焦点切换失效。


对于标准浏览器,焦点则是和选择区域控制分离,user-select 只控制选择区域,而焦点则由 mousedown 控制,根据前文可知,鼠标点击与焦点事件的触发关系为(a1为当前焦点元素,在a2上点击):


a2.mousedown


a1.blur


a2.focus


而 mousedown 是可以被阻止的,在标准浏览器中一旦阻止a2 mousedown的默认事件,则底下的事件都不会触发了,即 a1 不会失去焦点,a2 也不会获得焦点,达到了焦点抑制的目的,同时控制选择区域的起始位置不会出现 a2 的内容中,但是 ctr-a 还是可以选中 a2 内容的。



mousedown return false demo


4.焦点抑制+选择控制


对于 ie 用 2 方法即可,而对于标准浏览器则要结合 2,3 才能同时达到焦点抑制以及选择控制的目的:

?

兼容各个浏览器的demo:


focus and selection control for all demo

?

效果:

?

点击区域2不会获得焦点,不能从区域2中间开始选择,标准浏览器 ctrl-a 也不能选择区域2内容,ie ctrl-a 可以获得区域2内容。





  相关解决方案