Use jquery to target classes that are added dynamically?

吃可爱长大的小学妹 提交于 2019-12-11 19:24:10

问题


I have a slider (flexslider) that dynamically adds the class "flex-active-slide" to the active <li>.

I want to use jQuery to do something when a specific slide has the class "flex-active-slide." I tried the following, but it doesn't work because the .flex-active-class is added on the fly after this has already run:

if ( $('#slider li.about').is('.flex-active-slide')  ){  
   $('.nav li.about').show();
}

In my research, it seems I want to use on(), but all the examples I see relate it to an event like click() or hover(). This isn't triggered by anything like that -- the class just "appears." I can't figure out how to format it. Something like this...?

$(document).on('???',".flex-active-slide",  function() {
    $(".nav li.about").show();;
    })

I'm sure that is embarrassingly incorrect... I appreciate any help you can give!!

Note: I can't simply use CSS because the .nav I'm trying to affect is completely unrelated to the slider div.

UPDATE: Here is what appears to be the code in the flexslider.js that controls adding the flex-active-slide class. Is there anything here that suggests anything I could do?

 slider.flexAnimate = function(target, pause, override, withSync, fromNav) {

      if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev";

      if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) {
        if (asNav && withSync) {
          var master = $(vars.asNavFor).data('flexslider');
          slider.atEnd = target === 0 || target === slider.count - 1;
          master.flexAnimate(target, true, false, true, fromNav);
          slider.direction = (slider.currentItem < target) ? "next" : "prev";
          master.direction = slider.direction;

          if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) {
            slider.currentItem = target;
            slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
            target = Math.floor(target/slider.visible);

          } else {
            slider.currentItem = target;
            slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
            return false;
          }
        }
...

回答1:


The brute force way is to poll it.

var poll = function(){
  if ( $('#slider li.about').is('.flex-active-slide')  ){  
    $('.nav li.about').show();
  } else {
    setTimeout(poll,500); // Sets how often to check in milliseconds
  }
}

That code will keep checking for the element every half a second, and then stop checking once it sees the element for the first time. If you want to keep checking for the element whenever the page is open, take the setTimeout out of the else.

The smarter way to do it is with a callback. Flexslider has a few different callbacks. I'm using the after callback here, this will execute after each slide animates on.

$(document).ready(function() {
  $('.flexslider').flexslider({
    after: function(slider) {
      if($('#slider li.about').is('.flex-active-slide')) {
        $('.nav li.about').show();
      }
    }
  });
});

You have to call this on the correct element. I'm using .flexslider, but you will need to specify an identifier for your flexslider instance.

You can replace if($('#slider li.about').is('.flex-active-slide')) with something like if(slider.currentSlide == 3) to trigger your show() event after the third slide. Flexslider has more details about this in the advanced section on their home page. http://www.woothemes.com/flexslider/




回答2:


You can use MutationObservers to detect changes to the DOM: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver. They're not as straightforward as, say, jQuery, but immensely useful.




回答3:


try to use the hasClass method instead of is.

example:

if ( $('#slider li.about').hasClass('flex-active-slide')  ){  
   $('.nav li.about').show();
}



回答4:


If you don't mind messing with the jQuery, you could use the jquery.hook plugin and perhaps try the following:

$.hook('addClass');
$('#slider').delegate('onaddClass', function() {
    if ( $(this).hasClass('flex-active-slide') )
    {
        $(".nav li.about").show();
    }
});

For full disclosure though, I haven't tried this and I'm not sure if it'll impact the performance of your page :/ Let me know if you try this and how it goes..




回答5:


Editing the flexslider script would be the simplest solution imho (because I haven't used Flexslider myself). Find the line where the flex-active-slide` class is toggled (which is probably also an if else clause), and input your function directly there.

If you don't want to edit the file, there is another, more 'performance-heavy' way using the good ol' setInterval function. You'd have something like:

setInterval(function() {
  if ( $('#slider li.about').hasClass('.flex-active-slide')  ){  
     $('.nav li.about').show();
  };
},200);

This will fire a function every 200 milliseconds checking if your li.about has the class.

There is also a new way of doing this, called webworkers, basically scripts that work in the background and eliminate the need to use a sluggish setInterval(). I haven't investigated it yet, but it seems pretty interesting: The MDN Documentation gives a good deal of info about it.



来源:https://stackoverflow.com/questions/18245041/use-jquery-to-target-classes-that-are-added-dynamically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!