アプリ版:「スタンプのみでお礼する」機能のリリースについて

javascriptで特定のclassを表示、非表示にする方法を検討中なのですが、
a,b,cと三つのボタンが有り、abcというclassがあります。
aをクリックするとb,cが非表示になり、aが表示される
bをクリックするとa,cが非表示になり、bが表示される
cをクリックするとa,bが非表示になり、cが表示される
と言う動作をさせたいのですが、上手くいきません。
どなたかご教授ください。
お願いいたします。

<script type="text/javascript">
<!--
function change(site){
 if(!document.getElementsByTagName){return;}
 var e = new Array('a','b','c');
 var objs = document.getElementsByTagName('*');
 for(i=0;i<e.length;i++){
  if(e[i] != site){
   for(y=0;y<objs.length;y++){
    if(objs[y].className == e[i]){
     objs[y].style.display = 'none';
    }else{
     objs[y].style.display = '';
    }
   }
  }
 }
}
// -->
</script>

<table cellspacing="10">
<tr>
<th>テスト</th>
<td>
<input type="text" name="" id="" class="a" value="" />
<input type="text" name="" id="" class="b" value="" />
</td>
</tr>
<tr>
<th>test</th>
<td>
<input type="text" name="" id="" class="c" value="" />
</td>
</tr>
</table>
<a href="javascript:change('a')">a</a>
<a href="javascript:change('b')">b</a>
<a href="javascript:change('c')">c</a>

A 回答 (8件)

短時間でまとめたので、ほとんど何も考えていません。

他にもたくさんやり方がありますが、とりあえずシンプルを目指して書きました。

var cname = new Array();
cname["a"] = new Object("a" == site ? "block": "none");
cname["b"] = new Object("b" == site ? "block": "none");
cname["c"] = new Object("c" == site ? "block": "none");

//cname["a"] = new Object("a" == site ? "visible": "hidden");
//cname["b"] = new Object("b" == site ? "visible": "hidden");
//cname["c"] = new Object("c" == site ? "visible": "hidden");

var objs = document.getElementsByTagName('*');

