将焦点设置为仅在父焦点聚焦时显示的元素

时间:2016-01-15 19:29:24

标签: javascript html css

以下是此问题的JSFiddle:https://jsfiddle.net/g92u4deo/0/

在这个JSFiddle中,我想要实现的是在其父#big获得焦点时将焦点设置在#small div上。即,当用户选项卡到蓝色框时,红色框变为焦点并保持可见。

我该怎么做?

是的,你会在我的代码中看到故意等待500毫秒,如下所示。这样做是为了确保在设置焦点之前可以看到#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/

听到其他解决方案也很棒。

2 个答案:

答案 0 :(得分:0)

结帐演示



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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您所看到的问题是由于您无法专注于隐藏元素。当您在.focus()元素(即#small)上调用small.focus()方法时,您将从#big元素中删除焦点,这意味着选择器{{ 1}}将不再选择#big:focus #small元素并将#small设置为display(因为一次只有一个元素可以有焦点)。

潜在解决方案:

正如您已经指出的,最简单的选择是使用block属性隐藏元素而不是opacity属性。这样做,从技术上讲,元素不会被隐藏:

&#13;
&#13;
display
&#13;
document.getElementById("big").addEventListener('focus', function() {
  document.getElementById("small").focus();
});
&#13;
#big {
  width: 100px; height: 100px;
  background: blue;
}

#small {
  width: 60px; height: 60px;
  background: pink;
  opacity: 0;
}

#small:focus {
  opacity: 1;
}
&#13;
&#13;
&#13;

但是,在某些情况下,您可能无法更改元素的不透明度,因为您不希望它占用空间。另一种方法是删除任何可能的填充/边距/边框,然后将元素上的尺寸设置为<div id="big" tabindex="0"> <div id="small" tabindex="-1">Small</div> </div>。只要元素具有焦点,您就可以恢复它,并且它将按预期工作。

这是一个证明这一点的基本例子:

&#13;
&#13;
0
&#13;
document.getElementById("big").addEventListener('focus', function() {
  document.getElementById("small").focus();
});
&#13;
#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;
}
&#13;
&#13;
&#13;

作为替代方案,您最初也可以绝对将元素放在屏幕上。这样做,它将被隐藏但仍然可以集中精力:

&#13;
&#13;
<div id="big" tabindex="0">
  <div id="small" tabindex="-1">Small</div>
</div>
&#13;
document.getElementById("big").addEventListener('focus', function() {
  document.getElementById("small").focus();
});
&#13;
#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;
}
&#13;
&#13;
&#13;

上面三个可能的解决方法要求您在元素上手动设置CSS。如果要自动处理,可以在调用<div id="big" tabindex="0"> <div id="small" tabindex="-1">Small</div> </div>方法之前向元素添加focusable类。当元素具有焦点时,只需删除该类。

这样做,您仍然可以将元素的.focus()属性设置为display

&#13;
&#13;
none
&#13;
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');
});
&#13;
#big {
  width: 100px; height: 100px;
  background: blue;
}

#small {
  display: none;
  width: 60px;
  height: 60px;
  background: pink;
}

#small.focusable,
#small:focus {
  display: block;
}
&#13;
&#13;
&#13;