bhylu.com

Advertisements

jQuery Event Namespaces

Use a namespace for feature cleanup and preserve unrelated listeners.

How it works

Event namespaces let a feature remove its own jQuery handlers without deleting another feature’s work. A repeated initializer should either do nothing when already active or cleanly replace its previous binding. This lab uses the second approach. It deliberately keeps an unrelated handler on the same button, initializes the swap handler twice and then verifies that one click runs each owner exactly once.

Run in a separate local browser lab

Save this complete HTML source as index.html in an empty folder. Put the pinned full jQuery 4.0.0 file beside it and preserve the MIT licence notice. The document includes its own CSS and JavaScript. Bhylu’s shared website theme does not load jQuery globally.

Open index.html directly in a normal browser. You may also use the optional loopback fixture server with Node 22 if you want the same HTTP setup as the network lessons.

jQuery examples do not run in Bhylu’s current playground: it blocks external libraries and network access. No Apache, MySQL or website configuration change is needed. Review the full-build setup before using Ajax, effects or plugins.

Example

index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>jQuery Reinitialize Without Duplicating Owned Handlers</title>
    <style>
      :root {
        font:
          18px/1.6 system-ui,
          sans-serif;
        color: #16304e;
        background: #fff;
        color-scheme: light;
      }
      * {
        box-sizing: border-box;
      }
      body {
        margin: 0;
      }
      main {
        max-width: 50rem;
        margin: auto;
        padding: 1.25rem;
      }
      h1 {
        font-size: 1.8rem;
        line-height: 1.2;
      }
      h2 {
        font-size: 1.3rem;
      }
      button,
      input,
      select,
      textarea {
        font: inherit;
        max-width: 100%;
      }
      button {
        margin: 0.2rem;
        padding: 0.4rem 0.7rem;
        background: #034fa0;
        color: white;
        border: 1px solid #034fa0;
        border-radius: 0.3rem;
      }
      button:disabled {
        opacity: 0.6;
      }
      label {
        display: block;
        margin: 0.5rem 0;
      }
      input:not([type='checkbox']),
      select,
      textarea {
        display: block;
        padding: 0.3rem;
      }
      a {
        color: #034fa0;
      }
      output {
        display: block;
      }
      article,
      section,
      fieldset {
        padding: 0.75rem;
        margin-block: 0.75rem;
        border: 1px solid #a9bcd1;
      }
      ul {
        padding-left: 1.5rem;
      }
      :focus-visible {
        outline: 3px solid #0078d4;
        outline-offset: 3px;
      }
      .chosen {
        border: 3px solid #0078d4;
      }
      .highlight {
        font-weight: 700;
      }
      .muted {
        opacity: 0.7;
      }
      pre {
        white-space: pre-wrap;
        overflow-wrap: anywhere;
      }
      :root[data-theme='dark'] {
        color: #d6e7fb;
        background: #061d30;
        color-scheme: dark;
      }
      :root[data-theme='dark'] a {
        color: #8ecbff;
      }
    </style>
  </head>
  <body>
    <main>
      <h1>Neighbourhood book swap</h1>
      <button id="read">Read notice</button><output></output>
    </main>
    <script src="jquery.min.js"></script>
    <script>
      jQuery(function ($) {
        let owned = 0,
          other = 0;
        function report() {
          $('output').text('Feature ' + owned + ' / Other ' + other);
        }
        $('#read').on('click.other', function () {
          other++;
          report();
        });
        function init() {
          $('#read')
            .off('.swap')
            .on('click.swap', function () {
              owned++;
              report();
            });
        }
        init();
        init();
        report();
      });
    </script>
  </body>
</html>

Expected result

One click produces Feature 1 / Other 1 rather than a duplicated feature count.

The namespace is a label for owned handlers, not a hierarchical security boundary. Removing all click handlers would erase the other owner and conceal the duplication bug rather than solving it. A plugin should document which nodes and namespaces it owns, and should clean timers, observers and requests as well as event bindings during teardown.

Use jQuery’s official API documentation for exact method and return contracts.

Advertisements