ワテの場合、最近では物忘れが多い。
いろんなサイトを見ていると、こんなボタンがある場合がある。
どうやってそう言う機能を作成するのか、何度か調べたのだが良く忘れるのでその備忘録。
JavaScriptを使ってやれば簡単に実装出来る。
では、早速やってみよう。
前のページに戻るボタン
<a href="javascript:void(0);" onclick="history.go(-1);">前のページに戻る</a>
もしonclickイベントハンドラ関数をhtmlタグに入れるのでは無くて、<script>に分離したい場合には以下のようにすれば良い。
<a href="javascript:void(0);" id="prevPageID">前のページに戻る</a> <script type="text/javascript"> $(document).on('click', '#prevPageID', function () { history.go(-1); }); </script>
ここで
history.go(-1);
としている部分が重要だ。
もし二個前のページに戻りたい場合には、
history.go(-2);
次のページに進むボタン
これは簡単だ。
<a href="javascript:void(0);" onclick="history.go(1);">次のページに進む</a>
で可能である。
ところで、
href="javascript:void(0);"
これは何?
気になるので調べてみた。
href=”javascript:void(0);” とは何か?
hrefは良く知っている。
普段はこんな使い方をする。
<a href="http://www.example.com">別のページへ飛ぶ</a>
一方、今の場合にはこんなふうになっている。
<a href="javascript:void(0);" onclick="history.go(1);">次のページに進む</a>
まず、
void(0)
はJavaScriptの演算子 voidだ。
void 0
でも良い。
計算結果は
undefined
となる。
JavaScriptの鬼門 undefined とは何か?
JavaScriptのundefinedとは、JavaScriptにある六つの基本型のうちの一つだ。
例えばMozilla Developer Networkの解説を引用すると以下の通り。
A primitive (primitive value, primitive data type) is data that is not an object and has no methods.
In JavaScript, there are 6 primitive data types:
- string,
- number,
- boolean,
- null,
- undefined,
- symbol (new in ECMAScript 2015).
引用元 https://developer.mozilla.org/en-US/docs/Glossary/Primitive
二年前にJavaScriptを勉強し始めたワテはこのundefinedの意味を理解出来るまで数カ月掛った。でも今でも時々混乱するが。
undefined判定方法(あまりお勧めしない)
undefinedの使い方としては、同じくMozilla Developer Network から引用すると以下の通り。
何らかの変数 xがundefinedかどうかを判定するなら以下の通り。
var x; if (x === undefined) { // xがundefinedの場合はこちら } else { // xに何らかの値が入っている場合はこちら }
となる。
要するにxは宣言されているけれども初期値を与えられていない状態がundefinedとなる。
ところが、もし var x の宣言自体が無い場合には、上の判定では例外が発生する。
つまり、
// var x; if (x === undefined) { // throws a ReferenceError }
変数xを宣言せずに使うと例外が発生する。
なので、お勧めのundefined判定は typeof演算子を組み合わせた判定方式だ。
typeofを使ったundefined判定方法(ワテお勧め)
typeof演算子を使うと、以下のどちらの場合でも文字列 ‘undefined’ を返す。
- その変数が未宣言の場合
- 宣言済だが初期化されていない場合
なので、兎に角変数がundefinedかどうかを判定したいなら以下の様にするのが分かり易い。
// var x; // x の宣言を忘れている if (typeof x === 'undefined') { // 例外発生せずにtypeofの評価結果trueが得られる // xが未宣言でも未初期化でもここに来る } else { // xが宣言済で、かつ何らかの値が入っている場合はこちら }
この例では x が未宣言だが、コメントを解除して
var x;
としても、宣言済だが未初期化なので ‘undefined’ 判定となる。
ワテお勧めのundefinedやnull判定関数
ついでにnull判定もしたい場合には、以下のようにすると良い(ワテの場合)。
function isNullOrUndefined(some_variable) { if (typeof (some_variable) === 'undefined' || some_variable === null) { return true; } else { return false; } }
コード1. ワテが良く使う function isNullOrUndefined(some_variable) 関数
あくまでワテの理解は、JavaScriptのnullと言うのは、他の言語(C, C++, C#など)のnullと同じと思って良い。変数は宣言されているけれども中身が空の状態(nullで初期化されている)。undefinedは宣言されているけれども初期化されていない状態。
まあ、今でもワテの場合には、JavaScriptのこのnullとundefinedの区別が嫌いなので、isNullOrUndefined()関数を使いまくっている。
href=”javascript:void(0);” の話題に戻る
さて、void(0) の話題から脇に逸れてしまったが、兎に角 void(0) の計算結果はundefined型が帰る。
で、肝心の
<a href="javascript:void(0);" onclick="history.go(1);">次のページに進む</a>
この部分であるが、
href="javascript:void(0);"
では何もしない事を意味するのだが、良く分からないと言う人もいるだろう。
こんな風に書くと分かり易い。
<a href="javascript:void(0)">クリックで何もしない</a> <a href="javascript:alert('あ')">クリックでメッセージ表示する</a>
後者のaタグをクリックするとalert文が実行される。
まあ、こんな記述が必要な場面は滅多に無いと思うが。
と言う事で、
href="javascript:void(0)"
の javascript: は
href="http://www.example.com"
の http: に相当すると思っておけば良いのかな。
で、結局、href=”javascript:void(0);” の意味はaタグのリンク文字列をクリックしても何もしないと言う意味になる(ワテの理解)。
<a href="javascript:void(0)">クリックで何もしない</a>
それと似たようなのに
<a href="#">クリックするとページのトップに移動する</a>
があるが、これだとクリックでページの先頭に戻ってしまう。
それを以下のように書き換えると、クリックで何もしない動作となる。
<a href="#" onclick="return false;">クリックで何もしない</a>
それでようやく冒頭に登場した以下の記述であるが、
<a href="javascript:void(0);" onclick="history.go(1);">次のページに進む</a>
クリックしたら onclick の history.go(1); を実行すると言う意味だ。
なので、以下のように書いても良い。
<a href="#" onclick="history.go(1);">次のページに進む</a>
上の例では、クリックした瞬間に次ページに遷移するのでページのトップに移動する動作自体が無視される。
一般には以下のような記述をして、クリックしたらmyfuncを実行出来る。
<a href="#" onclick="myfunc();">同じページ内で関数を実行</a>
しかし、これだと関数は実行出来るが、実行したらページのトップに移動してしまう。
ページトップに戻るというデフォルトの動作をキャンセルする為には、最後に falseをリターンしておくと良い。
<a href="#" onclick="myfunc();return false;">同じページ内で関数を実行</a>
と言う事で、ようやく↑の記述の意味を理解出来た。
What does “javascript:void(0)” mean?
Attention Required! | Cloudflare
にも javascript:void(0) の詳しい説明があるが、英語なのでワテには良く分からない。
以下、余談になるが、ワテが良く混乱するjQueryのイベントハンドラ処理に関して備忘録的メモを書いておく。
jQueryの .on(‘click’, handler ) に関して
ワテの場合には、
$(selector).on('click', handler )
をよく使う。
以前は、
$(selector).click( handler )
をよく使っていた。
どちらも機能的には同じで、例えば
$('#prevPageID').on('click', function () { history.go(-1); });
$('#prevPageID').click( function () { history.go(-1); });
のどちらでも前のページに戻る動作が可能だ。
でも、.click() はあくまで .on() のショートカット版なので、正式版である .on() を使うようにしている。
JQueryのイベントハンドラには
.on() .click()
以外にも、
.change() .click() .dblclick() .hover() .mousedown() .mouseenter() .mouseleave() .mousemove() .mouseout() .mouseover() .mouseup() .on() .scroll() .select()
など沢山ある。
jQueryの最近のバージョン V3.1.1 ではショートカット版のハンドラ関数がサポートされていない場合もあるので、注意が必要だ。
ワテの経験では兎に角 .on() を使って
.on('click', ... .on('change', ... .on('mouseenter', ...
などとしておけば間違いない。
$(document).on(‘click’, selector, function() )について
今回、冒頭の例で使った .on() は $(document) に対して設定していて、引数の中に selector を記述している。
$(document).on('click', '#prevPageID', function () { history.go(-1); });
こんな感じ。
それを、
$('#prevPageID').on('click', function () { history.go(-1); });
と書いても同じ動作となる。
両者の違い
前者の場合には
$(document).on('click', '#prevPageID', function () ...
となっているのでHTMLのdocumentをクリックした場合に反応する。
その時にもしクリックされたものが #prevPageID であれば関数が実行される。
一方、後者の場合には
$('#prevPageID').on('click', function () ...
なので、#prevPageID がクリックされた場合に関数が実行される。
じゃあ同じじゃあないの?
確かに同じである。
では、どういう場合に使い分けるのか?
それは、例えば id=prevPageID を持つ a タグをこのように作ったあとで、
<a href="javascript:void(0);" id="prevPageID">前のページに戻る</a>
何らかの理由で削除したとする。
そして、再びJavaScriptなどを使って同じ id=prevPageID を持つ aタグを追加したとする。
その場合には、一旦削除した時点で
$('#prevPageID').on('click', function () ...
のハンドラの設定も消えてしまうので、あとで作り直した aタグをクリックしてもハンドラが実行されない。
一方、前者の
$(document).on('click', '#prevPageID', function () ...
の場合には id=prevPageID を持つ aタグを削除して追加し直したとしても、ハンドラ関数の設定はページが有る限り存在し続けている document要素に対して割り当てられている。
なので、この方式で id=prevPageID を持つ aタグに割り当てられているハンドラ関数は aタグを削除してあとに再び追加しても、その aタグをクリックするとハンドラ関数が正しく動作する。
$(document).on(‘click’, はどんな時に使うと良いのか?
あくまでワテの経験で言うと、例えばページにFormとSubmitボタンが有って、ボタンクリックでサーバーにAjax実行を行い、htmlデータを取得する。
そのhtmlデータの中にあるa タグにハンドラ関数を割り当てたい場合には、このdocumentの手法を使っておけば最初に一回だけ実行しておけばよい。
もしそれを
$('#prevPageID').on('click', ...
の手法でやると、Ajaxする度にhtmlが更新されるのでこの .on() の割り当て処理も毎回やる必要がある。
まとめ
最近、とあるWEBサイトを作っているのだが、その中で FormにSubmit Buttonを入れてAjaxする処理を良く書いた。
その時にこの $(document).on(‘click’, はとっても便利だった。
コメント