Blog

ブログ

jQuery卒業のため、クリックするとclass属性やWAI-ARIA属性を書き換えるJavaScriptライブラリ「Clickit.js」をリリースしました

個人的に欲しかったJavaScriptライブラリをリリースしました。「クリックするとclass属性やWAI-ARIA属性を書き換える」処理に特化したライブラリです。

https://webbingstudio.github.io/clickit-js/

Clickit.jsは、以下の4つを目標として作りました。

  1. 脱jQuery、他のライブラリに依存しないこと
  2. npmやwebpackを前提にせず、雑に読み込んで使えること
  3. なにかのUIの作成を前提にせず、何にでも使えること
  4. ARIA属性をサポートすること

ロゴのアイコンはこちらを使わせていただきました。かわいいです。
指ジェスチャー スマホのタップのアイコン素材 4 | 商用可の無料(フリー)のアイコン素材をダウンロードできるサイト『icon rainbow』

機能

js-clickitクラスを付与した要素をクリックすると、a要素のアンカーか、aria-controls属性を調べ、指示されたIDのaria-hidden要素をtrueにします。また、js-clickitクラスを付与した要素にはaria-expanded要素を付与してトグルさせます。

DOMは以下のように変化していきますから、それに応じたpositionやopacityなどのCSSを書けば、UIができます。

<!-- ライブラリの初期化前(最低限のマークアップ) -->

<button class="js-clickit my-trigger" aria-controls="my-menu">Menu</button>
. . .

<div id="my-menu" class="my-menu">
    <!-- opens and closes here -->
</div>

<!-- ライブラリの初期化後 -->

<button class="js-clickit my-trigger" aria-controls="my-menu" aria-expanded="false">Menu</button>
. . .

<div id="my-menu" class="my-menu js-clickit-ready" aria-hidden="true">
    <!-- opens and closes here -->
</div>

<!-- トリガーをクリックしてから展開するまで -->

<button class="js-clickit my-trigger" aria-controls="my-menu" aria-expanded="false">Menu</button>
. . .

<div id="my-menu" class="my-menu js-clickit-ready js-clickit-opening js-clickit-locked" aria-hidden="true">
    <!-- opens and closes here -->
</div>

<!-- 展開後 -->

<button class="js-clickit my-trigger" aria-controls="my-menu" aria-expanded="true">Menu</button>
. . .

<div id="my-menu" class="my-menu js-clickit-ready" aria-hidden="false">
    <!-- opens and closes here -->
</div>

基本的な機能はそれだけですが、さまざまなオプションプロパティがあり、クリックから展開までに待機時間を作ったり、WAI-ARIA属性をタブやモーダルを前提としたものに変更することもできます。

制作の背景

先日、こちらの有料記事を読みました。完全な脱jQueryにあたって最低限どのようなUIが作れればよいのか、どのようなライブラリに変えればよいのかがはっきりして、とても勉強になりました。

https://zenn.dev/hideki_climax/books/893fce619abc39

そのうえで、去年じっくりネイティブJavaScriptやVue.jsを勉強した際に、とても困っていたことを思い出しました。最近のJavaScriptライブラリはnpmでのインストールか、webpackでのインポートを前提としているため、気軽にscriptタグで読み込んで利用できないのです。

もしも、ClickIt.jsをモジュールとして作成していたのなら、こう書いていただろうと思います。しかし、export, import文はローカル環境(HTMLファイルをブラウザに投げ込んで開く)には対応していません。

export class ClickIt {
・・・
}

---

import {ClickIt} from './src/clickit.js';

const clickit = new ClickIt();

こういった細かいことを意識せずにモジュールを作成し、最適に圧縮し、かつ安全に実行できるようにするため、webpackなどのビルドツールが利用されます。ですが、モジュールやwebpackを前提とした時点で、フロントエンドのスキルがそれほど高くない(jQueryがそこそこ書ける程度)制作者には、全く扱えないものになります。

学習しなさいというのは簡単ですが、デザイン、マーケティング、CMSなど、勉強することは他にもあり、専業でなければそこまで学習する時間ないし、必要性を感じていないし、WordPressテーマであれば簡単にHTMLを書き換えられないし、既存サイトをネイティブJavaScriptに切り替えたくても予算がつかないのが現実です。

正直、大半のウェブ制作者は、Swiperなどのさっくりコピペで使えるライブラリがあれば充分だと思っていそうです。実際、Clickit.jsも、私がさっくりコピペでいろいろ作れるようにするために作ったものです。

フロントエンドエンジニアの人たちはそのあたりの事情を気にかけていただき、jQuery全盛のときのように、もう少し気軽に利用できるライブラリをお願いできればと…いや、JavaScriptが書けないならフロントエンドエンジニアに依頼するのが筋だとは思いますが…

メニューではなくボタンを起点にした理由

一般にUIを作成するライブラリは、親となる要素=メニューであれば展開されるメニューの方を、処理の起点としてセレクタを渡します。しかし、ClickIt.jsは最初に押されるであろうボタンの方を起点としています。

昨日リリースしたときは「display:noneでメニューを隠していたばっかりにライブラリが起動しない問題を回避するため」とツイートしましたがこれは誤りです。すみません。display:noneで隠されている要素でもDOMは解析されます。
そうではなく、「非エンジニアにも処理をわかりやすくするため」です。

例えばリモコンで家電を操作する場合、実際の表示などの処理は本体が担っていて、リモコンは信号を送るだけです。なのでJavaScriptのオブジェクトの作成は、よく家電に例えられます。ですが、機械のことがよくわからない人は、手に取っているリモコンの方を意識して、ボタンだけを見ています。なのでClickIt.jsも、設置や改修を直感的にするために、ボタンの方を起点にしました。

きちんとしたエンドエンジニアの方であれば、この処理は冗長になる可能性があるとすぐわかると思います。UIは、リモコン、つまりボタンが何個もあるケースが多いからです。このライブラリは、ゲームやインフラのサービスへの利用を想定していないですし、そういった層が使うとも考えにくいので、これで良いだろうと思っています。むしろ、これからウェブ制作を勉強する層に役に立てばいいなあ。未圧縮のコードはこちらです。

https://github.com/webbingstudio/clickit-js/blob/main/src/clickit.js

若者よー!

もし、ウェブ制作を勉強中の人がこの記事にたどり着いたら、声を大にして言いたいことがあります。

もうjQueryを勉強しなくてもいいです。
jQueryについては、私たち先達がやりますから任せてください。

これはみなさんに新しいことを勉強してほしいという気持ちと、jQueryの改修ができますというのはベテランならではの強みになるので残しておいてほしいという気持ちが、ない混ぜになっています。

たしかに、世の中のサイトの大半はjQueryが使われているので、書ければ即戦力になります。が、それはあくまで、古いサイトの改修についてだけのことです。両方勉強できる自身があれば両方やればいいですが、どっちかであればjQueryはもういいです。

もう12年も前の話になります。Google ChromeがEdgeのシェアに追いつき始め、GoogleがInternet Explorer 6のサポートをやめ、IE6が丁重に埋葬されました。その頃から、当時のメンターであるエンジニアは「もうIEに対応するな、CSS3を書け」と言い続けました。jQueryはそのときのように、使用に大きなデメリットがあるわけではないのですが、私もそうありたいと思っています。

あ、なんかつよそうなことを書きましたが、ClickIt.jsのコードは変なところもあると思うので、ぜひissueやフォークで教えてください…