offメソッドがとても便利だった話

こんばんは。有村です。

さて今日は、jQueryのoffメソッドについて記録を残します。
実装中、ある状態によって発火する・しないの処理分けをしたかったのですが、変数でのフラグ管理以外の解決法が思いつかなくて。どうしようもなくて禁忌に手を出そうとしていたところを、颯爽とoffメソッドが解決してくれたんですよね。こいつマジイケメン。

実際のものから略してますけど、なんとなくのソースはこちら。

仕様としては、
・ヘッダの一部(グロナビ)がスクロール量に応じて固定される(いわゆるスティッキー)
・グロナビ内のボタン押下でサブナビ表示
・サブナビ表示中はメインコンテンツ部のスクロールを防ぐため、メインコンテンツをスクロール量に応じてfixedにする
みたいな感じです。

そこで起こった問題が!
スティッキーはうまくできた…でもそのスティッキー部が固定された状態からメニュー表示ボタンを押下すると、サブナビ表示と共にグロナビが吹っ飛んでどっか行くという現象が起きたのです…。
DOMの状態を見てみたら、サブナビ表示と同時に #hoge からactiveが外れてしまっていました。
なぜだ…と調べていたところ、#main_pageをposition: fixed; 状態にした時に、windowのスクロール量が「0」とされてしまうことが分かりました。スクロール量が変化したことでonscrollが発火し、activeがすっ飛んでしまった、という顛末です。

ので、「サブナビを表示させる時は、windowのonscrollイベントに紐付いた処理を実行させたくない。」が今回の課題となりました。

で、早速ですが、これで解決しました。

・はじめにonメソッドで、windowのスクロールイベントのコールバックに「checkScroll」を紐付ける。その際に「check」という名前空間を付与しておく。(スティッキーの実装)
・fuga押下でサブナビを表示する際はcheckScrollを動かしたくないので、click直後にcheckの名前空間に紐付くコールバックを破棄する。

名前空間を付与しなくても実装はできるのですが、ただoffするだけではwindowのスクロールに紐付くコールバックが全て外れてしまうので、他にコールバックが設定されていることを考慮して特定の名前を付けています。

まとめると、「onで付与してoffで外した」って感じです。
もちろんこれだけでは、サブナビを閉じた後にスティッキーが効かなくなってしまうので、再度onメソッドでコールバックを設定する必要があるんですけど…いうてもそれもたった1行ですからね。らくちん。

「onは使ったことあるけどoffはないな〜」という方も多いと思いますが、便利なのでぜひ記憶の片隅に置いておいてください!

それでは、今日はこのへんで。

staticが理解できない(調査メモ)

こんばんは、フロントエンドエンジニアだけど最近PHPもはじめてみたよ!な有村です。
みなさんはJSで文字列連結しようとして、「’hoge’.’fuga’」って書いたことはありませんか?世界観ごっちゃになりますよね。

さて今日のテーマはstaticが理解できないです。
以前原田さんの記事にstaticメソッドの使い方が載っていたので、最近それを参考にしてみたんですけど、そもそもstaticとそうじゃないメソッドって何が違うの?って疑問が浮かんできたんです。
私は業務でSmartyを使うので、Smarty functionを作ることがあるのですが、そのときに既存のメソッドを使おうとする場合、newしなければいけないのか、::で呼び出していいのかが分からなくて。
本音としては「インスタンス化するのめんどくせぇ、全部staticで書いたら何がいけないんや!」なんですけど。

そこで調べてみました。メモ。

・static … インスタンス化(new)しないので、初期化がされない。初期化がされないということは、メソッド内の値を保持し続ける。
じゃあAさんとBさんが同じページにアクセスしたりして、同じメソッドを呼び出した場合は、同じ値を参照することになるのか?という疑問が。
これについては、サーバにリクエストが飛んだらその時点で初期化が行われるため、Aさんのリクエスト処理でBさんの処理の値を読んでしまった!ってことはない、らしい。

てことは、staticの使いどころって、メンバ変数とか初期化処理に左右されないメソッドの時なんでしょうか?
引数で値を渡して中で処理するだけ〜とか?

ちなみに今日、PHPに詳しい先輩に上記の認識を確認してみたところ、「う〜ん、違う^^^^」と一蹴されました。
そんなん言われても分からんものは分からんので、ひとまずここで今回の記録はとどめておきます。

それでは、今日はこのへんで。

説明リストの落とし穴

こんばんは。有村です。
ちょっと最近情報過多で整理をしきれない、思考回路はショート寸前の私です。

それでは本題、今日のコードレビューで起こった出来事を書きます。

みたいなコードを書いていたんですけど。

