0

I keep struggling with getting JavaScript executed when I need to target a DOM element that is added via the BigPipe module when I'm logged in on my Drupal site.

The following code runs when I'm not logged in, but it's never executed when I am logged in.

(function ($) {
  'use strict';

  Drupal.behavior.bpBlockTest = {
    attach: function(context, settings) {
      $('.my-block', context).once('bp-block-testing').each(function () {
        var $myBlock = $(this);
        var $addOn = $('<span>addOn</span>');
        $addOn.appendTo($myBlock);
      });
    }
  }

}(jQuery));

2 Answers 2

2

For the current Drupal version this is the correct way to run Javascript (including jQuery, Drupal and the new Drupal once library):

(function ($, Drupal, once) {
  Drupal.behaviors.myModuleBehavior = {
    attach: function (context, settings) {
      once('myCustomBehavior', 'input.myCustomBehavior', context).forEach(function (element) {
        // Apply the myCustomBehaviour effect to the elements only once.
      });
    }
  };
})(jQuery, Drupal, once);

MODULE.libraries.yml or THEME.libraries.yml:

foobar:
  js:
    js/foobar.js: {}
  dependencies:
    - core/drupal
    - core/jquery
    - core/once

From https://www.drupal.org/docs/drupal-apis/javascript-api/javascript-api-overview

See also https://www.drupal.org/node/3158256

1
1

Until #3272693 is fixed, the fix for this is to remove context from your once function or use $.filter()

(function ($, Drupal, once) {
  Drupal.behaviors.myBehavior = {
    attach: function (context, settings) {
      // don't use context with once
      once('myBehavior', '.myBehavior').forEach(function (element) {});
      // or use filter
      $(context).filter('.myBehavior').once('myBehavior').forEach(function (element) {});
    }
  };
})(jQuery, Drupal, once);
1
  • 1
    I wouldn't consider the issue as a bug, BigPipe works as designed. But when using the module you might need to adjust custom JS code to run for each lazy-loaded part of the page separately. Your answer is helpful if you can't apply .once to elements inside of the block like the example in my answer. It's preferable to make it as granular as possible to avoid such problems.
    – 4uk4
    Jan 5, 2023 at 8:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.