简体   繁体   中英

Click button trigger input to appear with focus

I have a hidden search bar that is made visible when you click on a button. When the search bar appears I would like the input to already have focus, so the user can immediately start typing.

I'm using $('#search-input').focus(); to try and achieve this on click but it isn't working.

Here is a JSFiddle . Click on the red box to trigger the search bar.

My Code:

 $('#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>

(From the official documentation) Take care to only use .focus() on elements that are visible.

You need just to wait for the toggle fired by toggleClass() to end so the #search-input input will be visible then you could perform the focus to the input.

Since toggleClass() method has no complete callback you could use setTimeout() for this like:

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>

The problem resides on input being hidden initially and browsers prevent operation such as focus on hidden elements. Common pratice, instead of using display: none , is to take the component off screen (IE: Fixed position with negative left and opacity === 0 or visibility hidden).

Using setTimeout (which in this case in undeterministic) is a bad pratice and should be avoided.

I suggest the use of display instead of visibility/opacity and toggling the classes, you could use simply display: none by default then toggle the display using the jQuery toggle() method then the focus will work:

 $('#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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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