Почему моя функция обратного вызова умножается на каждый клик? - PullRequest
0 голосов
/ 04 февраля 2020

Итак, я сделал простую функцию обратного вызова, но по какой-то причине, каждый раз, когда я нажимаю кнопку «принять», функция обратного вызова запускается дважды.

Почему это происходит, и я должен использовать что-то еще для этой цели, обещания, может быть?

Вот пример jsfiddle https://jsfiddle.net/p7oq63gL/

Вот js

function confirm(options = {}, o, run){


$('.toast-container').fadeIn();
  $('.toast.confirm .toast-header strong').html(options['title']);
  $('.toast.confirm .submit-toast').addClass(options['cls']);
  $('.toast.confirm .toast-body').html(options['message']);
  $('.toast.confirm').toast({
    autohide: false
  }).removeClass('invisible').toast('show');

  $('.submit-toast').on('click', function(){
    run(o);
    $('.toast-container').fadeOut();
    $('.toast.confirm').addClass('invisible');
  });

  $('[data-dismiss-toast]').on('click', function(){
    $('.toast-container').fadeOut();
    $('.toast.confirm').addClass('invisible');
  });
}
$(document).ready(function(){
$(document).on('click', '#banner-message button', function(){
        var toTrashEl = $(this);
        confirm({
            'message': 'Are you sure you want to press this button?</b>',
            'title': 'Ametid',
            'cls': 'bg-danger'
          }, [toTrashEl], function(o){
              o[0].parents('.slideLeft').addClass('removed');
            setTimeout(function(){
                o[0].parents('.slideLeft').remove();
            }, 500);
            $('#banner-message').prepend('<p>Hello World</p>');
          });
    });

});

1 Ответ

0 голосов
/ 04 февраля 2020

Каждый раз, когда запускается функция confirm, вы добавляете нового слушателя к submit-toast и data-dismiss-toast в

  $('.submit-toast').on('click', function(){
    run(o);
    $('.toast-container').fadeOut();
    $('.toast.confirm').addClass('invisible');
  });

  $('[data-dismiss-toast]').on('click', function(){
    $('.toast-container').fadeOut();
    $('.toast.confirm').addClass('invisible');
  });

Когда запускается confirm, удалите предыдущих слушателей, если они существуют:

  $('.submit-toast').off('click').on('click', function(){
    run(o);
    $('.toast-container').fadeOut();
    $('.toast.confirm').addClass('invisible');
  });

  $('[data-dismiss-toast]').off('click').on('click', function(){
    $('.toast-container').fadeOut();
    $('.toast.confirm').addClass('invisible');
  });

function confirm(options = {}, o, run) {
  $('.toast-container').fadeIn();
  $('.toast.confirm .toast-header strong').html(options['title']);
  $('.toast.confirm .submit-toast').addClass(options['cls']);
  $('.toast.confirm .toast-body').html(options['message']);
  $('.toast.confirm').toast({
    autohide: false
  }).removeClass('invisible').toast('show');

  $('.submit-toast').off('click').on('click', function() {
    run(o);
    $('.toast-container').fadeOut();
    $('.toast.confirm').addClass('invisible');
  });

  $('[data-dismiss-toast]').on('click', function() {
    $('.toast-container').fadeOut();
    $('.toast.confirm').addClass('invisible');
  });
}
$(document).ready(function() {
  $(document).on('click', '#banner-message button', function() {
    var toTrashEl = $(this);
    confirm({
      'message': 'Are you sure you want to press this button?</b>',
      'title': 'Ametid',
      'cls': 'bg-danger'
    }, [toTrashEl], function(o) {
      console.log('confirm callback running');
      o[0].parents('.slideLeft').addClass('removed');
      setTimeout(function() {
        o[0].parents('.slideLeft').remove();
      }, 500);
    });
  });

});
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#banner-message {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  font-size: 25px;
  text-align: center;
  transition: all 0.2s;
  margin: 0 auto;
  width: 300px;
}

.toast-container {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.4);
  z-index: 10000;
}

.toast {
  z-index: 1051;
  background: #fff;
}

.toast-header {
  font-size: 18px;
  font-weight: 400;
}

.toast-type {
  width: 30px;
  height: 30px;
  border-radius: 20px;
  font-size: 1em;
}

.bg-dng {
  background: #F44336;
}

.bg-info {
  background: #00BCD4;
  ;
}

.bg-success {
  background: #4caf50;
  ;
}

.center {
  top: 50%;
  left: 50%;
  background: white;
  transform: translate(calc(-50% + 0.5px), calc(-50% + 0.5px));
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}

#banner-message.alt {
  background: #0084ff;
  color: #fff;
  margin-top: 40px;
  width: 200px;
}

#banner-message.alt button {
  background: #fff;
  color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.js"></script>
<div id="banner-message">
  <button>Change color</button>
</div>
<div style="display: none;" class="toast-container">
  <div class="toast message position-fixed m-3 right bottom invisible" role="alert" aria-live="assertive" aria-atomic="true">
    <div class="toast-header p-3">
      <strong class="mr-auto">Veateade</strong>
      <button type="button" class="ml-2 close" data-dismiss-toast="toast" aria-label="Sulge">
            &times;
          </button>
    </div>
    <div class="toast-body">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla quisquam exercitationem esse inventore minima modi est dolore iusto, fugiat quas eos tempora, soluta animi neque consequuntur! Nulla corrupti expedita dignissimos.
    </div>
  </div>
  <div class="toast confirm bg-white position-absolute m-3 invisible" role="alert" aria-live="assertive" aria-atomic="true">
    <div class="toast-header p-3">
      <strong class="mr-auto">Kinnitamine</strong>
      <button type="button" class="ml-2 close" data-dismiss-toast="toast" aria-label="Sulge">
            &times;
          </button>
    </div>
    <div class="toast-body text-center">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla quisquam exercitationem esse inventore minima modi est dolore iusto, fugiat quas eos tempora, soluta animi neque consequuntur! Nulla corrupti expedita dignissimos.
    </div>
    <div class="toast-footer mt-4 d-flex align-items-center justify-content-around">
      <button data-dismiss-toast="toast" class="exit-toast p-2 w-100 formBtn formExit text-white">DECLINE</button>
      <button class="submit-toast formBtn text-white p-2 w-100">ACCEPT</button>
    </div>
  </div>
