【问题标题】:Click button trigger input to appear with focus单击按钮触发输入以显示焦点
【发布时间】:2018-11-08 10:58:56
【问题描述】:

我有一个隐藏的搜索栏,当您单击按钮时会显示该搜索栏。当搜索栏出现时,我希望输入已经具有焦点,以便用户可以立即开始输入。

我正在使用$('#search-input').focus(); 尝试在点击时实现此目的,但它不起作用。

这是JSFiddle。点击红色框触发搜索栏。

我的代码:

$('#search-btn').on('click', function() {
  $(this).toggleClass('active');
  $('#search-input').focus();
  $('#search-wrapper').toggleClass('visible');

  if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
  }

  if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
  }
});
#menu-side {
  width: 200px;
  float: right;
  position: static;
  z-index: 10;
  margin-right: 15px;
  margin-top: 15px;
}

#search-btn {
  background: red;
  border: none;
  font-size: 1.8rem;
  cursor: pointer;
  outline: 0;
  position: relative;
  display: block;
  width: 40px;
  height: 40px;
  transition-duration: 0.3s;
  transition-property: all;
}

#search-wrapper {
  width: 100%;
  position: absolute;
  top: 90px;
  left: 0;
  right: 0;
  opacity: 0;
  visibility: hidden;
  transition-duration: 0.3s;
  transition-property: all;
}

#search-wrapper.visible {
  opacity: 1;
  visibility: visible !important;
}

#search-inner {
  background: #e5e5e5;
  padding: 35px 80px;
}

#search-input {
  border: none;
  background: none;
  font-size: 1.8rem;
  line-height: 1.8rem;
  color: black;
  float: left;
  width: 90%;
}

#search-submit {
  background: none;
  border: none;
  float: right;
  width: 10%;
  font-size: 1.8rem;
  outline: 0;
  transition-duration: 0.3s;
  transition-property: all;
  cursor: pointer;
  max-width: 21px;
  margin: 0;
  padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
  <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

  <div id="search-wrapper">
    <div class="container">
      <div id="search-inner" class="o-bdr-top">
        <form role="search" method="get" id="search-form" class="clearfix" action="">
          <button id="search-submit"><i class="fas fa-search float-right"></i></button>
          <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
        </form>
      </div>
    </div>
  </div>
</div>

【问题讨论】:

  • #search-wrapper 必须是hidden 吗?如果我删除此属性 - 一切似乎都很好。
  • @Smollet777 你明白了,我也删除了我的答案(基于 setTimeout),因为这是一个肮脏的修复,既不能解决问题的根源,也不能解决良好的编程模式。

标签: javascript jquery html


【解决方案1】:

问题在于输入最初被隐藏并且浏览器阻止操作,例如关注隐藏元素。 常见的做法是使用组件off screen,而不是使用display: none(即:固定位置,负左和不透明度=== 0 或隐藏可见性)。

使用 setTimeout(在这种情况下是不确定的)是一种不好的做法,应该避免。

【讨论】:

  • 为什么您认为setTimeout() 在这种情况下是一种不好的做法? 而不是使用 display: none 你在哪里看到这个角色?
  • @ZakariaAcharki 仅仅是因为我们无法确定客户的互联网速度/计算能力。延迟可能不够。
  • 当作者已经使用opacity: 0;visibility: hidden; 时,您基于display: none 更改为不透明度或可见性的解决方案将被隐藏!你能给我们一个工作小提琴吗?
  • 抱歉我的错,可见性也会妨碍焦点,所以屏幕外黑客可以在不改变可见性的情况下工作。
  • @ZakariaAcharki toggleClass 并不总是花费相同的时间。事实上,jquery 在处理这些方法时提供了可以使用的承诺。另外 setTimeout 不保证实时执行延迟
【解决方案2】:

(来自官方文档)注意只在可见的元素上使用 .focus()。

您只需等待toggleClass() 触发的切换结束,#search-input 输入将可见,然后您可以对输入执行焦点。

由于toggleClass() 方法没有complete 回调,因此您可以使用setTimeout() 来表示:

setTimeout(function() {
    $('#search-input').focus();
}, 100);

$('#search-input').focus();

