Drupal - Why does js click function run multiple times?

Solution:

Most importantly you have to use the JQuery selector context. Otherwise you run the entire DOM through your js code anytime when Drupal behaviors passes you only context to process.

If your function still runs multiple times, add once() with a unique identifier:

$('input.myCustom', context).once('mySecondBehavior').each(function () {

Don't forget to add the library core/jquery.once to mytheme.libraries.yml, see https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview


I just came across this post while working something out in our project. We have multiple events bound to $('body', context) since flexibility in the platform allows for widgets and such to be placed almost anywhere within the body.

Using $('body', context).on('click', '.modal-trigger', function (e) {}); was causing the click event to be bound on body 2x.

Simply using $('body', context).once().on('click', '.modal-trigger', function (e) {}); was binding only the last attached/loaded script to the body, resulting in no other script events being attached.

Adding .once() with a unique identifier for each script solved this issue beautifully.

Ex. 1st modal script

  Drupal.behaviors.SigmaModal = {

    attach: function (context, settings) {

      // Trigger sigma dialog on click.
      $('body', context).once('SigmaModal').on('click', '.sigma-modal-trigger', function (e) {

2nd modal script

  Drupal.behaviors.DisplayModal = {

    attach: function (context, settings) {

      // Trigger generic dialogs on click.
      $('body', context).once('DisplayModal').on('click', '.modal-trigger', function (e) {