オンマウスでボタンスタイルを変化

:hover擬似クラス

アンカーの場合

アンカー(リンク)の場合は、CSSの :hover擬似クラスを使用する事によって、マウスが上を通った時のスタイルを簡単に変化させることが出来ます。

a:hover{
  color: #f00;
  background-color: #ffc;
}

このようなスタイルを適用しているため、CSSに対応しているブラウザではこのページのアンカーの上をマウスが通ると、文字色が赤くなり背景色が黄色になります。

アンカーサンプル

ボタンの場合

同じようにフォーム部品の一つである『ボタン』もオンマウスでスタイルを変化させられるようには出来ないでしょうか。

button:hover{
}

というセレクタを作る事もCSSのルールでは禁止されていませんが、現時点でおそらく対応しているブラウザは殆ど存在しないでしょう。ボタンでオンマウスのスタイル変化を実現するためには、幾つかの方法があります。

実現方法

その1― アンカーをボタンに“見せ掛ける”

偽ボタンサンプル

上のボタンは、見た感じボタンのように見えますが、実はただのアンカーです。 ただ、実際にsubmitボタンとして機能させるためにはスクリプトを用いなくてはならず、あまり実用的ではないでしょう。

a:link, a:visited{
  border: #fff 2px outset;
  background-color: #bbb;
  color: #000;
  font-size: 12px;
  padding: 2px 20px;
  text-decoration: none;
}
a:active{
  border-style: inset;
}
a:hover{
  color: #f00;
  background-color: #fcc;
}

その2― イベントハンドラを用いる

イベントハンドラを用いて、Javascriptでダイナミックにスタイルを書き換えるという方法もあります。 ただしこの方法は一つ一つのボタン全てにonmouseover属性とonmouseuot属性を記述しなければならず、非常に冗長です。 物理マークアップが嫌いであれば、この使い方を“潔しとしない”人は多いことでしょう。実際、ソースは非常に汚くなります。

<button onmouseover="this.style.backgroundColor='#ffc'"
onmouseout="this.style.backgroundColor='#bbb'">サンプルボタン</button>

その3― behaviorプロパティを使う

MSIEの独自拡張である、behiviorプロパティを使うという手もあります。 所詮は独自拡張ですが、これにかなり近い仕様がBehavioral Extensionsとして検討されているので、あながち将来性が無いわけではないでしょう。 スタイルシートの中に含めてしまうので、切り替えにも容易に対応できます。

<script type="text/javascript">
 attachEvent("onmouseover", func1);
 attachEvent("onmouseout", func2);
 function func1() { this.style.background = "#933"; }
 function func2() { this.style.background = "#339"; }
</script>

このようなスクリプトファイルを拡張子[.htc]で保存した後、

button{
  behavior:url('sample.htc')
}

というかたちでCSSの中から呼び出します。

その4― DOMを用いる

DOMを用いれば、イベントハンドラを書き込まなくとも任意の要素でイベントを起こす事が出来ます。

function func1(){
  if(document.all){
    var obj = window.event.srcElement;
    if(obj.nodeName == "BUTTON"){
      obj.style.backgroundColor = "#fcc";
      obj.style.color = "#f00";
    }
  }
}
function func2(){
  if(document.all){
    var obj = window.event.srcElement;
    if(obj.nodeName == "BUTTON"){
      obj.style.backgroundColor = "#bbb";
      obj.style.color = "#000";
    }
  }
}
if(document.all){
  document.onmouseover = func1;
  document.onmouseout = func2;
}

このようなスクリプト行を書きこむだけでOKです。 記述が非常に長いので、外部スクリプトファイルにしておくのがBestでしょう。

但し、このままではInternetExplorer(5.5以上?)でしか動きません。

改良してみる

DOMが最善

現在の所では、その4のDOMを使う方法が最も良いと言えるでしょう。 これをもとに幾つか改良してみます。

Gekko系にも対応

MozillaやNetscape6〜7、Camino、K-melonなどのGekko系ブラウザにも対応させるためには、ブラウザ判別してさらにコードを書き加える必要があります。ウィンドウを開いた時に、まず怪獣にイベントを食べさせないといけないのです。

