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 を返します。
checked されている場合
<input type="checkebox" checked />
初期 checked であるならば jQuery3 までは "checked" が入っている様に特別な処理がされています。 jQuery4 は getAttribute() に準じて空文字が入った 挙動となります。
checked に checked以外の文字が入っている場合
いわゆるこういうやつです
<input type="checkbox" checked="🐈" />
🐈 の様な値が checked に設定されている場合、 jQuery3 までは checked を取得します。
jQuery4 からは getAttribute() に準じた値となります。
以上。
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>