イケメン「なんでdl使ったねん」
有村「色についての説明だからや」
イケメン「色、の部分はheadingのほうがええんちゃうか」
有村「なんでや」
イケメン「【色】っていう言葉自体の説明にはなってへんやろ、そもそも色って何の色やねん」
有村「あー」

イケメンの指摘としては、説明リストを使っているけれど、それは本当に「説明」として成立しているんですかね?ということでした。
具体的に言うと、「商品Aは赤」「商品Bは青」というのは、確かに何かの色について説明なのかも知れませんが、「色」が何を指しているのかは示されてはいません。
もしかしたら箱の色かも知れないし、商品本体の色なのかも知れません。
さらに言えば、「商品Aは赤」「商品Bは青」という部分も説明リストを用いて書いていましたが、商品Aそのものが赤という色そのものを定義しているわけではありません。
たとえば、

であれば、文書として説明が成り立ちます。「お届けする商品本体の色は、商品Aの本体の色が赤、商品Bの本体の色が青です」となるので。
要は、dtとddを文章として切り出したときに、正しく説明として成立するかを見ろということですね。

なので、説明として成り立っていないのであれば「説明リスト」よりも、「見出しとコンテンツ」という構成の方が適しているのではないか、というアドバイスだったのです。
というわけで、最終的にこんなコードになりました。

HTML5で定義リストから説明リストに変わったとはいえ、それが文章として成り立っているかどうかという観点を忘れてはいけないな、という勉強になりました。
説明リストになったというよりは、厳密な定義から説明レベルに緩和されたんだよ、くらいに捉えるのがいいかも知れない、とイケメンからのありがたいお言葉でした。

それでは今日はこのへんで。

navについて本気出して考えてみた

こんばんは。有村です。

さて今日はフロントエンドエンジニアらしく、HTMLのタグの使い方について考えた記録を残します。
そのタグとは…ずはりnav

navってなんですか?という内容をいま一度。MDNではこう書かれています。

