Как вызвать событие изменения класса, когда код, который изменяет класс, недоступен - PullRequest
0 голосов
/ 04 октября 2018

Мне нужно вызвать событие в классе, когда этот класс изменяется. Единственное известное изменение, замеченное в DOM, - это то, что класс получает второй класс (скажем, класс «выбираемый», он становится «выбираемым выбранным»)

https://jsfiddle.net/zn1xj7wb/1/

В этой скрипке могут быть выбраны синие квадраты и изменение css происходит при изменении класса (добавляет «выбранный») Цель состоит в том, чтобы иметь возможность сделать что-то в другой частимоего кода так:

$("[class*='selectable']").on('classChange', function() {
    //do stuff like change the background color or add text
    //alert("this selectable div has been selected");      
});

Я не уверен, как поступить, поскольку jquery не имеет события для изменения класса, и я не могу добавить триггер "classChange" к скрытой части кода, которая добавляет иудаляет «выбранный» класс, чтобы он мог быть выбран моим кодом.

РЕДАКТИРОВАТЬ: причина, по которой мне нужен триггер для изменения класса, заключается в том, что это график, который использует первый щелчок для измененияclass (выберите узел графика), и поэтому первый щелчок по div этого класса не регистрируется, только во второй раз, и мне не нужно дважды щелкать, чтобы // сделать что-то.

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Я не уверен, что понимаю вашу проблему, но я хотел бы прикрепить событие к документу, например так:

$(document).on("click",".selectable", function() {
//do your stuff here
});

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

$(document).on("click",".selectable", function() {
  if($(this).hasClass("selected")){
        $(this).removeClass("selected")
        //do your stuff
  }else{
       $(this).addClass("selected")
       //do some different stuff
  }
});
0 голосов
/ 04 октября 2018

РЕДАКТИРОВАТЬ: Хорошо, так что это не будет работать (см. Комментарии).Однако мне удалось придумать другое решение.Хотя вы можете регулярно сканировать весь DOM на наличие изменений, используя внешнюю библиотеку, в этом случае вы можете сделать приложение более производительным, ограничив область действия только выбираемыми элементами.

Что делает следующий код (ссылка jsfiddleниже) это взять начальную выборку выбранных элементов на странице.Затем, один раз за цикл событий, он повторно выбирает эти выбранные элементы.Для каждого элемента, которого там раньше не было, запускается пользовательское событие:

$(document).ready(function() {
  $('.selectable').on('customSelectEvent', (e) =>{
    console.log("hello, world!");
    // Do your stuff here
  });
  // Get the starting list of selectable elements
  var selecteds = $('.selected');
  // Using setInterval to make sure this runs at the back of the event loop
  setInterval(() => {
    let loopSelecteds = $('.selected');
    $.each(loopSelecteds, function(loopIndex, loopSelected) {
      let alreadySelected = false;
      $.each(selecteds, function(index, selected) {
        if ($(selected).get(0) === $(loopSelected).get(0)) {
          alreadySelected = true;
        }
      });
      if (!alreadySelected) {
        $(loopSelected).trigger('customSelectEvent');
      }
    });
    selecteds = loopSelecteds;
  }, 0);
})

Здесь необходимо отметить несколько вещей:

  • setInterval(()=>{...}, 0) используется для приведения этой операциив конце цикла событий, поэтому он будет оцениваться один раз за ход.При этом соблюдайте осторожность, поскольку, если вы делаете это слишком много, это может повлиять на производительность.
  • $().get(0) === $().get(0) проверяет элементы DOM, чтобы определить, являются ли они одним и тем же элементом.Мы не хотим запускать событие, если они есть.Предоставлено: https://stackoverflow.com/a/19546658/10430668
  • Я использую здесь $.each(), потому что он достаточно умен, чтобы обрабатывать коллекции объектов jQuery, чего не было в других циклах (без некоторой путаницы).
  • Кто-то заметилотметьте меня на этом, но вы, возможно, сможете разместить пользовательский обработчик событий в другом месте кода.

JS Fiddle: https://jsfiddle.net/zn1xj7wb/15/

Это мой первый ответ, который нене работает в этом случае использования.Я включу его так, чтобы пользователи, которые не так застряли, могли извлечь из этого пользу:

Есть ли какая-то причина, по которой вы не можете привязать другого слушателя к событию click и проверить, есть ли у него право?учебный класс?Такие как:

$(document).ready(function() {
    $(".selectable").click((e) => {
        const currentElement = $(e.currentTarget);
        // This is a little tricky: don't run the code if it has the class pre-setTimeout()
        if (currentElement.hasClass('selected')) {
            return;
        }
        // Using setTimeout to cast the evaluation to the end of the event loop
        setTimeout(()=>{
             if (currentElement.hasClass('selected')) {
                 // Do your things here.
                 alert("selected!");
             }
        },0);
    })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...