Problem/Motivation

In js/init.js, when alerts are fetched and processed inside the initAlerts function, Drupal.attachBehaviors(); is called without a specific context element.

Because this call sits inside a forEach loop iterating over the active alerts, having multiple active alerts on the page causes Drupal.attachBehaviors() to fire globally on the entire document multiple times in rapid succession (once for each active alert).

We ran into this issue when it completely broke our custom tabs and accordions. Because the script re-runs across the entire page for every single active alert, it stacked multiple click listeners onto our buttons, causing them to glitch out. While we can update our own theme to guard against this, passing the context is a great best practice to ensure the module works smoothly across all types of projects and themes without causing accidental conflicts.

Steps to reproduce

  1. Have a site with custom JavaScript behaviors attached to DOM elements (like tabs or accordions).
  2. Create and activate more than one Sitewide Alert so that the alerts.forEach loop runs multiple times.
  3. Load a page displaying these alerts.
  4. Observe that Drupal.attachBehaviors() is fired globally multiple times, causing unexpected behavior in other JavaScript components on the page.

Proposed resolution

Scope the behavior attachment specifically to the newly rendered alert element.

Change:
Drupal.attachBehaviors();

To:
Drupal.attachBehaviors(renderableAlertElement);

This ensures that behaviors are only attached to the markup injected by the module, preventing it from unnecessarily rescanning the entire page and interfering with other components.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

alimc29 created an issue. See original summary.

alimc29’s picture

Status: Active » Needs review
chrissnyder’s picture

Thanks for the fix.

chrissnyder’s picture

Do we also need to pass Drupal.settings as the second parameter?

Edit: I just looked it up and attachBehaviors will default to drupalSettings if not passed

chrissnyder changed the visibility of the branch 3585232-global-drupal.attachbehaviors-in to hidden.

chrissnyder’s picture

Status: Needs review » Reviewed & tested by the community

chrissnyder’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

chrissnyder’s picture

Fixed in 3.1.2