I'm new to coding and I'm trying to get my searchbar to toggle when hovering over a button. I want it to toggle with a delay. Here's what I've come up with so far:
$( document ).ready(function() {
console.log( "ready!" );
$("#search-form").hover(
function(){
$("#search-input").delay(700).toggleClass("collapse");
}
)
});
And here the HTML:
<form id="search-form" style="display:flex-end;" class="form-inline my-2 my-lg-0">
<button class="btn btn-search" type="submit" data-toggle="collapse">
</button>
<input id="search-input" class="collapse form-control" type="text" placeholder="Search..." name="search">
</form>
So the toggle works, but it seems to just ignore the delay. Where did I go wrong? Not sure if relevant, but I'm using bootstrap 4.5.
Appreciate the help!
From the jQuery API documentation:
The .delay() method is best for delaying between queued jQuery effects. Because it is limited—it doesn't, for example, offer a way to cancel the delay—.delay() is not a replacement for JavaScript's native setTimeout function, which may be more appropriate for certain use cases. (https://api.jquery.com/delay/)
It is not perfectly documented (as far as I can tell), but toggleClass()
is not a function that uses the built-in effects queue.
Easiest solution is to use the vanilla window.setTimeout()
function:
$( document ).ready(function() {
console.log("ready!");
$("#search-form").hover(function() {
window.setTimeout(function() {
$("#search-input").toggleClass("collapse");
}, 700)
});
});
PS: The above solution, while it will technically work, it will not behave how you'd expect to, when you're moving fast on/off the form with the mouse pointer. See the simulation below:
$( document ).ready(function() {
console.log("ready!");
$("#search-form").hover(function() {
window.setTimeout(function() {
$("#search-input").toggleClass("collapse");
}, 700)
});
});
/* Border - just to highlight the form */
#search-form {
border: 2px solid red;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="search-form" style="display:flex-end;" class="form-inline my-2 my-lg-0">
<button class="btn btn-search" type="submit" data-toggle="collapse">BUTTON
</button>
<input id="search-input" class="collapse form-control" type="text" placeholder="Search..." name="search">
</form>
Instead, you might want to opt for a CSS-only solution which avoids the above misbehavior automatically (using the transition
CSS property and its delay
option):
// No JavaScript needed :)
/* Border - just to highlight the form */
#search-form {
border: 2px solid red;
}
#search-form #search-input {
visibility: hidden;
transition: visibility 0s linear 0.7s;
}
#search-form:hover #search-input {
visibility: visible;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<form id="search-form" style="display:flex-end;" class="form-inline my-2 my-lg-0">
<button class="btn btn-search" type="submit" data-toggle="collapse">BUTTON
</button>
<input id="search-input" class="form-control" type="text" placeholder="Search..." name="search"><!-- NOTE: no `collapse` class here anymore -->
</form>