ナビゲーション要素(

まぁ、ナビゲーションだからね。そうなるよね。

で、私も勘違いしていたことなんですけど、
navは1つしか使用してはならない、なんて決まりはないのです。
「主要な〜」とあるので、navはひとつしか使ってはならない!と思っていたのですが、そんなことはないのですね。
では逆になんでもかんでもnavにしていいのかというと、それも違う。

主要か主要じゃないか…いや、そもそもWEBにおける主要とは……と考え始めたら、HTMLの深い闇に飲み込まれそうです。
そこでひとつ目安にするとしたら、まずは「このリンク群はサイトにとって重要かどうか」を考えるのがよいのかなと思いました。
たとえば、通販サイトを制作していると仮定して…利用規約やプライバシーポリシーへのリンク群を、ユーザに踏んで欲しいかどうか。もちろん規約自体は重要っちゃ重要ですけど、うちに来たからには絶対見て!というコンテンツではないように見えます。
では、商品一覧やカテゴリリストへのリンク群はどうでしょうか。通販サイトであれば、もちろん商品がメインコンテンツだと思うので、リンクを踏んで見て行ってもらいたいと考える気がします。
navはグロナビに使われることが多いといいますが、グロナビの中に入っている内容って、一般的にはそのサイトの主要コンテンツですものね。そう考えれば納得。

そして、先ほど挙げたような利用規約やプライバシーポリシーは、主にfooterに配置されていることが多いです。
MDNなどの説明を見ると、このようなリンク集であったり、サイトの説明ページへのリンクだったりは、navではなくfooterで十分とされていました。(じゃあfooterの定義って何よと調べたら、ページの著作情報や関連リンクを置くところとされていた)

サイトによって何をnavにするかは迷いどころだと思いますが、今までただのリンク集にしていたところは、実はnavが適切だった!ってこともあるかも知れませんね。

それでは、今日はこの辺で。

条件文をシンプルに!

こんばんはー、有村です。
今日も通常運転で学んだことを好きなように書きます。

今日のテーマは条件文をシンプルに
頭では分かっていても、なかなか難しいんですよね〜。
そこでまずはいつも私が書くソースの例。

いつものように用途不明ですけど、要は引数の値に応じて計算式を変えて、その結果を引数として別の関数を実行しようってやつです。
これを整理していきます。

1・共通項を見つける
たとえば上の例だと、「calcに計算した値を代入する」「calcを引数にしてfugaを実行する」という流れが同じですね。

2・三項演算子を使ってみる
ワンライナーで済む内容であれば、三項演算子がシンプル。

慣れるまでちょっと読みにくいけど。

で、きれいにするとこうなる。

みじかくなった。

短いからいいと言うよりは、共通項がまとまって余計な処理が減ったことが大きいですね。
処理の記述が多いと、どうしても煩雑に見えてしまうので。

共通項はなんだろう?って考えることは、物事を抽象化して捉えることと近しいのですかね?
色々繋がってますね〜。

それでは、今日はこのへんで。

シェルコマンドでファイル名を取得したい!

こんばんは。有村です。
最近は前にも増して仕事がスムーズに進まないことが悩みです。分からないことが多すぎるので。
なので今日は気分を変えて〜疲労感を全面に出した喋り方で記事を書いてみま〜す。

さてさて〜今日ひっかかったことはこちら〜。
シェルコマンドを使ってファイル一覧を取得したい
でも取得にはちゃんと条件があるんですよ〜。
・特定の文字列と前方一致したファイルだけが対象。
・パスはいらない。
・拡張子はいらない。
・つまりファイル名だけが欲しい。
ワガママですね〜。でも多少困難がないと人生つまらないですからね〜。
さらに、今回実現するにあたっては、
・時間がそれなりに限られる
有村はシェルスクリプト書けない。なんとかワンライナーで。
という付加条件も加わっていたのですよね〜。困った〜。

で、早速ですが、どうしたかって答え。

でいけました〜!
私が全部書いたわけじゃないんですけどね。有村無能!!

まず、シェルとかよく分かんね〜ってところからのスタートだったので、ポイントをいくつか〜。
・|(パイプ)は、パイプ前の実行結果をパイプ後のコマンドの入力値にする。Smartyのmodifierと記法や考え方は一緒か。
・basenameは、引数に指定されたパス名から、ファイル名だけを取り出してくれる。findの結果はパスで返ってくるから、こいつでファイル名だけにするということ。でもこいつだけだと、まだ拡張子が残ってる。
・xargsはまだ理解しきれていないけど、上のパイプ前の実行結果一覧を引数にして、パイプ後のコマンドを実行するやつ。
-nはいくつ毎にコマンドへ引数を渡すか、のオプション。つまり上の例だと、basenameの処理は1ファイル毎に実行される。
・sedは置換コマンド。basename処理後のファイル名から、拡張子を取っ払う。正規表現つかえる!便利!けど有村は書けない。

ひとつひとつ読んでいくと、パイプ毎にひとつの処理のまとまりがあって、その結果を使って次の処理を…ってやっていってるんですね〜。
なんだかそれだけ聞くと、書き方は違うけどやってることはJSとか他の言語と変わらんなってなりますね〜。

ワンライナーでやろうとするからややこしくなるんじゃ!シェルスクリプト書けや!と、きびし〜ご意見をいただきましたので、いつか「泣きながらシェルスクリプト書いてみた」的な記事を書く日が来るかも知れませんね〜。
ぼくはつかれたよパトラッシュ

それでは、今日はこのへんで。
おやすみなさい〜。

ガード節と正常系と異常系

こんばんは。有村です。
寒いですね〜、うちの猫も布団にばかり居るようになりました。私も1日中、布団の中だけに居たい。

さてさて今日はガード節周りについて学んだので、忘れないように記録を残しておきます!

まずは、今まで分かったようで分かっていなかった「正常系と異常系」について。
超ライトに言うなら、
正常系 … 期待された処理や内容、いわばノーマルケース
異常系 … レアケース、めったに来ない珍客
的な感じ。

これは、引数で渡された食物をもぐもぐする用途不明関数なのですが。(こういうのしか思いつかなかった)
普通、食べ物って植物とか肉とかで、金属って食べないですよね。金属持って来られて食え!って言われるなんて考えもしないし、「食べる」という目的からすると、食べられないものを持って来られることは「異常」と見なすことができますよね。
なので、上の関数だと、
異常系 … 金属
正常系 … 金属以外
になります。

で、本題のガード節は、「起きにくい事象(異常系)だけど、もしそれが起きてしまったら、そのまま出て行ってもらう」という考え方だそうです。
正常系の動作に続いてしまう前にはじくってことですね。
それで、明確に「お前は異常系なんやで」ということを示す書き方(ガード節)がこれ。

if で囲まれた部分がガード節です。異常系、正常系を if の範囲で示すことで、先程より明瞭性が増した気がしますね!
else が無くなった分、記述がすっきりしたのも好印象。

ただし、正常系と異常系が分かれない場合もある、という点には注意しなければいけないようです。
具体的に言うと…

この関数は引数によって性別を判定するものですが、この分岐では「男」と「女」に正常と異常の区別はありません。(これをウェイトが同じ、とか言うらしい)
もし、

とかの条件式であれば、それが異常系になるのだと思いますが。

今日はこのへんでおしまい!
おつかれさまでした、おやすみなさい!

CSSにルールをつくる

こんばんは、有村です。
さすがにもう年始ムードはなくなりましたね〜、次の連休いつかなあ…

さて今日のテーマは「CSSにルールをつくる」です。
コーディング規約というよりは自分の中での設計に近いのかもしれませんが、そのレベルに達していないので、ここはルールという言葉を使います。

今日の有村ルールはこれ。
繋げる要素が3つ超えたら切り離す。

有村はこんなルールでclass命名を考えていました。

つまり、ネストするにつれて、その親のclass名を子が継承していくルールです。
こうしていた理由は、親と子の関係性をclass名で示したいなと思ったのと、.meun .list .inner とかすることで無意味に詳細度を上げたくなかったからです。

でもお気づきですね、そう、これネストが深くなるととんでもなくclass名なげぇってなるんです。困った。

今日そんな悩みをCSS設計のプロ(イケメン)に相談したら、こんな助言をもらいました。
3つ以上繋がったら切り離せ、と。

なぜかと有村聞きました。有村的にまとめた理由はこう。

・設計の基本は、その機能(たとえばトグルリスト、とかボタン、とか)をそれぞれモジュールとして考える。
・見た目ではなく機能として捉える。
・そうなったとき、上のルールでclass名が長くなりすぎる = 複数のモジュールがひとつになってしまっているのでは?と考える。
・ひとつのモジュールの目安はだいたい3ネスト。上のルールのclassで表すと、.hoge_fuga_arimura。それ以上超えたら、一度立ち止まって考える。

確かに先程のソースでは、
「メニューのリスト」と「矢印アイコンの箱」の2つにモジュールが分割できるように見えます。
それが全て「メニューのリスト」として扱われてしまっているから、こんなに長くなるのですね。

で、改良案。

自分の中でも納得がいきました!

まずはこのルールを自分の中でのベースとして、もっといい案があればどんどん取り入れたいですね!

それでは、今日はこのへんで。

既存関数をラップする

こんにちは。有村です。
ゲームは1日1時間、お勉強も1日1時間……………できれば理想ですね。

今日は手短に、「既存関数をラップする」について学んだことを書きます。

たとえばこのようなコードがあったとします。。

なんということはなく、hogeというclassを持つ要素をクリックしたらhoge();が実行され、hoge!ってアラートを出すだけですね。

それではこれはどうでしょうか。

追加実装で、hogeがさらにfugaというclassを持っていたら、hogeの前にfugaをアラートで出し、そうでなければ今まで通りという仕様に変わっています。

これは単純な例なのですが、実装って常に新規とは限らないですよね。
「既存の機能にあれを足したい」とか「この条件を変えたい」とか、そういうパターンのほうが多い気がします。
そうなったとき、上のコードで改良ポイントがあるとしたら、既存の関数を書き換えていることかなと思います。

というのも、hoge();は既に当初の実装でおそらく完成されており、テストも済んでいる内容です。
既存の関数を書き換えるということは、もちろんその中の処理が変わるということで、既存部分への影響考慮や関数全体の再テストが必要になります。。
なんなら、アラートにfugaを出すのは特殊なパターン(たとえばトップページだけ、とか)だけだったり、hoge();自体の処理は変えたくない!ということだってあると思います。

というわけで改良パターン。

alertの内容くらい引数で渡せや!というのは置いておいて…
どうでしょうか、既存の関数hogeは何も変わらず、代わりに「classにfugaを持っていたらこっち、持っていなかったらこっち」という案内役の関数と、fugaを持っていた場合の関数が足されました。
これであれば、既存関数hoge();自体は何も変わっていないので、影響の考慮やhoge();のテストは必要なくなりますね!

実装者は「今回の実装で既存の機能がぶっ壊れたんだけど;;」という展開を一番恐れる気がします…。
ので、できるだけ影響範囲が少なく、テストがしやすい実装を心がけたいものです!

それでは、今日はこのへんで。
ゲームしよう。

原則を知る ーDRYー

こんばんは、原田です。

さっき地元の知り合いから電話がきて、地元に帰りたくなりました。はい。

 

 

最近、上司に「どれが良い実装で、どれが悪い実装なのかが分からない」と相談しました。

すると、「原則を知るといい。」という助言を頂きました。

原則  …特別な場合は別として、一般に適用される根本的な法則。

確かに、原則を知ることは、いいコードが分かる導きになるかもしれないと思い、これからちょいちょい原則を書いていこうと思います!!!

 

ではでは、

今日の原則は〜・・・・

DRY

です。

乾燥という意味ではありません。(知らなかったのは私だけですかね?)

DRY(Don’t  Repeat Yourself)

重複を防ぐ考え方。

Single Source of truthとも言うそうです。

 

なぜ重複を防いだ方が良いのか?

重複が多い→変更時に変更箇所が増える→時間がかかる

情報量が多い→明確でない→不一致が生じる可能性がある

という点があるからだそうです。

 

ということで、今後はまとめることができたり、同じような実装が複数ある場合は、関数化したりしてDRYに努めようと思います。