</div>

Другим вариантом будет иметь один обработчик постоянных щелчков для каждого, но когда вызывается confirm, переназначается только функция обратного вызова, которая получает вызывается по клику:

let submitToastCallback = () => null;
$('.submit-toast').off('click').on('click', function() {
  $('.toast-container').fadeOut();
  $('.toast.confirm').addClass('invisible');
  submitToastCallback();
});

$('[data-dismiss-toast]').on('click', function() {
  $('.toast-container').fadeOut();
  $('.toast.confirm').addClass('invisible');
});

function confirm(options = {}, o, run) {
  $('.toast-container').fadeIn();
  $('.toast.confirm .toast-header strong').html(options['title']);
  $('.toast.confirm .submit-toast').addClass(options['cls']);
  $('.toast.confirm .toast-body').html(options['message']);
  $('.toast.confirm').toast({
    autohide: false
  }).removeClass('invisible').toast('show');
  submitToastCallback = run.bind(null, o);
}

let submitToastCallback = () => null;
$('.submit-toast').off('click').on('click', function() {
  $('.toast-container').fadeOut();
  $('.toast.confirm').addClass('invisible');
  submitToastCallback();
});

$('[data-dismiss-toast]').on('click', function() {
  $('.toast-container').fadeOut();
  $('.toast.confirm').addClass('invisible');
});

function confirm(options = {}, o, run) {
  $('.toast-container').fadeIn();
  $('.toast.confirm .toast-header strong').html(options['title']);
  $('.toast.confirm .submit-toast').addClass(options['cls']);
  $('.toast.confirm .toast-body').html(options['message']);
  $('.toast.confirm').toast({
    autohide: false
  }).removeClass('invisible').toast('show');
  submitToastCallback = run.bind(null, o);
}
$(document).ready(function() {
  $(document).on('click', '#banner-message button', function() {
    var toTrashEl = $(this);
    confirm({
      'message': 'Are you sure you want to press this button?</b>',
      'title': 'Ametid',
      'cls': 'bg-danger'
    }, [toTrashEl], function(o) {
      console.log('confirm callback running');
      o[0].parents('.slideLeft').addClass('removed');
      setTimeout(function() {
        o[0].parents('.slideLeft').remove();
      }, 500);
    });
  });

});
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#banner-message {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  font-size: 25px;
  text-align: center;
  transition: all 0.2s;
  margin: 0 auto;
  width: 300px;
}

.toast-container {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.4);
  z-index: 10000;
}

.toast {
  z-index: 1051;
  background: #fff;
}

.toast-header {
  font-size: 18px;
  font-weight: 400;
}

.toast-type {
  width: 30px;
  height: 30px;
  border-radius: 20px;
  font-size: 1em;
}

.bg-dng {
  background: #F44336;
}

.bg-info {
  background: #00BCD4;
  ;
}

.bg-success {
  background: #4caf50;
  ;
}

.center {
  top: 50%;
  left: 50%;
  background: white;
  transform: translate(calc(-50% + 0.5px), calc(-50% + 0.5px));
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}

#banner-message.alt {
  background: #0084ff;
  color: #fff;
  margin-top: 40px;
  width: 200px;
}

#banner-message.alt button {
  background: #fff;
  color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.js"></script>
<div id="banner-message">
  <button>Change color</button>
</div>
<div style="display: none;" class="toast-container">
  <div class="toast message position-fixed m-3 right bottom invisible" role="alert" aria-live="assertive" aria-atomic="true">
    <div class="toast-header p-3">
      <strong class="mr-auto">Veateade</strong>
      <button type="button" class="ml-2 close" data-dismiss-toast="toast" aria-label="Sulge">
            &times;
          </button>
    </div>
    <div class="toast-body">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla quisquam exercitationem esse inventore minima modi est dolore iusto, fugiat quas eos tempora, soluta animi neque consequuntur! Nulla corrupti expedita dignissimos.
    </div>
  </div>
  <div class="toast confirm bg-white position-absolute m-3 invisible" role="alert" aria-live="assertive" aria-atomic="true">
    <div class="toast-header p-3">
      <strong class="mr-auto">Kinnitamine</strong>
      <button type="button" class="ml-2 close" data-dismiss-toast="toast" aria-label="Sulge">
            &times;
          </button>
    </div>
    <div class="toast-body text-center">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla quisquam exercitationem esse inventore minima modi est dolore iusto, fugiat quas eos tempora, soluta animi neque consequuntur! Nulla corrupti expedita dignissimos.
    </div>
    <div class="toast-footer mt-4 d-flex align-items-center justify-content-around">
      <button data-dismiss-toast="toast" class="exit-toast p-2 w-100 formBtn formExit text-white">DECLINE</button>
      <button class="submit-toast formBtn text-white p-2 w-100">ACCEPT</button>
    </div>
  </div>
</div>
...