0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

jQuery4 で attr() が破壊的変更を受けたので比較してみた

Last updated at Posted at 2025-11-08

jQuery には 特殊対応しているケースが幾つかありますが、今回は特殊対応していた attr の特殊対応をやめますのケースの話です。

具体的にはこの記事で言われている話ですね。

ちなみに 確認の為に jquery は type module で import して確認しています。

demo

See the Pen input.checked の jquery と native での比較 by juner clarinet (@juner) on CodePen.

case

checked が設定されていない場合

いわゆるこういうやつです

<input type="checkbox" />

初期 非 checked であるならば getAttribute() および attr() は null / undefined を返します。

image.png

checked されている場合

<input type="checkebox" checked />

初期 checked であるならば jQuery3 までは "checked" が入っている様に特別な処理がされています。 jQuery4 は getAttribute() に準じて空文字が入った 挙動となります。

image.png

checked に checked以外の文字が入っている場合

いわゆるこういうやつです

<input type="checkbox" checked="🐈" />

🐈 の様な値が checked に設定されている場合、 jQuery3 までは checked を取得します。
jQuery4 からは getAttribute() に準じた値となります。

image.png

以上。

demo のソース

<h1>input.checked の jquery と native での比較</h1>
<script type="module">
  console.log("hello");
  import $1 from "https://esm.sh/jquery@1.12.4";
  import $2 from "https://esm.sh/jquery@2.2.4";
  import $3 from "https://esm.sh/jquery@3.7.1";
  import $4 from "https://esm.sh/jquery@4.0.0-rc.1";
  checkbox.addEventListener("change", redraw);
  attribute.addEventListener("input", () => {
    setAttr();
    redraw();
  });
  function setAttr() {
    checkbox.setAttribute("checked", attribute.value);
  }
  removeattribute.addEventListener("click", () => {
    checkbox.removeAttribute("checked");
    attribute.value = "";
    redraw();
  });
  function redraw() {
    const nullvalue = nullelement.content;
    const undefinedValue = undefinedelement.content;
    // #region native attribute
    {
      const className = "native";
      const attr = checkbox.getAttribute("checked");
      const $attr = document.querySelector(`.${className} .attribute`);
      
      for(const $node of [...$attr.childNodes])
        $attr.removeChild($node);
      if (attr === null) {
        $attr.appendChild(nullvalue.cloneNode(true))
      } else if (attr === undefined) {
        $attr.appendChild(undefinedValue.cloneNode(true));
      } else {
        $attr.innerText = attr;
      }
      const prop = checkbox.checked;
      const $prop = document.querySelector(`.${className} .property`);

      for(const $node of [...$prop.childNodes])
        $prop.removeChild($node);
      
      if (prop === null) {
        $prop.appendChild(nullvalue.cloneNode(true))
      } else if (prop === undefined) {
        $prop.appendChild(undefinedValue.cloneNode(true));
      } else {
        $prop.innerText = prop;
      }
    }
    // #endregion
    // #region jquery-1 attribute
    setValue("jquery-1", $1);
    // #endregion
    // #region jquery-2 attribute
    setValue("jquery-2", $2);
    // #endregion
    // #region jquery-3 attribute
    setValue("jquery-3", $3);
    // #endregion
    // #region jquery-4 attribute
    setValue("jquery-4", $4);
    // #endregion
    function setValue(className, $) {
      const version = $.fn.jquery;

      const $version = $(`.${className} .version`);
      $version.text(`jQuery@${version}`);

      const attr = $(checkbox).attr("checked");
      const $attr = $(`.${className} .attribute`);
      $attr.empty();
      if (attr === undefined)
        $attr.append($(undefinedValue.cloneNode(true)));
      else if (attr === null) 
        $attr.append($(nullValue.cloneNode(true)));
      else 
        $attr.text(attr);
      
      const prop = $(checkbox).prop("checked");
      const $prop = $(`.${className} .property`);
      $prop.empty();
      if (prop === undefined)
        $prop.append($(undefinedValue.cloneNode(true)));
      else if (prop === null) 
        $prop.append($(nullValue.cloneNode(true)));
      else 
        $prop.text(prop);
    }
  }
  redraw();
</script>
<div class="tool">
  <label><input type="checkbox" id="checkbox" /></label>
  <label>attribute:<input type="text" id="attribute" /></label>
  <button id="removeattribute">remove</button>

</div>
<table>
  <thead>
    <tr>
      <th>version</th>
      <th>attribute</th>
      <th>property</th>
    </tr>
  </thead>
  <tbody>
    <tr class="native">
      <th class="version">native</th>
      <td class="attribute"></td>
      <td class="property"></td>
    </tr>
    <tr class="jquery-1">
      <th class="version"></th>
      <td class="attribute"></td>
      <td class="property"></td>
    </tr>
    <tr class="jquery-2">
      <th class="version"></th>
      <td class="attribute"></td>
      <td class="property"></td>
    </tr>
    <tr class="jquery-3">
      <th class="version"></th>
      <td class="attribute"></td>
      <td class="property"></td>
    </tr>
    <tr class="jquery-4">
      <th class="version"></th>
      <td class="attribute"></td>
      <td class="property"></td>
    </tr>
  </tbody>
</table>
<template id="nullelement">
  <div class="nullvalue">null</div>
</template>
<template id="undefinedelement">
  <div class="nullvalue">undefined</div>
</template>
<style>
  body {
    display: grid;
    grid-auto-flow: row;
    gap: 0.5rem;
  }
  h1 {
    margin:0;
  }
  .nullvalue {
    color: gray;
  }
  .tool {
    display: grid;
    grid-auto-flow: column;
    gap: 1rem;
  }
  table {
    border-collapse: collapse;
    border: 1px solid black;
    td, th{
      border: 1px solid black;
      padding: 0.5rem;
    }
  }
</style>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?