繁体   English   中英

将焦点设置为仅在父对象被聚焦时才会显示的元素

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM