重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

イベントハンドラをjs内に内包したロールオーバーを作成していて、
解決できない問題が発生しています。
リンクボタンをクリックして次のページに遷移したあと、
ブラウザの戻るボタンで戻るとonmouseover時の状態で戻ってしまいます。
原因はonunloadが動作がしていないためと思います。
onunloadをonclickにするとこの問題は回避はできますが、
クリックしたら必ず別ページに遷移しなければいけなくなります。
このスクリプトは必ずしもaタグでなくてもロールオーバーできるようにしたいのでうまい解決策ではありません。
何かよい解決方法はありますでしょうか。
// javascript start
window.onload = function() {
if(!document.getElementsByTagName) return false;
var AddClass = document.getElementsByTagName("*");
for(var i=0;i<AddClass.length;i++){
if(AddClass[i].className.match("^(.+? )?addclass.+?( .+?)?$")){

if (document.all){ // IE
AddClass[i].onmouseover = AddClassOn;
AddClass[i].onmouseout = AddClassOff;
AddClass[i].onunload = AddClassOn;
}else{
AddClass[i].addEventListener("mouseover", AddClassOn, false);
AddClass[i].addEventListener("mouseout", AddClassOff, false);
AddClass[i].addEventListener("unload", AddClassOff, false);
}
}
}

function AddClassOn() {
id_name = this.className.replace(/^(.+? )?addclass_(.+?)_.+?( .+?)?$/i,"$2");
class_name = this.className.replace(/^(.+? )?addclass_.+?_(.+?)( .+?)?$/i,"$2")
var classNameOG = document.getElementById(id_name).className;
var id_Node = document.getElementById(id_name);
var createAttr = document.createAttribute("class");
createAttr.nodeValue = classNameOG + " " + class_name;
id_Node.setAttributeNode(createAttr);
}
function AddClassOff() {
id_name = this.className.replace(/^(.+? )?addclass_(.+?)_.+?( .+?)?$/i,"$2");
class_name = this.className.replace(/^(.+? )?addclass_.+?_(.+?)( .+?)?$/i,"$2")
var classNameOG = document.getElementById(id_name).className.replace(class_name,"");
var id_Node = document.getElementById(id_name);
var createAttr = document.createAttribute("class");
createAttr.nodeValue = classNameOG;
id_Node.setAttributeNode(createAttr);
}
}
// javascript end

/* style start */
.changeclass{
padding:4px;
background:#ff0;
border:1px solid #f00;
}
/* style end */

/* html start */
<body id="knowhow" class="body_test">
<ol>
<li><a href="test.html"><img src="image/list01.gif" class="addclass_knowhow_changeclass" width="64" height="64" alt="ボタン" /></a></li>
</ol>
</body>
/* html end */
ちなみに現状のスクリプトはidだけにclass追加するように作っていますが、
最終形は追加するclassのid指定部分をbodyやparentやthisにすることで、
id以外にもclassが追加できる仕様にする予定です。
よろしくお願いいたします。

A 回答 (2件)

説明を理解できているかは不明。


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<title>サンプル</title>
<style type="text/css">
.p1 { padding:4px; background:#ff0; border:1px solid #f00; }
.p2 { padding:4px; background:#00f; border:1px solid #f00; }
</style>

<body>
<body>
<ol>
  <li>
    <a href="test.html">
      <img src="image/list01.gif" class="aa addclass_p1_abc_def_ghi cc" width="64" height="64" alt="ボタン" id="abc">
    </a>
  </li>
  <li>
    <a href="test.html">
      <img src="image/list01.gif" class="bb addclass_p2_jkl_mno_pqr dd" width="64" height="64" alt="ボタン" id="jkl">
    </a>
  </li>
</ol>
<p><span id="def">def</span>と<span id="ghi">ghi</span></p>
<p><span id="mno">mno</span>と<span id="pqr">pqr</span></p>
<p>
class指定は、addclass_の文字列で始まり、設定するcss、以降'_'で区切ったものをIDとする<br>
thisは自分自身にidを振り指定。bodyは?<br>
あと去り際に元に戻す。<br>
こんなのでいいのかは不明。</p>

<script type="text/javascript">
//全角空白は適当に変換のこと
//@cc_on
/*@if(1)attachEvent('on'+ @else@*/addEventListener(/*@end@*/'load', function() {
  var m_ary = [];
  var m_css = [];
  var reg0 = /\b(addclass_.+?)\b/;
  
  document./*@if(1)attachEvent('on'+ @else@*/addEventListener(/*@end@*/'mouseover', function(evt) {
    var e = evt./*@if(@_jscript) srcElement @else@*/ target /*@end@*/;
    var cnt = 0;
    var o;
    if (m_ary[cnt = 2]) while (o = document.getElementById(m_ary[cnt])) o.className = m_css[cnt++];

    if (e.className && (a = e.className.match(reg0))) {
      m_ary = a[1].split('_');
      cnt = 2;
      while (o = document.getElementById(m_ary[cnt])) {
        m_css[cnt++] = o.className;
        o.className += ' ' + m_ary[1];
      }
    }
  }, false);

  document./*@if(1)attachEvent('on'+ @else@*/addEventListener(/*@end@*/'click', function(evt) {
    if (m_ary[cnt = 2]) while (o = document.getElementById(m_ary[cnt])) o.className = m_css[cnt++];
  }, false);
  
}, false);

</script>

この回答への補足

早速、試してみました。
動作はこのようなことを望んでいます。
ありがとうございます。

これのid部分をclassにしたいです。
formなどシステムがらみとのバッティングを回避したいので、
設計段階で追加したid(例えばnaviやheader、footerなど)以外は、
極力idは追加したくないからです。
元からあるidに対して、
ごく一般的なcssコーダーがclassの追加のみで制御することができる
汎用スクリプトを考えています。

補足日時:2009/04/26 09:41
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
説明不足ですみません。

クラス名「addclass_knowhow_changeclass」の
文頭がaddclassのクラスにマッチさせて、
クラス名を追加するノードのidがknowhowの部分で、
追加するクラス名がchangeclass部分になります。
予約語のような感じで、
addclass_body_changeclass
addclass_parent_changeclass
addclass_this_changeclass
の3つだけはidではなく、
それぞれ該当のタグにクラスが追加されます。

明日いただいた内容も試させていただきたいと思います。
よろしくお願いします。

お礼日時:2009/04/26 01:10

1対1で対応させるのであれば、面倒なことをする必要がないのでは?



getElementsByTagNameで集めたものに、いちいちイベントをくっつけて
、しかも3個もくっつけて・・・
大もと1つ付ければ、OK!
mouseoverするということは、それまで居たノードから
mouseoutしたことになるのだから、それを覚えておいて利用すればOK!

と、学んだ。

この回答への補足

前項の補足で失礼しました。
こちらのスクリプトで問題ありませんでした。。
bodyやthisやparentの場合だけ、
条件分岐すれば希望の状態になりそうです。
ご回答ありがとうございました。

補足日時:2009/04/26 09:58
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
たびたびの説明不足ですみません。

書き込んだソースは簡略化しすぎました。。
実際には汎用スクリプトとして使いたいので、
1対2だったり、2対1だったり、2対3だったりします。
1対2の場合、2つとも囲われているidやbodyに、classを追加し、
2対1の場合、2か所に同じclassを追加するといった感じになります。

お礼日時:2009/04/26 09:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!