このブログは更新を終了しました。移転先はこちらです。

2023-07-16

NTA-DIY:2ヶ月目②~付箋ツールを自作してみる-前編-~

 久しぶりの更新になってしまいました。二ヶ月目の話の続きです。

 これまで作ってきたのは、カード風メモツールにしろアウトライナーにしろ、内容の表示を自動で整えるタイプのものでした。決まった形式の見た目になって整然と並んでいくという形です。きっちり整列させられるのはデジタルのとても良いところですが、逆に自由に配置したいということもあります。きちんと並んでいてほしいものはきちんと並んでいてほしいわけですが、きちんと並んでいる必要のないものがきちんと並んでしまうのはあまり嬉しくなかったりするのです。

 ということで、付箋ツールを作ることにしました。ポストイットを壁に自由に貼り付けるように、情報を書いた四角い領域を自由に移動させられるようにするということです。


 JavaScriptのことがわからなかった時、要素を自由に位置づけるということは、かなり難易度の高そうな、プログラマーにしかできない魔法のように思えていました。どうやったら実現し得るものなのか全然イメージできていなかったからです。位置の移動だけなら良いとして、それを保存しておく術がわからなかったのです。

 しかしちょっとJavaScriptを齧って考えてみると、「styleのtopとleftの値を保存すればいいだけだ」ということがわかりました。localStorageに保存するデータにtopとleftのキーを作り、styleの値を保存しておいて、リロード時にhoge.style.topにその値を指定すれば要素の位置は復元されるわけです。

 文章で書いてもわかりにくいのでその部分の単純なコードを書いてみると、例えば以下のように書くことができます。保存・読込部分の最低限の処理なのでこれだけでは全然ツールにはなっていませんが、ともかく位置の保存と読込は簡単にできるということがわかりました。

const storageKey = 'hoge'; // localStorageに保存する際のキーが「hoge」だとする
const list = document.getElementById('list'); // 「list」というidを付けたul要素があるとする
function loadData() {
const json = localStorage.getItem(storageKey); // localStorageからデータを取り出す(文字列)
const data = JSON.parse(json); // 文字列からデータに復元する
/*
データの中身は以下のような形式のオブジェクトの配列だとする
{
text: '本日は晴天なり',
top: '50px',
left: '100px',
}
*/
data.forEach(item => { // データそれぞれについて
const elm = list.appendChild(document.createElement('li')); // ul要素の子要素としてli要素を追加する
elm.classList.add('fusen'); // 「fusen」クラスを付けておく
elm.textContent = item.text; // 本文をセット
elm.style.top = item.top; // topの値(=縦位置)をセット
elm.style.left = item.left; // leftの値(=横位置)をセット
})
}
function saveData() {
const elms = list.getElementsByClassName('fusen'); // ul要素内の全てのli要素を取得する
const data = []; // データを入れる配列を作っておく
Array.from(elms).forEach(elm => { // li要素それぞれについて
const item = { // データのオブジェクトを作る
text: elm.textContent,
top: elm.style.top,
left: elm.style.left,
}
data.push(item); // 配列にデータを入れる
})
localStorage.setItem(storageKey, JSON.stringify(data)); // localStorageに保存する
}
view raw i7e4w2Jy.js hosted with ❤ by GitHub


 このli要素をドラッグできるようにして、CSSを整えれば、付箋ツールっぽいものができていくということになります(ul要素とli要素で作ることにこだわる必要は特にありません)。何をすればいいのかがイメージできるようになったので、うきうきとツール作りに着手しました。


 付箋ツールらしさには、まず「ドラッグして位置を自由に動かせること」「付箋のサイズを自由に伸縮させられること」の二つが必要でしょう。サイズ変更に関しては必須ではないですが、そうできた方が柔軟で嬉しい感じがします。逆に敢えて余計な自由を封じた方がいい場合もあります。

 これらを実現するにはマウスイベントを色々設定する必要があります。結構大変です。正直二ヶ月目のこの時点ではちょっと厳しかったので、ライブラリの力を借りることにしました。「jQuery UI」というものです。(導入方法については検索していただくとして、ここでは割愛します。)

 2023年の今の時代でjQuery UIを使うのが最善手かというとそれはわからないところですが、素人でも良い感じの機能を比較的簡単に作れるようになるので、JavaScriptに挑戦したい人は知っておいて損はないと思います。私個人はjQuery UIをマウスイベントの実装にしか使ったことがないので全容を語ることはできませんが、今でも自力で実装するのが難しいような処理をまかなってくれるのでありがたい存在です。

 しかしそれでも楽勝というわけではありません。プログラミング初心者の身にはちょっと難しく感じられたのが、オプションの設定です。例えば「Draggable」の解説を見てみましょう。

  Draggable | jQuery UI 1.10 日本語リファレンス | js STUDIO

 ありがたいことに日本語リファレンスがあるので言葉の壁はないですが、オプション、メソッド、イベントの各タブを見た時に、つまるところどうしたらいいのかがパッとわかりませんでした。解説が不親切ということではなくて、自分が「初心者用の懇切丁寧なガイドがない記述」を理解できる域にまだ到達していなかったということです。

 この時点では引数にオブジェクトやコールバック関数を渡すという経験がなかったので、内部的に何が行われるのかが想像できず、少し飲み込みが悪かったなという記憶があります。設定項目が複数あるうちの一部だけを記述して渡すというのはどういうことなのだろうとか、コールバック関数の引数に入るものというのはどこから来るんだろうとか、今となっては謎の疑問に囲まれていました。できる人に尋ねても「質問の意味がわからない」と言われるタイプの疑問でしょう。

 初学者はそういう疑問をたくさん抱えながら進むことになるものと思います。疑問の持ち方とそれを表現する言い回しが千差万別なので、序盤のつまずきなのにもかかわらず先輩に尋ねて解決するのは大変に難しいものです。コードを書きまくっているうちにいずれ唐突に霧が晴れる時が来るので、その瞬間の訪れを信じてもがくしかないと私は思っています。

 そんなわけで、それまで自分で書いていたより複雑さが一段上のコードと格闘することになったのですが、幸いこのレファレンスは実例のコードを見ることができるので、この説明はこういう意味なのだろうかというのを探っていくことが容易です。ドラッグやドロップなどのイベントは作っていて楽しいこともあり、JavaScriptを理解するための教材としても役に立ったなと思います。


 エラーを出しながらも手探りでどうにかDraggableやResizableを設定することができました。そうすると随分付箋ツールらしくなりました。結構な格闘があったにもかかわらず、できてみると「簡単じゃないか」という気分になり、それじゃあと調子に乗って色々な機能を搭載することにしました。

 本題はここからという感じですが、記事一本としてはちょっと長くなってしまうのでここまでを前編とします。

 画像がないとちょっとイメージが湧かないと思いますので、当時作ったもののスクリーンショットを最後に一枚貼っておきます。


(書いてある内容は初学者の勉強中のメモなのでおかしいところを見つけてもスルーしてください。)



このシリーズ記事の概要はこちら→ノートテイキングアプリDIY体験記