jQuery appendTo makes duplicate items

598 views Asked by At

I'm new to jQuery and I managed to figure out most of what I wanted it to do, but I've been having problems.

When the user scrolls down, the menu bar goes with them. However, the search form appears multiple times. If the user scrolls up and down multiple times, the many search forms will fill up the entire page.

This is what my script looks like now:

<script>
$(document).ready(function () {

var menu = $('.yamm');
var origOffsetY = menu.offset().top;

function scroll() {
    if ($(window).scrollTop() >= origOffsetY) {
        $('.yamm').addClass('sticky');
        $('.content').addClass('menu-padding');
        $('<form class="form-inline"><input type="text" class="form-control" placeholder="Search over 80,000 products" style="width: 80%;"><button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button></form>').appendTo('.searchmenu'); 
    } else {
        $('.yamm').removeClass('sticky');
        $('.content').removeClass('menu-padding');
        $('.searchmenu .form-inline').remove();
    }

}

document.onscroll = scroll;

});</script>

What am I missing to make the search form appear only once?

Thank you for your help.

2

There are 2 answers

0
Juanma On BEST ANSWER

I recommend to show/hide the form instead of creating a new one each time the user scrolls down from the top. With this approach you keep all your html in the same file.

Html file:

<form id="search-form" class="form-inline"><input type="text" class="form-control" placeholder="Search over 80,000 products" style="width: 80%;"><button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button></form>

Script:

<script>
    $(document).ready(function () {

        var menu = $('.yamm');
        var origOffsetY = menu.offset().top;
        var searchForm = $('#search-form');

        function scroll() {
            if ($(window).scrollTop() >= origOffsetY) {
                $('.yamm').addClass('sticky');
                $('.content').addClass('menu-padding');
                searchForm.show(); 
            } else {
                $('.yamm').removeClass('sticky');
                $('.content').removeClass('menu-padding');
                searchForm.hide();
            }

        }
        // Hide the form on load, or you can just set a display:none with CSS
        scroll();

        document.onscroll = scroll;
    });
</script>

You can also make the form fadeIn/fadeOut, instead of show/hide.

0
Karl-André Gagnon On

That line :

$('<form class="form-inline"><input type="text" class="form-control" placeholder="Search over 80,000 products" style="width: 80%;"><button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button></form>')

create multiple elements. Instead of creating 1 element on the scroll, create it when you are instantiating the application and append it/detach it:

$(document).ready(function () {

var menu = $('.yamm');
var origOffsetY = menu.offset().top;
//Create it:
var $searchForm = $('<form class="form-inline"><input type="text" class="form-control" placeholder="Search over 80,000 products" style="width: 80%;"><button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></button></form>');

function scroll() {
    if ($(window).scrollTop() >= origOffsetY) {
        $('.yamm').addClass('sticky');
        $('.content').addClass('menu-padding');
        //Use it:
        $searchForm.appendTo('.searchmenu'); 
    } else {
        $('.yamm').removeClass('sticky');
        $('.content').removeClass('menu-padding');
        //Remove it:
        $searchForm.detach();
    }

}

document.onscroll = scroll;

});