$('#search-btn').on('click', function() {
  $(this).toggleClass('active');
  $('#search-wrapper').toggleClass('visible');

  if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
  }

  if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
  }
  setTimeout(function() {
    $('#search-input').focus();
  }, 100);
});
#menu-side {
  width: 200px;
  float: right;
  position: static;
  z-index: 10;
  margin-right: 15px;
  margin-top: 15px;
}

#search-btn {
  background: red;
  border: none;
  font-size: 1.8rem;
  cursor: pointer;
  outline: 0;
  position: relative;
  display: block;
  width: 40px;
  height: 40px;
  transition-duration: 0.3s;
  transition-property: all;
}

#search-wrapper {
  width: 100%;
  position: absolute;
  top: 90px;
  left: 0;
  right: 0;
  opacity: 0;
  visibility: hidden;
  transition-duration: 0.3s;
  transition-property: all;
}

#search-wrapper.visible {
  opacity: 1;
  visibility: visible !important;
}

#search-inner {
  background: #e5e5e5;
  padding: 35px 80px;
}

#search-input {
  border: none;
  background: none;
  font-size: 1.8rem;
  line-height: 1.8rem;
  color: black;
  float: left;
  width: 90%;
}

#search-submit {
  background: none;
  border: none;
  float: right;
  width: 10%;
  font-size: 1.8rem;
  outline: 0;
  transition-duration: 0.3s;
  transition-property: all;
  cursor: pointer;
  max-width: 21px;
  margin: 0;
  padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
  <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

  <div id="search-wrapper">
    <div class="container">
      <div id="search-inner" class="o-bdr-top">
        <form role="search" method="get" id="search-form" class="clearfix" action="">
          <button id="search-submit"><i class="fas fa-search float-right"></i></button>
          <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
        </form>
      </div>
    </div>
  </div>
</div>

【讨论】:

  • 在另一个答案下面的另一个评论中,toggleClass 和 setTimeout 都没有你可以依赖的真正时间。使用屏幕外元素或 jquery 承诺 ($("#myId").toggleClass('fadeOut',600).promise().done(...mymethod) 更加简洁和可靠
  • @MosèRaguzzini 感谢您的干预,.promise() 需要 jQuery-UI 我不想在这里建议,您可以发布一个很酷的有效答案。
【解决方案3】:

我建议使用display 而不是visibility/opacity 并切换类,默认情况下您可以简单地使用display: none,然后使用jQuery toggle() 方法切换显示,然后焦点将起作用:

$('#search-input').focus();

$('#search-btn').on('click', function() {
  $(this).toggleClass('active');
  $('#search-wrapper').toggle();
  $('#search-input').focus();

  if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
  }

  if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
  }
  $('#search-input').toggleClass('active').focus();
});
#menu-side {
  width: 200px;
  float: right;
  position: static;
  z-index: 10;
  margin-right: 15px;
  margin-top: 15px;
}

#search-btn {
  background: red;
  border: none;
  font-size: 1.8rem;
  cursor: pointer;
  outline: 0;
  position: relative;
  display: block;
  width: 40px;
  height: 40px;
  transition-duration: 0.3s;
  transition-property: all;
}

#search-wrapper {
  width: 100%;
  position: absolute;
  top: 90px;
  left: 0;
  right: 0;
  display: none;
  transition-duration: 0.3s;
  transition-property: all;
}

#search-inner {
  background: #e5e5e5;
  padding: 35px 80px;
}

#search-input {
  border: none;
  background: none;
  font-size: 1.8rem;
  line-height: 1.8rem;
  color: black;
  float: left;
  width: 90%;
}

#search-submit {
  background: none;
  border: none;
  float: right;
  width: 10%;
  font-size: 1.8rem;
  outline: 0;
  transition-duration: 0.3s;
  transition-property: all;
  cursor: pointer;
  max-width: 21px;
  margin: 0;
  padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
  <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

  <div id="search-wrapper">
    <div class="container">
      <div id="search-inner" class="o-bdr-top">
        <form role="search" method="get" id="search-form" class="clearfix" action="">
          <button id="search-submit"><i class="fas fa-search float-right"></i></button>
          <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
        </form>
      </div>
    </div>
  </div>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-20
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    相关资源
    最近更新 更多