
前回はイベントとイベントハンドラについて学習しました。そこで代表的なイベントハンドラを紹介しておきます。あ〜スクリプトで出てくる用語やプロパティ・メソッドなどは逐一覚えてからだと先に進まなくなりますので、覚える努力はしなくて結構です。いまはインターネット時代、必要な時それらはいつでも検索して見つけることができますからね。必要な時に必要なものだけを見つけてくればいいのです。何度も使うものは自然に覚えますから。
ページが読み込み完了したら・・・onload
ページが読み込み完了したとはHTMLドキュメントの一番最後の行まで読み込まれたらということです。IEやOEなどのHTML表示ソフトウェアは、一番最初の行から順番に一行ずつ読み込んで解釈していきます。
ページが切り替わったら・・・onunload
ページが切り替わるのは、勿論表示ページが移動した場合ですが、ページが閉じられる(ソフトウェアが終了される)時にも起こります。
クリックしたら・・・onclick
エレメントをクリックした時発生するイベントをキャッチします。
ダブルクリックしたら・・・ondblclick
マウスボタンを押したら・・・onmousedown
マウスボタンが戻ったら・・・onmouseup
マウスカーソル(ポインタ)が通過したら・・・onmuseover
マウスカーソル(ポインタ)が離れたら・・・onmouseout
主なイベントハンドラ
| onabort | onafterupdate | onbeforeunload | onbeforeupdate |
| onblur | onbounce | onchange | onclick |
| ondataavailable | ondatasetchanged | ondatasetcomplete | ondblclick |
| ondragstart | onerror | onerrorupdate | onfilterchange |
| onfinish | onfocus | onhelp | onkeydown |
| onkeypress | onkeyup | onload | onmousedown |
| onmousemove | onmouseout | onmouseover | onmouseup |
| onreadystatechange | onreset | onresize | onrowenter |
| onrowexit | onscroll | onselect | onselectstart |
| onstart | onsubmit | onunload |
ここではこのくらいにしておきましょう。まだまだたくさんあります。IEでは独自のイベントハンドラもあります。
それでは・・・んとなにするんでしたっけ?そうそう前回のソースには問題があるって書きましたね。
onloadのところで書きましたように、HTMLを表示するソフトウェアは、HTMLドキュメントのソース内容を一度読み込んでから、それから処理をするという手順でページを表示しているのではなく、ソースの最初の行から順番に読み込みながらその都度表示処理をしていきます。スクリプトも同様に順番に読み込まれて処理されますから、書いてある位置で命令を受ければ処理実行されます。イベントハンドラではスクリプトでその処理を記述しますね。onload="処理"でしたね。
ところで例えば<body onload="img1.style.border='red 2px solid'">のように記述した場合、クリックするとimg1の枠線を赤で2ピクセルの実線にするということになりますが、このクリックした時にimg1エレメントがまだ読み込まれていなかっただどうなるでしょう?表示ソフトはスクリプトで指定されたimg1エレメントをまだ認識していません。ということはimg1というエレメントが見つからない状態になるわけですね。結果は・・・img1は無いという様なエラーが出ることになります。
また次のような場合もクリックするタイミングによってはエラーになることがあります。
<img id="img1" onclick="imgChange()" src="syasin1.jpg">
<script>
function
imgChange(){
img1.src="syasin2.jpg"
}
img1エレメントをクリックしたらimgChange()関数を実行しなさいということになりますね。しかしいままさにimg1の画像ファイルsyasin1.jpgを読み込み中であった場合、まだスクリプト部分(関数imgChange())は読み込まれていません。表示ソフトはimgChange()関数を実行しろという命令を受けますが、肝心のその関数は記憶されていないので、実行しようがありませんね。
スクリプトを記述する場合は、スクリプトで処理される内容がその時点で読み込み完了していなければ実行に移せません。読み込み完了していない内容に働きかけようとするとエラーになります。イベントハンドラで処理する場合も含めて記述順番に中止してくださいね。
尚以前にも書きましたが、関数は読み込まれたら一旦メモリに記憶されます。関数は呼び出されない限り実行されませんので、関数の中で処理する内容が読み込み完了していなくても、実行されない限りはエラーにはなりません。あくまでも実行された時に読み込み完了されていればいいのです。
ということでスクリプトではどこに記述しても構わないソースは<head>〜</head>内に書くのが基本となっています。
さて前回のソースをもう一度見てください。
<body
onclick="clstart()" style="margin:0px;
overflow:hidden">とありますが、clstart()関数を記述しているのはもっと下の方になります。その記述場所まで読み込み完了していない時にクリックするとどうなるか・・・明白ですね。
但し、実際に試してもほとんどエラーにならないと思います。それほど長いソースではない上に、他で読み込みに時間がかかるものがほとんどなく、あっという間に全体が読み込まれます。読み込みが完了しない内にクリックするということ自体が難しいのですが、もっと複雑な文書である場合、読み込みに時間がかかることが多々あり、結果エラーになりやすくなるので、記述順番には注意が必要です。
では、エラーにならないように書き換えてみましょう。これも一方法として示します。
[ソース]
<html>
<head>
<title></title>
</head>
<body
style="margin:0px;
overflow:hidden">
<img id="img1" src="akiakane.gif"
style="position:absolute; left:0px; top:100px; width:100px">
<script>
var
ix=5//一度に動くピクセル数
var iy=5//一度に動くピクセル数(縦)
var rtime=10//繰り返し実行時間(ミリ秒)
function
lidou(){//右移動する関数
if(img1.style.pixelLeft+ix>=document.body.clientWidth-img1.clientWidth){
if(img1.style.pixelLeft<document.body.clientWidth-img1.clientWidth){
img1.style.pixelLeft=document.body.clientWidth-img1.clientWidth
}else{
ridou()
return
}
}else{
img1.style.pixelLeft+=ix
}
//status=img1.style.pixelLeft
setTimeout("lidou()",rtime)
}
function
ridou(){//左移動する関数
if(img1.style.pixelLeft>0){
if(img1.style.pixelLeft-ix<0){
img1.style.pixelLeft=0
}else{
img1.style.pixelLeft-=ix
}
setTimeout("ridou()",rtime)
}else{
lidou()
return
}
}
function
didou(){//下移動する関数
if(img1.style.pixelTop+iy>=document.body.clientHeight-img1.clientHeight){
if(img1.style.pixelTop<document.body.clientHeight-img1.clientHeight){
img1.style.pixelTop=document.body.clientHeight-img1.clientHeight
}else{
uidou()
return
}
}else{
img1.style.pixelTop+=iy
}
setTimeout("didou()",rtime)
}
function
uidou(){//上移動する関数
if(img1.style.pixelTop>0){
if(img1.style.pixelTop-iy<0){
img1.style.pixelTop=0
}else{
img1.style.pixelTop-=iy
}
setTimeout("uidou()",rtime)
}else{
didou()
return
}
}
var
saikoro=Math.floor(Math.random()*4)+1
status=saikoro
switch(saikoro){
case
1:
img1.style.pixelLeft=-img1.clientWidth
img1.style.pixelTop=Math.floor(Math.random()*(document.body.clientHeight+img1.clientHeight+1))-img1.clientHeight
break
case
2:
img1.style.pixelTop=-img1.clientHeight
img1.style.pixelLeft=Math.floor(Math.random()*(document.body.clientWidth+img1.clientWidth+1))-img1.clientWidth
break
case
3:
img1.style.pixelLeft=document.body.clientWidth
img1.style.pixelTop=Math.floor(Math.random()*(document.body.clientHeight+img1.clientHeight+1))-img1.clientHeight
break
case
4:
img1.style.pixelTop=document.body.clientHeight
img1.style.pixelLeft=Math.floor(Math.random()*(document.body.clientWidth+img1.clientWidth+1))-img1.clientWidth
}
var
flag=0
function clstart(){
if(flag==0){
lidou()
didou()
}
flag=1
}
document.onclick=clstart
</script>
</body>
</html>
解説:bodyタグにあるonclick="clstart()"を削除しています。その代わりにスクリプトの最後でdocument.onclick=clstartを追加しています。このdocument.onclick=clstartもbodyクリックするとclstart()関数実行になります。
このdocument.onclick=clstartが記述されているのはソースのほとんど最後の方ですね。ということはこのクリックイベントが作動するのはほとんどの内容が読み込み完了している時です。ということは読み込み完了していないのに実行してしまうということが起きなくなるということですね。
尚document.onclick=clstart()と括弧()を付けることはできません。document.onclick="clstart()"ならばOKです。前者はVBScriptによる関数呼び出しであり、関数にポインタを地けることができません。後者はJavaScript(Jscript)によるものです。
尚、元のソースで、関数部分を<head>〜</head>内に移動しても完全ではありません。bodyクリック時に関数が全て読み込み完了していてもimg1エレメントが読み込まれていないとエラーが起きるからです。しかしそこまで厳密に考えることはないでしょう。万に一つ悪いタイミングでクリックされたところで所詮スクリプトエラーが出るだけのことです。
さあ、バウンド時に移動ピクセル数を乱数で変更しましょう。移動ピクセル数はixとiyでしたね。横方向の移動はlidou()とridou()関数でした。横方向の移動方向転換時にはixを変更、縦方向移動方向転換時にはiyを変更するとしましょう。
ixの最大値と最小値を決めましょうか。最大で50ピクセル、最小で5ピクセルにしましょう。iyも同じとしましょうか。
最大値と最小値からその間の整数の乱数を得るのは覚えてますか?
最小値以上、最大値以下の整数の乱数を得る公式・・・Math.floor(Math.random()*(最大値-最小値+1))+最小値
でしたね。
ix=Math.floor(Math.random()*(50-5+1))+5つまりix=Math.floor(Math.random()*46)+5となりますね。iyも同じです。
これも関数にしてしまいましょうか。
function ixchange(){
ix=Math.floor(Math.random()*46)+5
}
function iychange(){
iy=Math.floor(Math.random()*46)+5
}
方向転換はどこで処理していたかわかりますよね。lidou()関数からだとridou()関数を呼び出すところでした。他もほぼ同様なので説明省略しますね。
最初クリックした時もこの関数を実行させて移動ピクセルを決定させましょう。
ついでにこの値をステータスバーに表示させて起きますね。
[ソース]
<html>
<head>
<title></title>
</head>
<body
style="margin:0px;
overflow:hidden">
<img id="img1" src="akiakane.gif"
style="position:absolute; left:0px; top:100px; width:100px">
<script>
var
ix=5//一度に動くピクセル数
var iy=5//一度に動くピクセル数(縦)
var rtime=10//繰り返し実行時間(ミリ秒)
function
lidou(){//右移動する関数
status="ix="+ix+"
;iy="+iy
if(img1.style.pixelLeft+ix>=document.body.clientWidth-img1.clientWidth){
if(img1.style.pixelLeft<document.body.clientWidth-img1.clientWidth){
img1.style.pixelLeft=document.body.clientWidth-img1.clientWidth
}else{
ixchange()
ridou()
return
}
}else{
img1.style.pixelLeft+=ix
}
//status=img1.style.pixelLeft
setTimeout("lidou()",rtime)
}
function
ridou(){//左移動する関数
status="ix="+ix+"
;iy="+iy
if(img1.style.pixelLeft>0){
if(img1.style.pixelLeft-ix<0){
img1.style.pixelLeft=0
}else{
img1.style.pixelLeft-=ix
}
setTimeout("ridou()",rtime)
}else{
ixchange()
lidou()
return
}
}
function
didou(){//下移動する関数
if(img1.style.pixelTop+iy>=document.body.clientHeight-img1.clientHeight){
if(img1.style.pixelTop<document.body.clientHeight-img1.clientHeight){
img1.style.pixelTop=document.body.clientHeight-img1.clientHeight
}else{
iychange()
uidou()
return
}
}else{
img1.style.pixelTop+=iy
}
setTimeout("didou()",rtime)
}
function
uidou(){//上移動する関数
if(img1.style.pixelTop>0){
if(img1.style.pixelTop-iy<0){
img1.style.pixelTop=0
}else{
img1.style.pixelTop-=iy
}
setTimeout("uidou()",rtime)
}else{
iychange()
didou()
return
}
}
var
saikoro=Math.floor(Math.random()*4)+1
switch(saikoro){
case
1:
img1.style.pixelLeft=-img1.clientWidth
img1.style.pixelTop=Math.floor(Math.random()*(document.body.clientHeight+img1.clientHeight+1))-img1.clientHeight
break
case
2:
img1.style.pixelTop=-img1.clientHeight
img1.style.pixelLeft=Math.floor(Math.random()*(document.body.clientWidth+img1.clientWidth+1))-img1.clientWidth
break
case
3:
img1.style.pixelLeft=document.body.clientWidth
img1.style.pixelTop=Math.floor(Math.random()*(document.body.clientHeight+img1.clientHeight+1))-img1.clientHeight
break
case
4:
img1.style.pixelTop=document.body.clientHeight
img1.style.pixelLeft=Math.floor(Math.random()*(document.body.clientWidth+img1.clientWidth+1))-img1.clientWidth
}
var
flag=0
function clstart(){
if(flag==0){
ixchange()
iychange()
lidou()
didou()
}
flag=1
}
function ixchange(){
ix=Math.floor(Math.random()*46)+5
}
function iychange(){
iy=Math.floor(Math.random()*46)+5
}
document.onclick=clstart
</script>
</body>
</html>
以外に面白い動きになりますね。次回は移動しながら消えたり現れたり?スクリプトでフィルタを操作してみましょう。