Problem z przyciskiem

0

Witam,
dodaje elementy do "koszyka" wraz z przyciskiem usuwania danej pozycji. Lecz przy dodaniu nowego produktu do koszyka przycisk dopiero działa po przeładowaniu strony. Nie uruchamia się w ogóle .click na przycisku.

 $('.removeFromCart').click(function(){
            var product_id = $(this).val();
            $.ajax({
                type: "post",
                url: url + '/remove/' + product_id,
                success: function (data) {
                                    $('.shopping-cart-counter').html(parseInt($('.shopping-cart-counter').html(),10)-1);
                                    if(data=='0'){
                                        $('#item{{$product->id}}').remove();
                                    }else{
                                        $('#item{{$product->id}} .item-qty').html(parseInt($('#item{{$product->id}} .item-qty').html(),10)-1);
                                    }
                },
                error: function (data) {
                    console.log('Error:', data);
                }
            });
    });
1

click podpinane jest do wszystkich elementów będących w drzewie DOM w momencie wywołania tej funkcji - wykorzystaj $(document).bind.

2

W momencie wywołania metody click, w twoim przypadku $('.removeFromCart').click(function() {}), jQuery wyciąga wszystkie elementy aktualnie znajdujące się na stronie i pasujące do selektora, po czym dodaje do nich handler. Możemy to podejrzeć:

$('#test').click(function() {})
console.dir($._data($('#test')[0], 'events'))

click.png

Nasz click jest bezpośrednio powiązany z tym konkretnym elementem. Jeżeli fizycznie usuniemy go z drzewa DOM, a później z palca, korzystając z narzędzi deweloperskich, wstawimy nowy element o takim samym id, to okaże się, że nie jest już do niego podpięte nasze zdarzenie click.

Po co to mówię? Otóż Ty podpinasz swoje zdarzenie click w momencie załadowania strony, co oznacza, że jQuery podepnie go tylko do elementów, które w momencie podpinania znajdują się na stronie. Jeżeli dojdzie nowy element (dodasz coś do koszyka) o klasie .removeFromCart to nie zostanie do niego nic podpięte, ponieważ w momencie podpinania nie było go fizycznie na stronie. Dlatego wszystko działa dopiero po odświeżeniu strony

Jak temu zaradzić? Możemy użyć trochę innego sposobu, czyli $('.parent').on('click', '.removeFromCart', function() {}), gdzie parent to musi być element, w którym zawierają się nasze dynamiczne elementy. Jeżeli użyjemy naszej nowej składni, to nasz obiekt z eventami będzie teraz wyglądał tak:
click2.png

Zgodnie z tym jak działa event bubbling i event capturing, jeżeli klikniesz w '.removeFromCart', który jest wewnątrz rodzica .parent, to również na nim zostanie wywołany click. jQuery sprawdzi, czy to co faktycznie zostało kliknięte pasuje do property selector i jeżeli tak to zostanie wywołany twój handler.

Dlatego dla dynamicznych elementów używaj $('.parent').on('click', '.removeFromCart', function() {}), a dla statycznych $('.removeFromCart').click(function() {}). Warto też nie podpinać wszystkiego do $(document). Nie potwierdziłem tego żadnymi testami, ale logika podpowiada, że ponieważ jest to podpięte najwyżej jak się da, to jQuery za każdym razem będzie to sprawdzał, co może uderzyć w wydajność, lepiej jest podpiąć tak blisko interesującego nas elementu jak to możliwe (w tym wypadku np. kontenera Twojego koszyka).

więcej o bubbling and capturing

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0