Dynamicznie dodany element - stop bubbling

Dynamicznie dodany element - stop bubbling
R7
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 36
0

Witam
Toczę nierówną walkę z dynamicznie dodawanymi przyciskami. Pojawiają się one po przeładowaniu strony przez Ajax w wyniku akcji na kontrolce select.
Żebym mógł je obsłużyć, muszę je wcześniej delegować do document:

Kopiuj
$(document).on('click','.button1', function() {
// some code...
});

W ten sam sposób jest obsłużony drugi przycisk (button2). Obydwa przyciski po kliknięciu wyświetlają stworzony ręcznie popup.:

Kopiuj
<div id="popup_confirm_main" class="popup_confirm_main">
    <div id="popup_confirm" class="popup_confirm">

        <div id="popup_confirm_text" class="popup_confirm_text">SOME TEXT</div>
        <div id="popup_confirm_btn_ok_div" class="popup_confirm_btn_ok_div">
            <button type="button" id="popup_confirm_btn_ok" class="button-alert-normal" name="popup_confirm_btn_ok">
                OK
            </button>
        </div>
        <div id="popup_confirm_btn_cancel_div" class="popup_confirm_btn_cancel_div">
            <button type="button" id="popup_confirm_btn_cancel" class="button-cancel-normal" name="popup_confirm_btn_cancel">
                ANULUJ
            </button>
        </div>

    </div>
</div>

button1:

Kopiuj
$(document).on('click','.button1', function() {

showMonitAlert(); // wyświetlenie popup

if($('.popup_confirm').length > 0){
             
       $(document).one('click','.popup_confirm_btn_ok_div', function(){        
        $('.popup_confirm_main').fadeOut(200);
        alert('jestem button1');
});

$(document).one('click','.popup_confirm_btn_cancel_div', function(){
        $('.popup_confirm_main').fadeOut(200);
        
      });
      }
        
});

button2:

Kopiuj
$(document).on('click','.button2', function() {

showMonitAlert(); // wyświetlenie popup

if($('.popup_confirm').length > 0){
             
       $(document).one('click','.popup_confirm_btn_ok_div', function(){        
        $('.popup_confirm_main').fadeOut(200);
        alert('jestem button2');
});

$(document).one('click','.popup_confirm_btn_cancel_div', function(){
        $('.popup_confirm_main').fadeOut(200);
        
      });
      }
        
});

I teraz: Wciskam przycisk button1, w wyświetlonym popupie wciskam przycisk popup_confirm_btn_cancel_div, popup się zamyka.
Następnie wciskam button2, pojawia się popup, wciskam popup_confirm_btn_ok_div i wtedy w wyniku bubblingu (tak myślę) wywołuje mi najpierw
zdarzenie z button1 czyli wyświetla alert: jestem button1 a następnie z button2 alert: jestem button2.
Zjawisko to nie występuje, kiedy nie korzystam z przycisku popup_confirm_btn_cancel_div w popup.
Próbowałem już event.preventDefault(), eventStopPropagation(), event.stopImmediatePropagation() oraz return false - nie działa.
Czy spotkał się ktoś z Szanownych Kolegów z takim problemem i udało mu się go rozwiązać?

Xarviel
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 847
0

Żeby rozwiązać problem w taki najprostszy sposób, musisz usuwać wszystkie niewykorzystane eventy przed zamknięciem popupa (https://api.jquery.com/off/).

Kopiuj
$(document).on('click.some_action', 'popup_confirm_btn_ok_div', function() { // <-- ustawiamy nazwę eventu .some_action
  //
});

$(document).off('click.some_action'); // <-- usuwamy event po nazwie .some_action
pablop76
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 70
0

Powtarzasz kod. Użyłbym e.target i sprawdził co klikam. I za pomocą switch ogrywał kliknięcie.
demo

R7
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 36
0

Xarviel, twój sposób zablokuje mi przycisk, jeśli będę chciał jeszcze raz z niego skorzystać to będę musiał przeładować stronę.
pablop76, raczej dobrze zaimplementowałem twoje rozwiązanie ale ono nie usuwa/zatrzymuje bubblingu. W twoim rozwiązaniu przyciski btn1 i btn2 nie pojawiają się dynamicznie - a to jest kluczowa sprawa.

Xarviel
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 847
0
rafik73 napisał(a):

Xarviel, twój sposób zablokuje mi przycisk, jeśli będę chciał jeszcze raz z niego skorzystać to będę musiał przeładować stronę.

A w którym miejscu usuwasz te eventy? Bo faktycznie jeśli robisz to w złym miejscu to może coś się psuć.

pablop76
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 70
0

Edytowałem demo
Ty zapinasz klik na document więc tu dochodzi chyba do przechwytywania a nie bąbelkowania

R7
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 36
0

@Xarviel: blokuję je w przypadku naciśnięcia przycisku cancel.

R7
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 36
0

@pablop76: Na czym dokładnie miało by to polegać i czy jest na to jakieś remedium? Zapinam na document ze względu na dynamicznie ładowane elementy.

pablop76
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 70
0

@rafik73:
Tak jak napisałem wcześniej. Sprawdź co zostało kliknięte (event.target) i wykonaj akcję jeżeli to jest właściwy element

R7
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 36
0

@pablop76: Jest ok, musiałm troszkę "nagiąć" do swoich warunków, szczególnie fragment z obsługą klika:

Kopiuj
$(document).on('click', function(e) {
    let cn = e.target;
    if(cn.getAttribute('class') != null){
    executeClick(cn); 
}
});

Musiałem dać ifa z nullem bo łapało mi klik gdziekolwiek klikałem.

Nie działała mi linijka:

Kopiuj
let cn = $(event.target);

no i w funkcji showMonitAlert linijka:

Kopiuj
const el = cn.attr('class');

generowała błąd, że attr nie jest funkcją.
Ale po tych drobnych zmianach adaptacyjnych działa super. Wielkie dzięki za naprowadzenie na właściwą drogę.

Xarviel, również wielkie dzięki.

P.S. Nie macie wrażenia, że za badzo miksuję JS z JQuery? Którą technologię preferujecie?

pablop76
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 70
0

P.S. Nie macie wrażenia, że za badzo miksuję JS z JQuery? Którą technologię preferujecie?
javascript

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.