function func1(e){
  if(document.all){
    var obj = window.event.srcElement;
    if(obj.nodeName == "BUTTON"){
      obj.style.backgroundColor = "#fcc";
      obj.style.color = "#f00";
    }
  }
  else{
    e.target.style.backgroundColor = "#fcc";
    e.target.style.color = "#f00";
  }
}
function func2(e){
  if(document.all){
    var obj = window.event.srcElement;
    if(obj.nodeName == "BUTTON"){
      obj.style.backgroundColor = "#bbb";
      obj.style.color = "#000";
    }
  }
  else{
    e.target.style.backgroundColor = "#bbb";
    e.target.style.color = "#000";
  }
}
function addEvent(){
  if(document.all) return;
  var objBtns = document.getElementsByTagName("BUTTON");
  for(var i=0,objBtns; i<objBtns.length; i++){
    objBtn = objBtns.item(i);
    objBtn.addEventListener('mouseover', func1, true);
    objBtn.addEventListener('mouseout', func2, true);
  }
}
if(document.all){
  document.onmouseover = func1;
  document.onmouseout = func2;
}
window.onload = addEvent;

input要素にも対応

フォームボタンはbutton要素ではなく、input要素の type="submit"type="button" で行なっている人も多いはず。 そこでそれらにも対応したスクリプトを組んでみましょう。 もちろん type="text" の一行プロンプトや、 type="radio" のラジオボタンなどでは動作しないようにします。

function func1(e){
  if(document.all){
    var obj = window.event.srcElement;
    if(obj.nodeName == "BUTTON"){
      obj.style.backgroundColor = "#fcc";
      obj.style.color = "#f00";
    }
    else if(obj.nodeName == "INPUT"){
      var objType = obj.getAttribute("TYPE").toLowerCase();
      if(objType == "submit" || objType == "button" || objType == "reset"){
        obj.style.backgroundColor = "#fcc";
        obj.style.color = "#f00";
      }
    }
  }
  else{
    e.target.style.backgroundColor = "#fcc";
    e.target.style.color = "#f00";
  }
}
function func2(e){
  if(document.all){
    var obj = window.event.srcElement;
    if(obj.nodeName == "BUTTON"){
      obj.style.backgroundColor = "#bbb";
      obj.style.color = "#000";
    }
    else if(obj.nodeName == "INPUT"){
      var objType = obj.getAttribute("TYPE").toLowerCase();
      if(objType == "submit" || objType == "button" || objType == "reset"){
        obj.style.backgroundColor = "#bbb";
        obj.style.color = "#000";
      }
    }
  }
  else{
    e.target.style.backgroundColor = "#bbb";
    e.target.style.color = "#000";
  }
}

function addEvent(){
  if(document.all) return;
  var objBtns = document.getElementsByTagName("BUTTON");
  for(var i=0,objBtns; i>objBtns.length; i++){
    objBtn = objBtns.item(i);
    objBtn.addEventListener('mouseover', func1, true);
    objBtn.addEventListener('mouseout', func2, true);
  }
  var objIpts = document.getElementsByTagName("INPUT");
  for(var i=0,objIpts; i>objIpts.length; i++){
    objIpt = objIpts.item(i);
    objType = objIpt.getAttribute("TYPE").toLowerCase();
    if(objType == "submit" || objType == "button" || objType == "reset"){
      objIpt.addEventListener('mouseover', func1, true);
      objIpt.addEventListener('mouseout', func2, true);
    }
  }
}
if(document.all){
  document.onmouseover = func1;
  document.onmouseout = func2;
}
window.onload = addEvent;

今回はわかりやすくするために、単純にソースコードを加えていくという形を取りましたが、属性の判別部分やスタイルの変更部分などを関数化すると、かなりの行数は削減できるでしょう。各自で試してみてください。

面倒くさくてさっぱり分からんという方へ

とりあえず一番下のソースをコピー&ペーストして "sample.js" という名前でテキストファイルに保存し、

<script type="text/javascript" src="sample.js"></script>

という行を同じフォルダのHTMLファイルの <head>〜</head>の間に記述してください。 ボタンの上をマウスが通ると、ちかちかと色が変わるはずです。