for(var y=0;y<objs.length;y++){
if(cname[(objs[y].className)] != undefined){
objs[y].style.display = cname[(objs[y].className)] ;
// objs[y].style.visibility = cname[(objs[y].className)] ;
}

不特定多数のオブジェクトをClassNameで判断して処理するやり方は、意図する事はわからないでもないですが、現実的ではありませんね。確かにこれだと、後から変更しなくても、オブジェクトを増やしてゆくだけでいいのですが、オブジェクト型DBとかECサイトなど、リストが多いものに関しては、パフォーマンスが悪くなり、あまりお勧めできるやり方ではないですね。

change()に対象となるIDの配列(又はHTMLオブジェクト)を渡して、処理するほうが、パフォーマンス的にも、コード的にも、早くシンプルに書けます。

今回のコードのポイントは、Display=block とした場合、"" ではなく、none を指定しないとだめですね。

それと、”if(e[i] != site){” だと、表示対象のオブジェクトで、現在非表示の場合は表示処理をしないとだめですね。コード的に間違いはそこです。

後、CSS的にはBlockだとフォーマットが変更されてしまいます。それを意図したならいいですが、"visible"で表示だけを消してもいいのかな、と思います。

JavaScript1.2 レベルであれば、change()に渡す時に、("block", "none", "none")で渡して、change(a,b, c)にすればいいわけです。そうなんです、渡す時にもっと確定した情報を渡せばいいわけです(配列で渡してもいいですね)。
    • good
    • 0
この回答へのお礼

とてもわかりやすいご説明ありがとうございます。
おかげで問題が解決いたしました。
ちなみに他にもたくさんやり方とか教えていただけると
幸いです。
どうぞ宜しくお願いいたします。

お礼日時:2010/03/22 14:26

#7のていせい。

ごめん。
var change = (function ( ) {

 var classA = document.getElementsByClassName( 'a' );
 var classB = document.getElementsByClassName( 'b' );
 var classC = document.getElementsByClassName( 'c' );
 
 return (function ( setter ) {
  return function ( s, css ) {

   if( 'undefined' == typeof css )
    css = 'inline';

   Array.map( classA, setter( s == 'a' ? css: 'none' ) );
   Array.map( classB, setter( s == 'b' ? css: 'none' ) );
   Array.map( classC, setter( s == 'c' ? css: 'none' ) );
  };
 })(
  function ( css ) {
   return function ( e ) { e.style.display = css; };
  })
})();
    • good
    • 0

くらすがこていなら、こっちがすこしはやいかなぁ~?


var change = (function ( ) {

 var classA = document.getElementsByClassName( 'a' );
 var classB = document.getElementsByClassName( 'b' );
 var classC = document.getElementsByClassName( 'c' );
 
 return (function ( setter ) {
  return function ( s, css ) {

   if( 'undefined' == typeof css )
    css = 'inline';

   Array.map( classA, setter( s == 'a' ? css, 'none' ) );
   Array.map( classB, setter( s == 'b' ? css, 'none' ) );
   Array.map( classC, setter( s == 'c' ? css, 'none' ) );
  };
 })(
  function ( css ) {
   return function ( e ) { e.style.display = css; };
  });
})();
    • good
    • 0

ていせい。


var change = (function ( ) {

 var setter = function ( css ) {
  return function ( e ) { e.style.display = css; };
 };

 var none = setter( 'none' );

 return function ( s, css ) {
  var disp = setter( 'undefined' !== typeof css ? css: 'inline' );
  var func;

  func = s == 'a' ? disp: none;
  Array.map( document.getElementsByClassName( 'a' ), func );

  func = s == 'b' ? disp: none;
  Array.map( document.getElementsByClassName( 'b' ), func );

  func = s == 'c' ? disp: none;
  Array.map( document.getElementsByClassName( 'c' ), func );
 };
})();
    • good
    • 0

なしのつぶてだが、こういうのはどう?うごかないぶらうざもあるけど。




var change = (function ( ) {

 var setter = function ( css ) {
  return function ( e ) { e.style.display = css; };
 };

 var none = setter( 'none' );

 return function ( s, css ) {
  var disp = setter( 'undefined' !== typeof css ? css: 'inline' );

  Array.map( document.getElementsByClassName( 'a' ), s == 'a' ? disp: none );
  Array.map( document.getElementsByClassName( 'b' ), s == 'b' ? disp: none );
  Array.map( document.getElementsByClassName( 'c' ), s == 'c' ? disp: none );
 };
})();
    • good
    • 0

element.style.display = '';


は、おかしい(そうだ)。


document.getElementsByClassName
をつかうとか

element.style.className = "a b d";
みたいにふくすうできるのだから、それもかんがえようよ。
    • good
    • 0

クラス名が設定されていない要素は表示のままでいいのですよね?



パフォーマンスなどについては他の方のご意見に賛成。しっかりした回答もあるみたいなので、少々いい加減なものを…

>ちなみに他にもたくさんやり方とか教えていただけると~
ということなので、ご質問文にほぼ近い方法で。

function change(site){
if(!document.getElementsByTagName) return;
var i=0, e, objs = document.getElementsByTagName('*');
while (e = objs[i++]) e.style.display = (!e.className || site==e.className)?'':'none';
}

実用的に考えると、クラスの設定がこのためだけにされているとは思いにくいし、仮にそうだとしても、2つのクラスを同時に表示しておきたいとかいろいろありそうな気もする。
    • good
    • 0

こんなのはだめ?


onloadのあとに。
ぜんかくくうはくは、はんかくにしてね。

var change = (function ( contains, display ) {

 var tags = document.getElementsByTagName( '*' );
 var classA = [ ];
 var classB = [ ];
 var classC = [ ];
 var cnt = 0, element;
 
 while( element = tags[ cnt++ ] ) {
  contains( element, 'a' ) && classA.push( element );
  contains( element, 'b' ) && classB.push( element );
  contains( element, 'c' ) && classC.push( element );
 }
 
 return function ( sw, tp ) {
  var c = 0;
  var o;
  if( 'undefined' === typeof tp )
   tp = 'inline';
  
  display( classA, 'a' === sw ? tp: 'none' );
  display( classB, 'b' === sw ? tp: 'none' );
  display( classC, 'c' === sw ? tp: 'none' );
 };
})(
  (function ( cut, has ) {
   return function ( e, name ) {
    if( !has( e.className, name ) ) {
     var keys = cut( name );
     var cnt = 0, key;
     
     while( key = keys[ cnt++ ] )
      if( !has( e.className, key ) )
       return false;
    }
    return true;
   };
  })(
    function (s) { return ('' + s).split( /\u0020+/ ); },
    function (s, n) { return -1 < ( '\u0020' + s +'\u0020' ).indexOf( '\u0020' + n + '\u0020' ); }
   ),

  function ( ary, css ) {
   for( var cnt = 0, e; e = ary[ cnt++ ]; e.style.display = css );
  }
 )
    • good
    • 0

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