質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

3671閲覧

複数タグのイベントハンドラ

dady

総合スコア18

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1グッド

2クリップ

投稿2016/05/05 16:07

###前提・実現したいこと
WEBデザインを勉強中のものです。
複数のinputタグにonmouseoverでスタイルを変える方法がわかりません。inputタグのonmouseover属性に関数を書くのではなくwindow.onloadで実行したいんですが・・・
下記のソースコードのイメージでできませんか?

###該当のソースコード

javascript

1 window.onload = function(){ 2 var txtbx; 3 var num; 4 var i; 5 txtbx = document.getElementsByTagName("input"); 6 num = txtbx.length; 7 for(i = 0;i < num;i++){ 8 txtbx[i].onmouseover = function(){ 9 //ここに書くべき処理がわかりません 10 //下のソースではもちろん動きませんがイメージとしてはこのような感じです 11 //txtbx[i].style.border= "1px solid #000"; 12 }; 13 } 14 }
kei344👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

onmouseover に書いてしまうと2つ以上の関数を登録できず上書きしてしまうので、addEventListener を使ったほうが良いような。
【動くサンプル】https://jsfiddle.net/dp5kc1t2/

CSS

1.mouseover { border: 1px solid #000; };

JavaScript

1var txtbx = document.getElementsByTagName( 'input' ) 2 , i, l = txtbx.length 3 ; 4for( i = 0; i < l; i++ ){ 5 txtbx[ i ].addEventListener( 'mouseenter', function( e ) { 6 e.currentTarget.classList.add( 'mouseover' ); 7 }, false ); 8 txtbx[ i ].addEventListener( 'mouseleave', function( e ) { 9 e.currentTarget.classList.remove( 'mouseover' ); 10 }, false ); 11}

classList がIE10+、addEventListener currentTarget がIE9+ なのでそろそろ使えるかなという感じです。(当然別の書き方もあります)

【JavaScriptでよく使うDOM操作とか - Qiita】
http://qiita.com/okkunokkun18/items/10a0a40cba0022dff617#onclick-と-addeventlistenerclick-の違い

【element.classList - Web API インターフェイス | MDN】
https://developer.mozilla.org/ja/docs/Web/API/Element/classList

【EventTarget.addEventListener - Web API インターフェイス | MDN】
https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener

【Event.currentTarget - Web API インターフェイス | MDN】
https://developer.mozilla.org/ja/docs/Web/API/Event/currentTarget


ちなみに i をイベントに渡したいときは下記のようにするとできます。
【動くサンプル】https://jsfiddle.net/dp5kc1t2/1/

JavaScript

1var txtbx = document.getElementsByTagName( 'input' ) 2 , i, l = txtbx.length 3 ; 4for( i = 0; i < l; i++ ){ 5 txtbx[ i ].addEventListener( 'mouseenter', ( function( int ) { 6 return function( e ) { 7 e.currentTarget.classList.add( 'mouseover' ); 8 e.currentTarget.id = 'id' + int; 9 }; 10 } )( i ), false ); 11 txtbx[ i ].addEventListener( 'mouseleave', function( e ) { 12 e.currentTarget.classList.remove( 'mouseover' ); 13 }, false ); 14}

【JavaScriptで即時関数を使う理由 - Qiita】
http://qiita.com/katsukii/items/cfe9fd968ba0db603b1e

【即時関数のメリットと主な用途|もっこりJavaScript|ANALOGIC(アナロジック)】
http://analogic.jp/immediate-function/


いっそこうも書ける。
【動くサンプル】https://jsfiddle.net/dp5kc1t2/3/

JavaScript

1[].forEach.call( document.getElementsByTagName( 'input' ), function( ele, i, arr ) { 2 ele.addEventListener( 'mouseenter', function( e ) { 3 e.currentTarget.classList.add( 'mouseover' ); 4 e.currentTarget.id = 'id' + i; 5 }, false ); 6 ele.addEventListener( 'mouseleave', function( e ) { 7 e.currentTarget.classList.remove( 'mouseover' ); 8 }, false ); 9}); // IE9+

【Array.prototype.forEach() - JavaScript | MDN】
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

【配列ライクなオブジェクトをforEachするときのイディオム - ぷちてく - Petittech】
http://ptech.g.hatena.ne.jp/noromanba/20120521/1337639496

投稿2016/05/05 18:18

編集2016/05/05 19:27
kei344

総合スコア69407

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/05/05 18:53

最後の例は txtbx[ i ].addEventListener( 'mouseenter', function(int, e ) { e.currentTarget.classList.add( 'mouseover' ); e.currentTarget.id = 'id' + int; }.bind(this,i), false ); って書き方もできそうですね。thisはwindowオブジェクトになっちゃいますが。
kei344

2016/05/05 19:15 編集

ああ、その発想は無かったです。ずっと即時関数でこなしてきたので。さっと見てみましたが .bind() 面白いですね。 > thisはwindowオブジェクトになっちゃいますが。 thisは渡してしまえば良いのでは? txtbx[ i ].addEventListener( 'mouseenter', function( int, e ) { e.currentTarget.classList.add( 'mouseover' ); e.currentTarget.id = 'id' + int; }.bind( txtbx[ i ], i ), false ); https://jsfiddle.net/dp5kc1t2/2/
kei344

2016/05/05 19:29

> 最後の例は すいません、ちょっと追記してしまったので「2番目の例」となりました。
退会済みユーザー

退会済みユーザー

2016/05/05 22:51

>thisは渡してしまえば良いのでは? はい。その通りですね。 解ってはいたのですが,そう書くとbind使うまでもなくtxtdx[i]がthisでアクセスできてしまうのでindex i を持ち込む意味合いが微妙になるかなと思って,そういう表現になってしまいましたw txtdxを渡して,bindしたiをつかってtxtdx[i]でアクセスするのが良いかなと思いつつも恐らく質問者様がbindを初めて見る書き方だと思ったので,一番基本的な使い方で,一応こう書くとwindow objectが参照できるようになりますという注釈のつもりでした。 kei344様のご参考にもなったのであれば何よりです。
think49

2016/05/05 23:02 編集

i を束縛するなら handleEvent を使うとクロージャを使わずに済みます。 ele.addEventListener('mouseenter', {handleEvent: handleMouseenter, i: i}, false); this は呼び出し方によって変動するので個人的には信用してません…。 ちなみに、this === window になるのは sloppy mode で Strict Mode なら this === undefined ですね。
退会済みユーザー

退会済みユーザー

2016/05/05 23:30

think49様 ele.addEventListener('mouseenter', {handleEvent: handleMouseenter, i: i}, false); これすごいですね。, i: iなくても動いたのですが,入れると,スコープが{handleEvent: handleMouseenter, i: i}だけに変わるってことですか?
think49

2016/05/05 23:43 編集

To: tkow さん 下記コードと等価と認識して問題ないかと。 (特に prototype 上のメソッドを渡すときに便利です。) ele.addEventListener('mouseenter', handleMouseenter.bind({handleEvent: handleMouseenter, i: i}), false);
退会済みユーザー

退会済みユーザー

2016/05/06 00:10

think49様 なるほど!勉強になりました! ありがとうございます!
guest

0

複数のinputタグにonmouseoverでスタイルを変える方法

http://start-now.link/100/archives/2277
の用な感じで、cssのclass指定でclass名:hoverのスタイルを設定してあげる。

投稿2016/05/05 16:46

TetsujiMiwa

総合スコア1124

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dady

2016/05/05 17:05

なるほど、こちらの方がはるかに簡単ですね。 ありがとうございます。
guest

0

ベストアンサー

その書き方でほとんど合っていますが,イベントを引き起こしたDOMにアクセスする場合は,thisを使います。
以下のコードで治らなければどこか指定が間違っているだけだと思うので,こちらも参考にしてみてください。

javascript

1var txtbx = document.getElementsByTagName("input"); 2var length = txtbx.length; 3 for(var i = 0; i<length;i++){ 4 txtbx[i].onmouseover = function(event){ 5 this.style.border= "1px solid #000"; 6 } 7}

投稿2016/05/05 17:02

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dady

2016/05/05 17:14

ありがとうございます。thisですね。なんか視野が狭くなっていたようです。 txtbxもiも関数の外にあるので、参照できないのでthisを使うという認識で間違いないですか?
退会済みユーザー

退会済みユーザー

2016/05/05 17:36 編集

いえ実は,txtbxもonmouseoverもiも同じwindow.onloadの関数スコープの中にあるのでアクセスはできます。 ただし,dady様のコードは,onmouseoverイベントが発生するタイミングよりも先に,forループが終了し,iはlength+1の値になったまま,保持され,onmouseoverイベント発生時に,txtbx[length+1]にアクセスしようとしてエラーになってしまいます。 なので,実は, txtbx[i].onmouseover = function(event){ for(var j =0;j<length;j++){ txtbx[j].style.border= "1px solid #000"; } } と書いても動きます。この時,jではなくiを使ってしまうと今回の場合はバグが出ませんが,広域のiの値を上書きしてしまう書き方になっているのでやめたほうがいいと思います。 またこの場合は,一つのマウスオーバーイベントで全ての同じタイプのDOMオブジェクトに影響を与えてしまいます。 thisはイベントハンドラ内で使用すると,indexを指定しなくともイベントを引き起こしたDOMオブジェクトを参照することができるのでそちらを採用しました。イベントを起こしたDOMがindexの何番目かを保持する方法はかなりトリッキーな実装になるのでやらないほうがいいでしょう。
think49

2016/05/05 22:54

この方法ではinput要素ノードの数だけ関数オブジェクトが生成されるので onmouseover イベントハンドラ関数を関数宣言して参照を保持しておくといいかもしれません。
退会済みユーザー

退会済みユーザー

2016/05/05 23:31

パフォーマンス重視なら関数オブジェクトへの参照をキャッシュすべきですね。
think49

2016/05/06 04:58

関数生成コスト問題は、どちらかといえば、パフォーマンスよりもメモリ使用量が重要だと思います。 極端な話、100個のinput要素が存在すれば100倍のメモリを消費することになります。 (付随してイベント定義時の処理時間も延びますが、イベント発火時の処理速度には影響しません。) 親要素でmouseoverイベントを定義してevent.targetで処理分けすれば、イベント定義が一つで済むので更にメモリ消費量を削減することが出来ます。ついでに動的に生成されるinput要素ノードにも対応出来ます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問