たびたびすみません。また質問です。
今回はイベントについてです。
テーブルの背景をマウスのあるところだけ変更するプログラムを作りました。
要は、a:hoverと同様のことをテーブル要素にしたいのです。ここでは、横長
のテーブルでポイントしている位置をわかりやすくするために、mouseOver と
mouseOutで関数を呼んで背景を書き換えています。
一応、クロスブラウザなプログラムにしているつもりです。
IE と O7 ではうまく動いたのですが、NN7 では、何かの拍子にmouseoutの状
態の色が別の行のものになったり、行のうち一部のセルの背景のみが変わって
しまったりします。
いろいろと実験したところ、マウスをCat->Dogに動かすと、確実にDogの背景
色だけが薄緑色になったままになります。その後は右側のセルと左側のセルは
マウスに対して別々の色変化をするようになります。
もしかして、何かの拍子にセル構造が壊れてしまったりするのでしょうか?
これを防ぐ方法はあるのでしょうか?
><HTML lang="ja">
><HEAD>
><META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
><META http-equiv="Content-Script-Type" content="text/javascript">
><TITLE>テーブルホバー5D</TITLE>
><script language="JavaScript1.2">
><!--
>function init()
>{
> if(document.getElementById){
> turnoff_all(document.getElementById('tab0'));
> turnoff_all(document.getElementById('tab1'));
> }else{
> turnoff_all(document['tab0']);
> turnoff_all(document['tab1']);
> }
>}
>
>
>function turnon(_event)
>{
>if(!_event){
> _event = window.event;
>}
> if(_event.srcElement){
> _event.srcElement.parentElement.bgColor="#ffff80";
> }else{
> _event.target.parentNode.bgColor="#ffff80";
> }
>}
>
>function turnoff(_event)
>{
>if(!_event){
> _event = window.event;
>}
> if(_event.srcElement){
> row = _event.srcElement.parentElement;
> }else{
> row = _event.target.parentNode;
> }
> if(row.rowIndex % 2){
> row.bgColor = '#d0d0ff';
> }else{
> row.bgColor = '#c0ffc0';
> }
>}
>
>function turnoff_all(tab)
>{
> i = 0;
> while(tab.rows[i]){
> if(i % 2){
> tab.rows[i].bgColor = '#d0d0ff';
> }else{
> tab.rows[i].bgColor = '#c0ffc0';
> }
> i++;
> }
>}
>
>//-->
></script>
></HEAD>
><BODY onload="init()">
>
><p>
><table id="tab0" border=0 cellspacing=0 width=100%>
><tr onMouseOver="turnon(event)" onMouseOut="turnoff(event)">
><td width=50%>Ant</td><td>Bat</td>
></tr>
><tr onMouseOver="turnon(event)" onMouseOut="turnoff(event)">
><td width=50%>Cat</td><td>Dog</td>
></tr>
><tr onMouseOver="turnon(event)" onMouseOut="turnoff(event)">
><td width=50%>Elephant</td><td width=50%>Fly</td>
></tr>
></table>
><br>
><br>
><table id = "tab1">
><tr onMouseOver="turnon(event)" onMouseOut="turnoff(event)">
><td width=50%>Elephant</td><td width=50%>Fly</td>
></tr>
><tr onMouseOver="turnon(event)" onMouseOut="turnoff(event)">
><td width=50%>Goat</td><td>Hip</td>
></tr>
></table>
><br><br><br>
>
>
><p>
><p>
></div>
><br><br>
>
></BODY>
></HTML>
--
Takashi YOSHIMI mailto:tak-y...@rio.odn.ne.jp
In message news:bc1q7r$24kg$1...@nwall2.odn.ne.jp
"Takashi YOSHIMI" <tak-y...@rio.odn.ne.jp> wrote ...
> いろいろと実験したところ、マウスをCat->Dogに動かすと、確実にDogの背景
> 色だけが薄緑色になったままになります。その後は右側のセルと左側のセルは
> マウスに対して別々の色変化をするようになります。
> もしかして、何かの拍子にセル構造が壊れてしまったりするのでしょうか?
手持ちの phoenix(Gecko/20021020 Phoenix/0.3) で確認したところ、
同様の症状でした。
デバッグ用にウィンドウをオープンし、id を全てに付けて
イベントを表示させてみたところ、テーブルの文字上では
td に対しても onMouseOver/Out が発生しているようです。
tr だけ選別して処理するだけではうまく動作しないような
イベントの発生のしかたでしたので、td で処理するとか
連動させるとか、なにか工夫が必要そうでした。
一度、イベントを全て表示されてみてはどうでしょうか。
T. Sugitawrote in <bc2g82$dd1$1...@news00.iij4u.or.jp> dated Tue, 10 Jun 2003 02:28:12 +0900
on Re: テーブルの背景変更
>In message news:bc1q7r$24kg$1...@nwall2.odn.ne.jp
>"Takashi YOSHIMI" <tak-y...@rio.odn.ne.jp> wrote ...
>
>> いろいろと実験したところ、マウスをCat->Dogに動かすと、確実にDogの背景
>> 色だけが薄緑色になったままになります。その後は右側のセルと左側のセルは
>> マウスに対して別々の色変化をするようになります。
>> もしかして、何かの拍子にセル構造が壊れてしまったりするのでしょうか?
>
>手持ちの phoenix(Gecko/20021020 Phoenix/0.3) で確認したところ、
>同様の症状でした。
>デバッグ用にウィンドウをオープンし、id を全てに付けて
>イベントを表示させてみたところ、テーブルの文字上では
>td に対しても onMouseOver/Out が発生しているようです。
>tr だけ選別して処理するだけではうまく動作しないような
>イベントの発生のしかたでしたので、td で処理するとか
>連動させるとか、なにか工夫が必要そうでした。
わたしのプログラムでも、tdのイベントをキャッチしてparent(ieの場合は
parentElement, NNの場合はparentNode)を参照し、そこのbgColorを変えてい
ます。イベントはtrのタグに書いてありましたが、イベント自体のプロパティ
はtdのものでしたので、そうしてたのです。そういうものなんだと思っていま
したが、違うのでしょうか。
trタグ内にイベントを記述しても発生するイベントはtd単位だとすると、同じ
row内で別のtd に移動すると、onmouseover/outが同じイベントに対して同時
に発生して変なことになるという可能性はありますか?
縦方向の移動、例えば下への移動でも、上の行のonmouseout と下の行の
onmouseoverが同時に起きますが、この場合は別のタグにかかれているイベン
トなので排他処理がうまくいくけど、左右に移動すると、同じタグに書かれた
イベントが同時に発生するので排他処理がうまくいかずにデータ構造が壊れて
しまうとか?
その場合、イベントをtrに書くのではなく、tdタグに書けばいいのかもしれな
い。(まだ試していません)
あと、わたしのプログラムでは target を使っていますが、NNのイベントに
は、originalTargetとかcurrentTargetとかあります。この使い分けをうまく
すればいいのかもしれませんが、まだどういう役割分担があるのかよくわかっ
ていません。
--
吉見隆 mailto:tak-y...@aist.go.jp
> あと、わたしのプログラムでは target を使っていますが、NNのイベントに
> は、originalTargetとかcurrentTargetとかあります。この使い分けをうまく
> すればいいのかもしれませんが、まだどういう役割分担があるのかよくわかっ
> ていません。
たぶん、Netscape系ではイベントキャプチャ(横取り)があるので、
横取りされなかった場合の行き先がoriginalTarget、横取りの結果
イベントが送られる先がcurrentTargetなんじゃないですかね。
推測しただけですが 久野
自己フォロー。
吉見隆さんの<bc3alg$cuk$1...@xfire.aist.go.jp>から
>>デバッグ用にウィンドウをオープンし、id を全てに付けて
>>イベントを表示させてみたところ、テーブルの文字上では
>>td に対しても onMouseOver/Out が発生しているようです。
>>tr だけ選別して処理するだけではうまく動作しないような
>>イベントの発生のしかたでしたので、td で処理するとか
>>連動させるとか、なにか工夫が必要そうでした。
その後、さらに実験を繰り返し、下に添付したプログラムを作りました。
このプログラムでは、色の変わる下にそれぞれの行とその下のセルのbgColor
を表示するボタンがあるテーブルがあります。
注目していただきたいのは、flipbg()の最後にある、対象となるrowの下の
cellのbgColorをすべてクリアする部分です。これをコメントアウトしたまま
実行し、下のボタン表を使ってbgColorを表示すると、正常な状態では
row のbgColor: 指定色、cellのbgColor:null
であるのに、NNでわざと色の異常を起こしてから同じように表示させると、
row のbgColor: 指定色、異常なcellのbgColor: 固定色
となっています。つまり、何かの拍子で変更されないはずのcellの色が固定に
なり、その後、いくらそのrowのbgColorを変更しても反映されなくなってしま
うのです。ieでは、このようなセルの色が勝手に入ってしまう現象は起きませ
んでした。
ですので、プログラムにあるようにrowの色を変更したのちに、念のためにそ
の下のセルのbgColorをすべてnullにするようにすれば、ちゃんと色が望むよ
うに変わります。ときどき、右のセル、左のセルだけが色が変化するフリッ
カーみたいのが観測できますが。
ところで、この勝手にセルの背景色が変わってしまうというのは、もしやブラ
ウザのバグなのでしょうか?
##############ここからプログラム
<HTML lang="ja">
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<META http-equiv="Content-Script-Type" content="text/javascript">
<TITLE>テーブルホバー5F</TITLE>
<script language="JavaScript1.2">
<!--
function init()
{
if(document.getElementById){
turnoff_all(document.getElementById('tab0'));
turnoff_all(document.getElementById('tab1'));
}else{
turnoff_all(document['tab0']);
turnoff_all(document['tab1']);
}
}
function flipbg(_event)
{
if(!_event){
_event = window.event;
}
if(_event.srcElement){
row = _event.srcElement.parentElement;
}else{
row = _event.target.parentNode;
}
if(row.bgColor != "#ffff80"){
row.bgColor = "#ffff80";
}else{
if(row.rowIndex % 2){
row.bgColor = '#d0d0ff';
}else{
row.bgColor = '#c0ffc0';
}
}
//// row以下のcellのbgColorをクリア///
//i=0;
//while(row.cells[i]){
// row.cells[i].bgColor = null;
// i++;
//}
////////////////////////////////////
}
function turnoff_all(tab)
{
i = 0;
while(tab.rows[i]){
if(i % 2){
tab.rows[i].bgColor = '#d0d0ff';
}else{
tab.rows[i].bgColor = '#c0ffc0';
}
i++;
}
}
function show_tab(i,j)
{
row = document.getElementById(i).rows[j];
message="";
message+="bgColor:"+row.bgColor+"\n";
k = 0;
while(row.cells[k]){
k++;
}
message+="num of cells:"+k+"\n";
for(n = 0; n < k; n++){
message+=n+" bgolor:"+row.cells[n].bgColor+"\n";
}
alert(message);
}
//-->
</script>
</HEAD>
<BODY onload="init()">
<p>
<table id="tab0" border=0 cellspacing=0 width=100%>
<tr onMouseOver="flipbg(event)" onMouseOut="flipbg(event)">
<td width=50%>Ant</td><td >Bat</td>
</tr>
<tr onMouseOver="flipbg(event)" onMouseOut="flipbg(event)" >
<td width=50%>Cat</td><td>Dog</td>
</tr>
<tr onMouseOver="flipbg(event)" onMouseOut="flipbg(event)" >
<td width=50%>Elephant</td><td width=50%>Fly</td>
</tr>
</table>
<br>
<br>
<table id = "tab1">
<tr onMouseOver="flipbg(event)" onMouseOut="flipbg(event)" >
<td width=50%>Elephant</td>
<td width=50%>Fly</td>
</tr>
<tr onMouseOver="flipbg(event)" onMouseOut="flipbg(event)" >
<td width=50%>Goat</td><td>Hip</td>
</tr>
</table>
<br><br><br>
<p>
<p>
</div>
<br><br>
<table border=1>
<tr>
<td onClick="show_tab('tab0', 0);"> tab0 row0</td>
<td onClick="show_tab('tab0', 1);"> tab0 row1</td>
<td onClick="show_tab('tab0', 2);"> tab0 row2</td>
</tr>
<tr>
<td onClick="show_tab('tab1', 0);"> tab1 row0</td>
<td onClick="show_tab('tab1', 1);"> tab1 row1</td>
</tr>
</table>
</BODY>
</HTML>
##############ここまでプログラム
# サーバーの調子が悪いもので、ダブってたらすみません。
In message news:bc3alg$cuk$1...@xfire.aist.go.jp
"吉見隆" <tak-y...@aist.go.jp> wrote ...
> わたしのプログラムでも、tdのイベントをキャッチしてparent(ieの場合は
> parentElement, NNの場合はparentNode)を参照し、そこのbgColorを変えてい
> ます。イベントはtrのタグに書いてありましたが、イベント自体のプロパティ
> はtdのものでしたので、そうしてたのです。そういうものなんだと思っていま
> したが、違うのでしょうか。
すみません。私の勘違いで、parent だったのを忘れてました。
ただ、確認したのは、parentNode.id についてです。
そこで、parentNode が td だったものの nodeName を確認したところ、
"#text" でした。
最悪 TR まで遡るという手もありかもしれませんが、
ちょっとスッキリしないところかな・・・
while (row.nodeName != "TR")
row = row.parentNode;
イベントの発生のしかたは、IEの場合については、MSDNで一部
解説されてます。(以下、IE限定)
MSの場合、イベントバブルと定義してあって、今回の場合、
デフォルトイベントハンドラがTDで呼び出され、イベントが
バブルアップして上位層のイベントハンドラ(今回の場合TR)
に渡されます。
# table にも指定していると、それも呼び出されるはず。
これを途中でキャンセルして上位層に渡さないようにする場合、
そのイベントハンドラで
event.cancelBubble = true;
とします。
イベントの発生のしかたはそれぞれ異なると思いますので、
NN7 でも一度確認してみてください。
ずいぶん前の記事の続きです。
以前の記事で、row の色を変更するプログラムを書くと、何かの拍子でその下
のcellの色が代入され、固定になってしまうことを書きました。それを防ぐた
めにcellの色をすべて初期化するという小手先の業でしのいだのです。
夏休みになって時間がとれたために、これをいよいよウェブページ
http://www.geocities.co.jp/Bookend-Soseki/3185/Jokes/index.html
に応用したのですが、うまくありません。なぜか一部のcellの色が固定されて
しまいます。(上のページから年代順リスト>各年のページを見てください)
(1)IE では、cellの中にlinkがあると、マウスがそれにさわったときに何
かステータスの変化があってその後はrows.cell[i]の変更ができなくなってし
まいます。参照はできます。下に添付したサンプル画面下の[tab0 row0]など
と書かれたセルをクリックして表示させると、それぞれのrow
内のセルの色が見えるので。でも、色が固定したあとではクリアしようとして
もエラーになるようです。
(2)今回Operaでも試したところ、Operaでは、cellのbgColorをクリアしよ
うとしてnullを代入すると、値が#000000になってしまい、真っ黒になってし
まうことがわかりました。
値をnullにするのはいけないことなんでしょうか。
(3)NSではいまのところ上の二つの問題はおきておらず、正常に表示できま
す。でも、javascript:でエラーを表示させると、マウスがリンクの上を通っ
たときに"row.cells has no properties"というエラーが出るので、問題は起
きています。画面に現れないだけで。
で、どうも、問題が二つあって、
A:マウスがリンクに触るとrow.cellのアクセスに問題が出る現象
B:row.cell[i].bgColor = null を実行すると #000000が代入されてしまう
現象(Operaのみ)
があるようです。後者は何やらバグっぽいですが、これらは回避可能でしょう
か。どのように回避できるでしょうか。
Takashi YOSHIMIさんの<bc4pfc$1s5g$1...@nwall2.odn.ne.jp>から
> i=0;
> while(row.cells[i]){
> row.cells[i].bgColor = null;
> i++;
><td width=50%><a href="#">Ant</a></td><td >Bat</td>
></tr>
><tr onMouseOver="flipbg(event)" onMouseOut="flipbg(event)" >
><td width=50%>Cat</td><td><a href="#">Dog</a></td>
In message news:biveai$2k8p$1...@nwall2.odn.ne.jp
"Takashi YOSHIMI" <tak-y...@rio.odn.ne.jp> wrote ...
> 以前の記事で、row の色を変更するプログラムを書くと、何かの拍子でその下
> のcellの色が代入され、固定になってしまうことを書きました。それを防ぐた
> めにcellの色をすべて初期化するという小手先の業でしのいだのです。
>
> 夏休みになって時間がとれたために、これをいよいよウェブページ
> http://www.geocities.co.jp/Bookend-Soseki/3185/Jokes/index.html
> に応用したのですが、うまくありません。なぜか一部のcellの色が固定されて
> しまいます。(上のページから年代順リスト???各年のページを見てください)
イベントの一つ上(親)が必ずしもTRでないことから、row が tr 以外
のとき、おかしくなっていると思われますので、イベントターゲット
から遡って、TR を見つけるのが良さそうです。
function flipbg(_event)
{
if(!_event){
_event = window.event;
}
if(_event.srcElement){
row = _event.srcElement;
while(row.nodeName != "TR") {
if(!(row = row.parentElement))
return;
}
}else{
row = _event.target;
while(row.nodeName != "TR") {
if(!(row = row.parentNode))
return;
}
}
if(_event.type == "mouseover"){
row.bgColor = "#ffff80";
}else{
if(row.rowIndex % 2){
row.bgColor = '#d0d0ff';
}else{
row.bgColor = '#c0ffc0';
}
}
}
上記で、mouseover か mouseout かの判定ですが、mouse で wheel
を利用したところ、onmouseout が発生し、次に mouse を動かした
ところ、NN7 では onmouseout と onmouseover が発生して、色が
ダブってしまうため、_event.type で判定するようにしてみました。
# Opera は 7.0 正式版以降は、インストールはできるものの
# なぜか私のマシンでは動作しない(起動時にエラーが発生する)
# ようになってしまったため、確認してないです。
## 7 の beta までは問題なかったのですが・・・
ありがとうございました。
T. Sugitaさんの<27f2aa3c03e499eb...@local.news00.iij4u.or.jp>から
>イベントの一つ上(親)が必ずしもTRでないことから、row が tr 以外
>のとき、おかしくなっていると思われますので、イベントターゲット
>から遡って、TR を見つけるのが良さそうです。
これでうまくいきました。イベントハンドラは TR タグの中に書いてあって
も、その中に TD があれば イベントのノードはTD アンカーがあればアンカー
の(要はイベントを起こした最下層の)ノードが帰るということで、TRに対し
て何かの処理をしようと思ったら、イベントで呼ばれた関数内でさかのぼる必
要があるわけですね。
自分でセルのparentNodeを書いておきながら考えがいたりませんでした。
まあ、上位のノードにイベントハンドラを置いても、イベントが起きた場所を
あとで正確に知りたくなったときに詳細な情報を参照できるようになっている
んでしょうね。こっちのほうが便利なんだろうなあ。でも、イベントの発生し
た最下位のノードとイベントハンドラが実際においてあるノードの両方を持っ
ていてもばちはあたらないと思うんだけどなあ。
これだけではなんですので、今回気づいたのですが、IE6においては、
_event.srcElement.nodeName == "A"
_event.srcElement.parentNode.nodeName == "TD"
のときに
_event.srcElement.parentNode.nodeName.bgColor = "#00bbff"
といった処理を行うと、
_event.srcElement.parentNode.nodeName.bgColor == "#00bbff"
になるのはわかるのですが、
_event.srcElement.parentNode.nodeName.outerTextも最初は
<td><a href="#">foo</a></td>
だったものが
<td bgcolor="#00bbff"><a href="#">foo</a></td>
と変わるようです。
Takashi YOSHIMIさんの<bje8ee$hdq$1...@nwall2.odn.ne.jp>から
>T. Sugitaさんの<27f2aa3c03e499eb...@local.news00.iij4u.or.jp>から
>>イベントの一つ上(親)が必ずしもTRでないことから、row が tr 以外
>>のとき、おかしくなっていると思われますので、イベントターゲット
>>から遡って、TR を見つけるのが良さそうです。
>
>これでうまくいきました。イベントハンドラは TR タグの中に書いてあって
>も、その中に TD があれば イベントのノードはTD アンカーがあればアンカー
>の(要はイベントを起こした最下層の)ノードが帰るということで、TRに対し
>て何かの処理をしようと思ったら、イベントで呼ばれた関数内でさかのぼる必
>要があるわけですね。
あとで気づいたのですが、一般的にはこれでは不十分ですね。
というのは、テーブルの中にテーブルがある場合があるわけです。
<table>
<tr onMouseOver="flipbg();"> // 上位の TR:色を変えたい部分
<td>
<table>
<tr> // 下位の TR
<td>
Ant // イベントのノード
</td>
</tr>
</table>
</td>
</tr>
</table>
のような表だと、下位の TR でループが停止しています。
<table>
<tr id="target" onMouseOver="flipbg("target");"> // 対象
<td>
<table>
<tr> // 下位の TR
<td>
Ant // イベントのノード
</td>
</tr>
</table>
</td>
</tr>
</table>
のように id をつけて、関数内でさかのぼるときに id をチェックしながら
さかのぼれば、完璧です。
つまり、
function flipbg()
{
...
while(row.nodeName != "TR") {
if(!(row = row.parentElement))
return;
}
...
}
を
function flipbg(id0)
{
...
while(row.id != id0) {
if(!(row = row.parentElement))
return;
}
...
}
とする具合。
ただ、すごくスマートでないのは、
<tr id="target" onMouseOver="flipbg('target');">
の中でタグ内に同じ文字列を書かなければならないこと。イベントがこのタグ
自身の情報を渡してくれないことに起因しているわけですが、なんとかならな
いものでしょうかねえ。
In message news:bjerlq$27lo$1...@nwall1.odn.ne.jp
"Takashi YOSHIMI" <tak-y...@rio.odn.ne.jp> wrote ...
> ただ、すごくスマートでないのは、
> <tr id="target" onMouseOver="flipbg('target');">
> の中でタグ内に同じ文字列を書かなければならないこと。イベントがこのタグ
> 自身の情報を渡してくれないことに起因しているわけですが、なんとかならな
> いものでしょうかねえ。
少々発想を変えて、this を渡してしまうのも手かもしれません。
function flipbg(_event, row)
{
if(!_event){
_event = window.event;
}
if (_event.type == "mouseover") {
row.bgColor = "#ffff80";
} else {
if (row.rowIndex % 2) {
row.bgColor = '#d0d0ff';
} else {
row.bgColor = '#c0ffc0';
}
}
if (_event.srcElement) {
_event.cancelBubble = true;
_event.returnValue = false;
} else {
_event.stopPropagation();
_event.preventDefault();
}
return false;
}
<tr onMouseOver="flipbg(event,this)" onMouseOut="flipbg(event,this)">
イベントハンドラが複数の階層で指定された場合を考慮して
(無駄を省くために)イベントバブルをキャンセルしていますが、
必要ないのであれば、その部分を省くと、スッキリして良いかも。
function flipbg(row, sw)
{
if (sw) {
row.bgColor = "#ffff80";
} else {
if (row.rowIndex % 2) {
row.bgColor = '#d0d0ff';
} else {
row.bgColor = '#c0ffc0';
}
}
}
<tr onMouseOver="flipbg(this,1)" onMouseOut="flipbg(this,0)">