[英]Set focus to an element that only shows up when the parent is focused
这是此问题的JSFiddle: https ://jsfiddle.net/g92u4deo/0/
在此JSFiddle中,我要实现的目标是在父#big获得焦点时将焦点放在#small div上。 即,当用户将选项卡切换到蓝色框时,红色框将变为焦点并保持可见状态。
我该怎么做呢?
顺便说一句,您会在我的代码中看到500ms的故意等待,如下所示。 这样做是为了确保在设置焦点之前#small可见。 尽管我认为这不是绝对必要的,但我将其放在此处是因为我认为您不能将重点放在不可见的元素上。
big.onfocus = function () {
console.log("Big focused");
console.log("Active Element: " + document.activeElement.id);
setTimeout(function () {
small.focus();
console.log("Active Element: " + document.activeElement.id);
}, 500);
}
更新:发布此消息后不久,我找到了解决方案。
使用opacity
似乎有效,但display
无效。
https://jsfiddle.net/g92u4deo/1/
也很高兴听到其他解决方案。
结帐演示
var big = document.getElementById("big"); var small = document.getElementById("small"); var log = document.getElementById("log"); big.onfocus = function () { big.classList.add('focused'); small.classList.add('focused'); small.focus(); log.innerText = document.activeElement.id; } big.onblur = function () { if(!small.classList.contains('focused')){ big.classList.remove('focused'); } log.innerText = document.activeElement.id; } small.onfocus = function(){ log.innerText = document.activeElement.id; } small.onblur = function(){ small.classList.remove('focused'); big.classList.remove('focused'); log.innerText = document.activeElement.id; }
#big { width: 100px; height: 100px; background: blue; border: none; display: inline-block; } #big.focused { background: lightblue; } #small { width: 40px; height: 40px; background: red; display: none; } #small.focused { background: pink; display: block; } #log{ clear:both; float:right; display: inline-block; }
<div id="big" tabindex="1"> <div id="small" tabindex="-1"> </div> </div> <div id="log"></div>
您看到的问题是由于您无法专注于隐藏元素。 当您在#small
元素(即small.focus()
)上调用.focus()
方法时,因此将要从#big
元素上移除焦点,这意味着选择器#big:focus #small
将不再选择#small
元素,然后将display
设置为block
(因为一次只能有一个元素具有焦点)。
正如您已经指出的那样,最简单的选择是使用opacity
属性隐藏元素而不是display
属性。 这样,该元素在技术上不会被隐藏:
document.getElementById("big").addEventListener('focus', function() { document.getElementById("small").focus(); });
#big { width: 100px; height: 100px; background: blue; } #small { width: 60px; height: 60px; background: pink; opacity: 0; } #small:focus { opacity: 1; }
<div id="big" tabindex="0"> <div id="small" tabindex="-1">Small</div> </div>
但是,在某些情况下,您可能不希望更改元素的不透明度,因为您不希望它占用空间。 一种替代方法是删除所有可能的填充/边距/边界,然后将元素上的尺寸设置为0
。 一旦该元素具有焦点,您将还原它,它将按预期工作。
这是一个演示此情况的基本示例:
document.getElementById("big").addEventListener('focus', function() { document.getElementById("small").focus(); });
#big { width: 100px; height: 100px; background: blue; } #small { /* Explicity set everything to 0 initally.. */ width: 0; height: 0; margin: 0; padding: 0; border: 0; overflow: hidden; } #small:focus { width: 60px; height: 60px; overflow: visible; background: pink; }
<div id="big" tabindex="0"> <div id="small" tabindex="-1">Small</div> </div>
或者,您也可以最初将元素绝对定位在屏幕之外。 这样,它将被隐藏,但仍然可以聚焦:
document.getElementById("big").addEventListener('focus', function() { document.getElementById("small").focus(); });
#big { width: 100px; height: 100px; background: blue; } #small { /* Absolutely position the element off the screen initially */ position: absolute; top: -9999px; left: -9999px; } #small:focus { position: static; top: auto; left: auto; width: 60px; height: 60px; background: pink; }
<div id="big" tabindex="0"> <div id="small" tabindex="-1">Small</div> </div>
以上三种可能的解决方法要求您手动在元素上设置CSS。 如果希望自动处理此问题,则可以在调用.focus()
方法之前向该元素添加一个focusable
类。 当元素具有焦点时,只需删除该类。
这样,您仍然可以最初将元素的display
属性设置为none
。
var big = document.getElementById("big"); var small = document.getElementById("small"); big.addEventListener('focus', function() { small.classList.add('focusable'); small.focus(); }); small.addEventListener('focus', function() { this.classList.remove('focusable'); });
#big { width: 100px; height: 100px; background: blue; } #small { display: none; width: 60px; height: 60px; background: pink; } #small.focusable, #small:focus { display: block; }
<div id="big" tabindex="0"> <div id="small" tabindex="-1">Small</div> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.