goo blog サービス終了のお知らせ 

Psalm

プログラマ向け技術メモ

DOMのonclickプロパティに引数ありの関数を指定する方法。

2009-03-24 11:18:57 | JavaScript
例えば、こういうパターン。

for(var i=0; i<10; i++) {
    var link = document.createElement("a");
    var url = "xxxxxxxx?id=" + i;
    var onclickEvent = function() {
        location.href = url;
        return false;
    }

    link.onclick = onclickEvent;
    link.setAttribute("href", "javascript:void(0)");
    link.appendChild(document.createTextNode("URLその" + i));
}

for文でiを+1ずつしたリンクを10個作成している。
ように見える。
が、リンクをクリックしてみるとIDは常に9なのである。
リンクをクリックしたときにはfor文回り終わってるんだから当たり前である。
う~む、これはいけてない・・・
という訳で、調べてみたら素晴らしい解決法を発見。

    var onclickEvent = (function(num) {
        return function() {
            location.href = url + "&id=" + num;
            return false;
        }
    })(i);

どうやら(i)がミソらしい。
これがあることによって、function(num)のオブジェクトを
即時に作ってくれるのだそうで。
う゛~~~~ん。奥が深いな、Javascript!

マウスポインタの座標取得(IE限定)

2008-09-04 11:43:07 | JavaScript
現在のマウス座標:
window.event.clientX
window.event.clientY

スクロールバーの移動量:
document.body.scrollTop

画面の高さ:
document.body.clientHeight

つまり、スクロール分を含むページの縦サイズは

document.body.scrollTop + document.body.clientHeight

となるわけだ。
さらに、divブロックの高さは

document.getElementById(id).clientHeight

で取得できるので、これらを組み合わせて計算すると
程よく画面からはみ出さない位置にdivブロックを表示できる。
前々回書いたソースでは、divブロックが画面縦サイズより大きい場合に
上が切れてしまうので、少し修正した。

var x = window.event.clientX;
var y = window.event.clientY;
var windowHeight = document.body.clientHeight;
var element = document.getElementById(id);
var elementHeight = element.clientHeight;

// 説明表示位置を決定する
x = x + 10;
if( (windowHeight - 20) < elementHeight ) { // 上が切れる
y = 20 + document.body.scrollTop;
} else if((windowHeight - y) < elementHeight) { // 下が切れる
y = windowHeight - elementHeight - 20 + document.body.scrollTop;
} else {
y = y - 10 + document.body.scrollTop;
}

さて、ここでも注意点がひとつ。いや、ふたつ。
このような使い方をする場合、divブロックの初期状態は
display:noneか、visibility:hiddenになっているだろう。
visibility:hiddenでこの機能を実装したら、何故かdivブロックに載せた
tableのborderが隠れてくれなかった。
Windows2000のIE6では正常に動作するが、XPのIE6では駄目。
仕方なくdisplay属性を使うことにしたが、初期状態noneでは
element.clientHeightが取得できず、0が返ってきてしまう。
これまた非常によろしくない。
迷った末、divブロックの初期表示はdisplay:blockにして
x座標を3000、つまりページの外に配置することで対処した。
で、前回の横スクロール禁止が出てくるわけである。

見ちゃ駄目!

・・・いいのか、そんなことで。

時刻の桁合わせ

2008-09-03 18:14:57 | JavaScript
桁数分0をくっつけて、右からX桁を切り取る。

/*
* 現在時刻をyyyy/MM/dd hh:mm:ss.SSS形式で取得
*/
function getDateStr() {
var now = new Date();
var month = conv2deg(now.getMonth()+1);
var date = conv2deg(now.getDate());
var hours = conv2deg(now.getHours());
var minutes = conv2deg(now.getMinutes());
var seconds = conv2deg(now.getSeconds());
var milSec = conv3deg(now.getMilliseconds());
var dateStr = now.getFullYear() + "/" + month + "/" + date + " ";
dateStr += hours + ":" + minutes + ":" + seconds + "." + milSec;

return dateStr;
}

/*
* 時刻の桁あわせ(2桁)
*/
function conv2deg(val){
val = "00"+val;
return val.substr(val.length-2,2);
}

/*
* 時刻の桁あわせ(3桁)
*/
function conv3deg(val){
val = "000"+val;
return val.substr(val.length-3,3);
}

JavaScriptからJSPに値を渡す

2008-08-29 20:22:57 | JavaScript
JSPからJavaScriptに値を渡すのはformを使えば簡単にできるが
逆は意外と難しい。
JavaScriptで値を取得してから一度、サーバにリクエストを投げないと
画面の再描画が行われないからだ。

が、JavaScriptでformの値を操作できるというところに着目すると
やや反則的ではあるが、サーバにリクエストを飛ばさなくても
JavaScript変数の値を表示することはできる。
つまりformを使うのである。
表示したい項目を

<input type="text" name="xxx" style="background-color: #f5f5dc; border: none;" readonly>

と書いておく。JavaScriptの中では

document.xxxForm.xxx.value= xxxxxx;

とセットしてやれば、セットした値がテキストフィールドに表示されるのだ。
ミソは、テキストフィールドをテキストフィールドでないかのように
見せてしまうところだ。
border:noneで境界線を消し、background-colorで背景色を揃えればOK。
あとはbodyにonLoadを設置して、ページ読み込みのタイミングで
JavaScriptから値を貰えば良い。

え?
ふざけんなって?
まあ、でも、一般の人はソースとか見ないだろうし
一応、表示はできてるヨ。(遠い目)




誰だ、こんな無茶振りしやがったやつは。

JavaScriptでsleep

2008-08-29 12:52:23 | JavaScript
テーブル要素にカーソルを当てると、ちょっとしてから説明が表示されるような
画面を作りたかったので。
JavaScriptにはsleep関数はないので、代わりにsetTimeout()を使う。
要するにこんな感じ。

// 説明を表示する
function setCaption(id) {
var x = window.event.clientX;
var y = document.documentElement.scrollTop + window.event.clientY;
var windowHeight = document.body.scrollTop + document.body.clientHeight;
var element = document.getElementById(id);
var elementHeight = element.clientHeight;

// 説明表示位置
x = x + 10;
if( (windowHeight - y) <elementHeight ) { } else {
y = y-10;
}

viewCaption = setTimeout(
function dispCaption() {
element.style.left = x;
element.style.top = y;
element.style.display = "block";
setShim(element);
}, 500);
}

// 説明を隠す
function eraseCaption(id) {
clearTimeout(viewCaption);
var element = document.getElementById(id);
var shim = document.getElementById('shim');
element.style.display = "none";
shim.style.display = 'none';
}

マウスポインタのある位置を探して、その位置に説明が表示されるように
なっている。ちなみに0.5秒後にセット。
0.5秒経たないうちにポインタが外れた場合は、eraseCaptionを呼び出して
clearTimeoutで表示処理をキャンセルしている。

ポインタの座標の取得はブラウザに依存するので悩ましいところ。
このスクリプトではIE6.0しか考えていないので、その他のブラウザでは
動かないと思われる。笑
座標の取得のあれこれについては次回。

使えるはずの関数が使えない!

2008-08-28 18:52:05 | JavaScript
オブジェクトでサポートされていないプロパティまたはメソッドです

document.form.reset()を呼んでいるのに怒られる。
なーぜーだーと悩むこと1時間。
ボタン名が「reset」だった。
ボタン名に予約語を使うなよ。
リセットボタンから変更したときに直すのを忘れたのだ・・・

こんなエラーで悩んだときはボタン名とかフォーム名を見直そう。
同じものがあったり、予約語使ってたりするはず。