ひな形スクリプト講座8

 

[ひな形スクリプト講座1][ひな形スクリプト講座2][ひな形スクリプト講座3][ひな形スクリプト講座4][ひな形スクリプト講座5][ひな形スクリプト講座6][ひな形スクリプト講座7][ひな形スクリプト講座8][ひな形スクリプト講座9][ひな形スクリプト講座10][ひな形スクリプト講座11][ひな形スクリプト講座12][ひな形スクリプト講座13][ひな形スクリプト講座14][ひな形スクリプト講座15][ひな形スクリプト講座16][ひな形スクリプト講座17][ひな形スクリプト講座18][ひな形スクリプト講座19][ひな形スクリプト講座20][ひな形スクリプト講座21][ひな形スクリプト講座22][ひな形スクリプト講座23][ひな形スクリプト講座24][ひな形スクリプト講座25][ひな形スクリプト講座26][ひな形スクリプト講座27][ひな形スクリプト講座28][ひな形スクリプト講座29][ひな形スクリプト講座30][参考資料索引]

前回はイベントとイベントハンドラについて学習しました。そこで代表的なイベントハンドラを紹介しておきます。あ〜スクリプトで出てくる用語やプロパティ・メソッドなどは逐一覚えてからだと先に進まなくなりますので、覚える努力はしなくて結構です。いまはインターネット時代、必要な時それらはいつでも検索して見つけることができますからね。必要な時に必要なものだけを見つけてくればいいのです。何度も使うものは自然に覚えますから。

ページが読み込み完了したら・・・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>

方向転換時に移動速度変更

 

以外に面白い動きになりますね。次回は移動しながら消えたり現れたり?スクリプトでフィルタを操作してみましょう。


[ひな形スクリプト講座1][ひな形スクリプト講座2][ひな形スクリプト講座3][ひな形スクリプト講座4][ひな形スクリプト講座5][ひな形スクリプト講座6][ひな形スクリプト講座7][ひな形スクリプト講座8][ひな形スクリプト講座9][ひな形スクリプト講座10][ひな形スクリプト講座11][ひな形スクリプト講座12][ひな形スクリプト講座13][ひな形スクリプト講座14][ひな形スクリプト講座15][ひな形スクリプト講座16][ひな形スクリプト講座17][ひな形スクリプト講座18][ひな形スクリプト講座19][ひな形スクリプト講座20][ひな形スクリプト講座21][ひな形スクリプト講座22][ひな形スクリプト講座23][ひな形スクリプト講座24][ひな形スクリプト講座25][ひな形スクリプト講座26][ひな形スクリプト講座27][ひな形スクリプト講座28][ひな形スクリプト講座29][ひな形スクリプト講座30][参考資料索引]