jQueryを読み込んだページを用意し、ボタンとDIV だけおいておく。
<!doctype html>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"></script>
<button id="b1">生成</button>
<div id="d1"></div>
<script>
// ここにあとから追加すると思う
</script>
(ソース)
ボタンを押すと関数 go を呼び出すことにしておく。
HTMLで書くなら、
<button onclick="go()"> ...
JS(jQuery)で呼び出すなら(以下のコードは、ソースのscriptタグに書いてもいいし、 コンソールで実行してもいい。)
$('#b1').click(go)
勿論、書き方はいろいろあって
$('button').click(go)
// タグ名で指定してもいいし、
var b=$('button')
b.click(go) // 一度変数に入れてから使ってもいい
注)この$
関数を呼び出すときの引数として、文字列を渡し、 その文字列の中には、タグ名、ID名、クラス名などが指定できる。
つまり、CSSセレクタとして使えるものが様々な組み合わせ方で利用可能。 詳しくは、「jQuery CSS」などで検索すると見つかるだろう (たとえばこのページなど)。
$
関数はこの使い方のときは、該当する要素が見つかっても見つからなくても(複数見つかっても)返す値はいつも jQueryオブジェクト。
タグ名を指定すると、該当するタグで作られた要素をすべて保持したjQueryオブジェクトとなる。ネイティブの関数 getElementsByTagname と動作は似ている。
id名を(CSSのルールに沿って ‘#b1’ のように #
を前置して)指定した場合は、おそらく1個だけ(または0個)見つかる該当要素、 を含む jQueryオブジェクトが返される。
getElementById と似ているが、getElementById が単数形の名前の関数で、要素を1つだけ返す(複数形の関数の返す値と扱い方が変わってくる)のに対し、
jQUeryでは対象がいくつでも同じように jQUeryオブジェクトを返す。
関数定義の枠組み
function go() {
// (中身はあとで)
// あるいは console.log("押した") でも入れておいてもいい
}
とりあえず中身なし
$('<div>')
$
関数の引数(文字列)として、 HTMLのタグの形式(<
~ >
で囲む)のものを渡すと、ただし、生成しただけでは表示されない(DOMのどこに位置づけるかが指定されていない)ので、
生成したオブジェクト(これもjQueryオブジェクト)を、 DOMのどこかに差し挟むべく、以下のような呼び出しが必要になる。
$('<div>').appendTo('#d1')
// または
$('#d1').append('<div>')
中身を、$
関数に与える文字列の中に HTMLの文法で書いてもいい ($('<div>あいうえお</div>')
のように)が、
今は、属性で与える以下のような書き方が使えるので、 そちらが好まれているようだ。
$('<div>',{text: "あいうえお"})
$
関数の第1引数が(前項と同様に)タグ形式の要素名、 第2引数として連想配列(オブジェクト)の形で (ブレース { }
で囲んで、コロン :
で対にする) 要素の属性名と属性値を渡す。属性はあとから変更したり追加したりもできる
$('<div>',{id: "dx1"})
// ...
$('#dx1').attr("text", "かきくけこ")
.text
メソッドが呼べる$('#dx1').text("かきくけこ")
$
)という名のオブジェクト(変数)、と関数
$
が使われる.click()
// 動作を指定する.toggle()
// 表示をオン/オフする.appendTO(..)
// 対象のDOM要素の末尾に追加する.attr(..)
// 属性を変更する.text(..)
// 表示文字列を変更する$(....).xxxx(...)
のような式全体の値)は、 ピリオドの左側のjQueryオブジェクトそのもの。
$(....).xxxx(...).yyyy(...)
のように、結果に対してさらに 連鎖的にメソッド呼び出しを行うことができる(メソッドチェーンと呼ばれる)。$
(またはjQuery)関数の主な用途(を、整理しておく)
要素を取得する(タグ名やCSSセレクタを文字列として渡す)
要素を生成する(HTMLで書くようにタグを <
~ >
で囲んで文字列で渡す)
document(Webページ)が readyになった時(読み込みが完了した時点)に行うべき処理を指定する(関数を渡す)
$( 関数 )
という呼び方になる。 引数として渡すものは、定義済みの関数名でもいいし、 ここに無名関数をベタ書きしてもいい。
後者の場合、長い定義になるため、
$(function(){
// 中略
// (長いプログラム)
})
または、
$(()=>{
// 中略
// (長いプログラム)
})
のような形になるだろう。
JSでは繰り返しの書き方がいくつかある。
for を使った構文( C Java と同じような)
for(var i=0 ; i<10 ; i++) console.log(i)
Array(配列)と forEach (または map) を使った書き方
[...Array(10).keys()].forEach(()=>console.log(i))
この動作は、一見して分かりづらいが、コンソールで、中から順々に、
Array(10)
Array(10).keys
Array(10).keys()
[...Array(10).keys()]
map についてはここでは省略しておく。
メソッド forEach にわたす引数も、関数、とされている。ので、 定義済みの関数名を渡してもいいし、 無名関数(function キーワード または =>
(ダブルアロー)を使って書く)を渡してもいい。
上記の例ではダブルアローで書いてあり、 その無名関数の本体(実行する部分)が単一の式なので、 ブレースで囲むことを省略している(ダブルアローを使う場合に省略が許されているので)。
他に、
もあるが、ここでは割愛する(機会があればこれも学んでおいて下さい)。
100個のボタンを生成
[...Array(100).keys()].foreach(()=>$(<button>,{text: "ボタン"}))
これだとぜんぶ同じ表示になって面白くないので、 * 番号を表示してボタン生成
[...Array(100).keys()].foreach((i)=>$('<button>',{text: `__${i}__`}).appendTO('body'))
文字列について:
本ページでは文字列を囲む記号として ' '
(シングルクォート) " "
(ダブルクォート)を混在して使ってきている。JSではどちらで囲んでも意味は変わらないので、そのつもりで読んでおいて下さい。
ただし、ひとかたまりの文字列を囲むときに その左側と右側が同じクォート文字でないといけない。
さらに最近では ` `
(バッククォート)で文字を囲むこともできる。
このバッククォートで囲んだ文字列は、式展開を有効にするやや特殊な囲み方(式展開を使わないときには使わないのが普通)。
バックォート文字列の中に、${ }
のように、$
を前置したブレースで囲んだ部分があると、 その中身が式として評価(計算)され、その結果の値が文字列として、 その場所に展開される。
セミコロンについて:
昔のJavascriptではCやJavaと同様に文末にセミコロン(;
)が必要だった (そういう書き方をしている資料もまだ多数ある)が、
今は行の終わりで(文法的に継続する可能性がある書き方をしている場合を除いて)式が終了している時にはセミコロンは省略できる。
ので、本ページの実行例でも、殆どセミコロンを使わない書き方をしている。
ただし、セミコロンをつけないとうまく動作しないケースも時々ある (ここでは詳しくは省略するが) ので、曖昧な時にはセミコロンをつけるようにするといいだろう (入力してみてエラーが起きてから対処しても大丈夫だが)。 #### 一括処理
前前節で沢山生成したボタンについて、
すべてのボタンの表示をオン/オフする:
$('button').toggle()
* 一括生成したボタンだけを一括でオン/オフ:
いちどページを再表示させてボタンを生成しなおしておこう。
[...Array(100).keys()].forEach((i)=>$('<button>',{text: `__${i}__`,class:'nn'}).appendTo('body'))
* こんどは属性として class:'nn'
も追加してあることに注意。
* こうして nn というクラス名を持つ要素だけを選んで操作するときは、
$('.nn').toggle()
このように、複数の要素(を保持するjQueryオブジェクト)に対して、 単一のメソッド呼び出しをすることで、一括操作が実現できる。
なお、以下のようにまとめて消去することもできる。
$('.nn').remove()
一括処理ではなく、この複数の要素に対して、 個別の処理を行いたい場合は、 jQueryの eachメソッドを使うことになる。
1つ実施例を示す。
var colors=["red", "white", "black", "yellow", "blue"]
// と、準備しておいて、
//(上記の100個のボタンがクラスnn で作成されているとして)
$('.nn').each(function(i){
$(this).attr('style',`background-color:${colors[i%5]}`)
})
または、あらかじめ関数を用意して、名前で呼び出してもいい。
// 色のリストの準備は省略
function chg(i) {
$(this).attr('style',`background-color:${colors[i%5]}`)
}
$('.nn').each(chg)
i%5 の値の意味については、
[...Array(15).keys()].forEach((i)=>console.log(`${i} -> ${i%5}`))
などの実験をすると理解しやすいだろう。
これらを、ボタン動作で動作させるとしたら、以下のようなHTMLファイルにするといい。
<!doctype html>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"></script>
<button id="b1">生成</button>
<button id="b2">変更</button>
<script>
const colors=["red", "white", "black", "yellow", "blue"]
function chg(i) {
$(this).attr('style',`background-color:${colors[i%5]}`)
}
function gen() {
[...Array(100).keys()].forEach((i)=>
$('<button>',{text: `__${i}__`,class:'nn'}).appendTo('body'))
}
$(()=>{
$('#b1').click(gen)
$('#b2').click(()=>$('.nn').each(chg))
})
$('.nn').each(chg)
</scri pt>
(ソース)