bhylu.com

Advertisements

jQuery Data Storage

Understand when data imports an attribute and why later attr edits need not update the cached value.

How it works

jQuery data stores values associated with an element. It can initially read and convert data-* attributes, then retain its own cached value. Changing the attribute later does not automatically synchronize every cached read. This example intentionally demonstrates the difference so a feature does not accidentally keep two conflicting sources of truth. Use one defined owner for changing state, and choose whether markup is a starting configuration or a live representation.

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 Treat Cached Data and Markup as Separate Stores</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>
      <p id="shelf" data-count="2">Book shelf</p>
      <output></output>
    </main>
    <script src="jquery.min.js"></script>
    <script>
      jQuery(function ($) {
        const $shelf = $('#shelf');
        const initial = $shelf.data('count');
        $shelf.attr('data-count', '7');
        $('output').text(
          'Attribute: ' +
            $shelf.attr('data-count') +
            '; cached data: ' +
            $shelf.data('count'),
        );
      });
    </script>
  </body>
</html>

Expected result

The attribute reads seven while cached data still reads two.

This is an intentional cache contract, not random stale behaviour. Plugin state can live in data when its lifecycle includes removeData during teardown. Do not place secrets there: browser code and users can inspect it. If another system needs to observe a live attribute, update that attribute deliberately rather than hoping a data setter changes the DOM.

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

Advertisements