当无法更改类的代码时,如何触发类更改事件

时间:2018-10-04 16:31:38

标签: javascript jquery css events

该类更改时,我需要在该类上触发事件 DOM中唯一已知的变化是该类获得了第二个类(例如,该类是“ selectable”,它变为“ selectable selected”)

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

在此小提琴中,可以选择蓝色方块,并且当类更改时会发生css更改(添加“ selected”) 目标是能够在我的代码的另一部分中做类似的事情:

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

我不确定如何进行处理,因为jquery没有发生类更改的事件,因此无法将“ classChange”触发器添加到代码的隐藏部分,该隐藏部分添加和删除了“ selected”类以供选择根据我的代码。

编辑:之所以需要触发器来更改类,是因为它是一个图,它用完了第一次单击以更改类(选择图的节点),因此首先单击该图的div该类不会注册,只有第二次注册,而且我不必单击两次即可完成工作。

2 个答案:

答案 0 :(得分:0)

编辑:好的,所以将不起作用(请参阅评论)。但是,我能够提出另一种解决方案。虽然您可以使用外部库定期扫描整个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小提琴: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);
    })
})

答案 1 :(得分:0)

我不确定我是否理解您的问题,但是我要做的是将事件发送到文档,就像这样:

$(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
  }
});