简体   繁体   English

如何防止jQuery函数被多次初始化(涉及的重复行为)?

[英]How to prevent jQuery function from being initialized more than once (Drupal behaviours involved)?

My goal: To enable a user to load a template (which contains preset jquery, html and css) to allow them to click one of five dots to trigger an animation on an image. 我的目标:使用户能够加载模板(包含预设的jquery,html和css),以允许他们单击五个点之一以触发图像上的动画。

My issue: When I load more than one of these templates to my page, my animation value (margin-left in this case) applies double the number of times that there is an instance of this template on the page. 我的问题:当我在页面上加载多个这些模板时,我的动画值(在这种情况下为margin-left)应用的次数是页面上此模板实例的两倍。 If my template is loaded twice, the margin-left sets to a value, jumps to the correct value, then back before finally setting on the correct value. 如果我的模板加载了两次,则左边距设置为一个值,跳至正确的值,然后返回,最后设置为正确的值。 This means that if I was to add 10 instances to the page, it would take 20 times as long to get that last value. 这意味着,如果我要向该页面添加10个实例,则获取该最后一个值所需的时间将是原来的20倍。

Before testing I thought that my code would be ok, as due to the context and .once() function, I believed it would only fire once. 在测试之前,我认为我的代码还可以,因为上下文和.once()函数,我相信它只会触发一次。

All html and CSS are functioning as expected, it's just the jQuery is an issue. 所有的html和CSS都按预期运行,只是jQuery是一个问题。

My code: 我的代码:

(function ($) {
 Drupal.behaviors.click_the_dots = {
  attach: function (context, settings) {
   $('.wrapper_class', context).once('click_the_dots', function () {
    // Prevent other buttons from being clickable until the
    // previous animation is complete.
    var animationDone = false;

    function clickDots(dotNum) {
      $('.dot_class_num_' + dotNum).click(function () {
        // Setup context, to keep animations to the container in which the dots exist.
        var findElem = $(this).parent().parent().parent().find('.inner_wrapper');
        // Prevent other buttons from being clickable until the
        // previous animation is complete.
        if (animationDone === false) {
          animationDone = true;
          // Find the visible image.
          var animatingImage = findElem.find('.dot_class_num_active');
          // Find the image that will be animating in.
          var thisImageAnim = findElem.find('.dot_num_img_src_' + dotNum);
          if (animatingImage.is(thisImageAnim)) {
            // Can't click on the same dot again, until another dot is clicked.
            animationDone = false;
            return;
          } else {
            // Animate out the already visible image.
            // Remove the visible image class as it's going to be hidden.
            findElem.find('.dot_class_num_active').removeClass('dot_class_num_active');
            // Animate it to hide to the left.
            animatingImage.animate({
              marginLeft: '-10%',
              opacity: 0
            }, 280, 'easeInOutQuad');
            // Animate in the image associated with the dot click
            // Set the image css to be further right in order to animate to left at 0.
            thisImageAnim.css('margin-left', '10%').delay(200).animate({
              marginLeft: '0',
              opacity: 1
            }, 300, 'easeInOutQuad', function () {
              // Set the now visible image to the visible image.
              thisImageAnim.addClass('dot_class_num_active');
            }).promise().done(function () {
              // Now allow the other dots to be clicked.
              animationDone = false;
            });
          }
        }
      });
    }

    // For each of the five dots.
    for (i = 1; i <= 5; i++) {
      clickDots(i);
    }
});}};})(jQuery);

I would like to add as many instances of this jQuery as required, but only have the function be looped through once. 我想根据需要添加此jQuery的尽可能多的实例,但仅使函数循环一次。 I'm not sure how to check if this has already been done, or how to ensure that once it has been done at least once, it shouldn't happen again. 我不确定如何检查是否已经完成,或者如何确保一旦完成至少一次就不会再次发生。

:) :)

I figured out what my issue was - I was attaching the behaviour to the wrapper class of my content, ie $('.wrapper_class', context).once... - this meant that it attached the behaviour to each instance of this class, of which there could be many. 我弄清楚我的问题是-我将行为附加到我的内容的包装类,即$('.wrapper_class', context).once...这意味着它将行为附加到了该类的每个实例,其中可能有很多。

What I did was attach the behaviour to a higher parent element, of which I knew there would be only one instance. 我所做的就是将行为附加到较高的父元素,我知道只有一个实例。 It attaches just once and the code works perfectly. 它仅附加一次,代码运行完美。

Thanks to the commenters above who helped me realise my issue! 感谢上面的评论员帮助我意识到了我的问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM