知名度が低いウェブ標準ひとり Advent Calendar 2021 – 19 日目

今日は spellcheck です。スペルチェックするしないの制御をします。

基本的な使い方

HTML に spellcheck="true" みたいに書きます。グローバル属性といってあらゆる HTML 要素で利用可能です。

<div spellcheck="true">Check!</div>
<div spellcheck>Also check!</div>
<div spellcheck="false">No check!</div>

値は文字列で "true""false" あるいは空 "" を取ります。空 """true" と同じです。

属性がない場合は祖先要素から引き継ぎます。それも見つからなければブラウザーが定める初期状態を取ります。<textarea> は初期状態でオンだろうね。

JavaScript は論理値

JavaScript からも同名 spellcheck プロパティが利用可能ですが、こっちは文字列ではなく boolean 型で truefalse になります。なんで。

el.spellcheck = true;
el.spellcheck = false;

el.spellcheck = "false"; // TypeScript なら型エラー。JS は Boolean("false") なので true

JavaScript は論理値だが

実はややこしいことになってます。

前述のとおり spellcheck の実効値は祖先要素の設定を引き継ぐので、要素単体ではなく祖先の状況により得られる値が変化します。おやおや。

優先順位はだいたいこんな感じ。

  1. spellcheck 属性がある → それに従う
  2. …がなく、祖先要素に属性がある → 直近の祖先のそれに従う
  3. …がない → ブラウザー規定

ただのプロパティではなく内部的な処理を伴う getter/setter なわけです。getter でツリーの状態を追って、setter では要素の属性へ反映させます。

<div id="elWrapper">
  <textarea id="elTextarea"></textarea>
</div>
console.log([
  elWrapper.spellcheck, // => false
  elTextarea.spellcheck, // => true
]);

// 親に設定したので全部同じに
elWrapper.spellcheck = false;
console.log([
  elWrapper.spellcheck, // => false
  elTextarea.spellcheck, // => false
]);

// 親に設定したので全部同じに (2)
elWrapper.spellcheck = true;
console.log([
  elWrapper.spellcheck, // => true
  elTextarea.spellcheck, // => true
]);

// 親から消えたので初期状態
elWrapper.removeAttribute("spellcheck")
console.log([
  elWrapper.spellcheck, // => false
  elTextarea.spellcheck, // => true
]);

おしまい

文章じゃないもの、例えば ID とかアカウント名とかハッシュ値とか、そういうのの入力欄に付いててほしいなとか思いました。