Rainier laan
Rainier laan

Reputation: 1130

jQuery width input field bug

I made a custom search block that slides out when you click on the search icon. When the search block opens for the first time there is a bug where the input field becomes 100% width of the whole screen for 1 second instead of only the search block.

enter image description here

$(document).ready(function() {

    var search_block = $('.search-block');
    var search_block_overlay = $('.search-block-overlay');

    $('#dashboard-sub-search').on('click', function() {

        search_block.animate({width: "toggle"}, 300);
        search_block.addClass("search-block-active");
        search_block_overlay.addClass("search-block-overlay-active");
    });

    $('#close-search').on('click', function() {
        search_block.animate({width: "toggle"}, 300);
        search_block.css({'display': 'none'});
        search_block_overlay.removeClass("search-block-overlay-active");
    });
});
.search-block {
    display: none;
}

.search-header {
    display: flex;
}

.search-form {
    width: 100%;
}

.search-content {
    margin-left: 38px;
}

.close-search {
    cursor: pointer;
    font-size: 36px;
}

.search-block-active {
    display: block;
    background: white;
    position: absolute;
    width: 600px;
    height: 100vh;
    top: 0;
    padding: 30px;
}
.search-block-overlay {
    display: none;
}
.search-block-overlay-active {
    display: block;
    background-color: rgba(9, 30, 66, 0.54);
    width: calc(100% - 600px);
    height: 100vh;
    position: absolute;
    top: 0;
    right: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.css">


<div class="dashboard-sub-top-search mt-4">
    <i id="dashboard-sub-search" class="fa fa-search dashboard-sub-search"></i>
</div>

<div class="search-block">
    <div class="search-header">
        <div class="close-search-block mr-3">
            <i id="close-search" class="fa fa-times close-search"></i>
        </div>
        <div class="search-form">
            <input type="text" class="form-control" placeholder="Search">
        </div>
    </div>
    <div class="search-content mt-5">
        <h6>Recent search history</h6>
    </div>


</div>
<div class="search-block-overlay"></div>

After the initial opening it is fine. It occurs only when it gets opened for the first time. I made the block with the following code:

How can I fix this?

Upvotes: 1

Views: 67

Answers (1)

Heretic Monkey
Heretic Monkey

Reputation: 12114

Here's the code, working as desired (I hope).

What I did was move the code for the search-block-active (except the display property) out of that class and to search-block (same with search-block-overlay).

This may seem counter-intuitive: search-block has display: none, so why would it matter if it has a width defined? The trick is in the way animate works. It looks at the defined width of the block it's animating and basically calculates the steps (interim widths) needed to get from 0 to that width, and sets the width to those steps every x milliseconds, over the total you've given it.

So, now that we've told jQuery how wide it will be, it can calculate the correct amount to animate in each step.

$(document).ready(function() {

    var search_block = $('.search-block');
    var search_block_overlay = $('.search-block-overlay');

    $('#dashboard-sub-search').on('click', function() {

        search_block.animate({width: "toggle"}, 300);
        search_block.addClass("search-block-active");
        search_block_overlay.addClass("search-block-overlay-active");
    });

    $('#close-search').on('click', function() {
        search_block.animate({width: "toggle"}, 300);
        search_block.css({'display': 'none'});
        search_block_overlay.removeClass("search-block-overlay-active");
    });
});
.search-block {
    display: none;
    background: white;
    position: absolute;
    width: 600px;
    height: 100vh;
    top: 0;
    padding: 30px;
}

.search-header {
    display: flex;
}

.search-form {
    width: 100%;
}

.search-content {
    margin-left: 38px;
}

.close-search {
    cursor: pointer;
    font-size: 36px;
}

.search-block-active {
    display: block;
}
.search-block-overlay {
    display: none;
    background-color: rgba(9, 30, 66, 0.54);
    width: calc(100% - 600px);
    height: 100vh;
    position: absolute;
    top: 0;
    right: 0;
}
.search-block-overlay-active {
    display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.css">


<div class="dashboard-sub-top-search mt-4">
    <i id="dashboard-sub-search" class="fa fa-search dashboard-sub-search"></i>
</div>

<div class="search-block">
    <div class="search-header">
        <div class="close-search-block mr-3">
            <i id="close-search" class="fa fa-times close-search"></i>
        </div>
        <div class="search-form">
            <input type="text" class="form-control" placeholder="Search">
        </div>
    </div>
    <div class="search-content mt-5">
        <h6>Recent search history</h6>
    </div>


</div>
<div class="search-block-overlay"></div>

Upvotes: 1

Related Questions