$(this)を変数に入れないと動作しない理由

このQ&Aのポイント
  • jQueryのセレクタ$(this)は、現在の要素に対して処理を適用するための実行時の変数です。
  • $(this)を変数に入れずに直接使用すると、要素が変わってしまい、正しく動作しなくなります。
  • そのため、`var a = $(this);`とすることで、処理を適用する要素を確実に指定する必要があります。
回答を見る
  • ベストアンサー

$(this)を変数に入れないと動作しない理由

「WebデザイナーのためのjQuery入門」という書籍でjQueryの勉強をしています。 リンク先 http://gihyo.jp/book/2012/978-4-7741-4856-4 この書籍の中のロールオーバーボタンのスクリプトで質問があります。 以下のスクリプトは書籍に載っているスクリプトですが、これにより画像ボタンにポインタがのる・のらないでボタン画像が切り替わります。 --------------- $(function(){ $('.rollover').each(function(){ var a = $(this); var img = a.find('img'); var src_off = img.attr('src'); var src_on = src_off.replace('_off','_on'); $('<img />').attr('src','src_on'); a.hover(function(){ img.attr('src',src_on); },function(){ img.attr('src',src_off); }); }); }); --------------- htmlは以下になります。※<body>内のみ抜粋 --------------- <body> <div class="header"> <ul class="menu"> <li><a href="index.html" class="rollover"><img src="menu01_off.png" alt="Home"></a></li> <li><a href="index.html" class="rollover"><img src="menu02_off.png" alt="Products"></a></li> <li><a href="index.html" class="rollover"><img src="menu03_off.png" alt="Company"></a></li> </ul> </div> </body> --------------- 質問したいのは、スクリプトの上から3行目の「var a = $(this);」です。 var a = $(this); var img = a.find('img'); 上記を、 var img = $(this).find('img'); とした場合、なぜか画像が切り替わりません。 どちらも同じような気がするのですが、不具合の原因が分かりません。 お分かりの方がいっらしゃいましたら、お手数ですがご回答よろしくお願いいたします。

  • pileny
  • お礼率89% (325/362)

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8523/19372)
回答No.1

>上記を、 >var img = $(this).find('img'); >とした場合、なぜか画像が切り替わりません。 そうしてしまうと、aの値が設定されないから、下のほうにある a.hover(function(){ が正常に動作しなくなる。

pileny
質問者

お礼

さっそくのご回答ありがとうございます。 たしかに! hoverのところを見落としていました! 試しに以下のようにすると正常に動作しました。 お手数おかけしました。 $(function(){ $('.rollover').each(function(){ var img = $(this).find('img'); var src_off = img.attr('src'); var src_on = src_off.replace('_off','_on'); $('<img />').attr('src','src_on'); img.hover(function(){ img.attr('src',src_on); },function(){ img.attr('src',src_off); }); }); });

関連するQ&A

  • ページによってロールオーバーが機能しない

    javascriptを使用して、カーソルがあたった時に色が変わる ロールオーバーを実現しているサイトを作りました。 ところが、ページによってロールオーバーが機能しません。 すべて同じソースをコピペしただけなのですがこれが原因ですか? サイトは複数ページあり、機能するものとそうでないもので 置かれている階層が異なるものもあります。 他のjavascriptも記述されているのですが、それらが影響しているのでしょうか? ちなみに下記のようなソースです。(一部抜粋) 【HTML】 <div id="a"> <a href=""> <img src="test.png" /> </a> <ul> <li> <a href="00.html"><img src="test2.png" class="rollover" /></a> </li> </ul> </div> 【javascript】 $.fn.rollover = function() { return this.each(function() { // 画像名を取得 var src = $(this).attr('src'); //すでに画像名に「_on.」が付いていた場合、ロールオーバー処理をしない if (src.match('_on.')) return; // ロールオーバー用の画像名を取得(_onを付加) var src_on = src.replace(/^(.+)(\.[a-z]+)$/, "$1_on$2"); // 画像のプリロード(先読み込み) $('').attr('src', src_on); // ロールオーバー処理 $(this).hover( function() { $(this).attr('src', src_on); }, function() { $(this).attr('src', src); } ); }); }; // 画像をロールオーバーする箇所を指定 $(function() { $('.rollover').rollover(); }); $(document).ready(function(){ $('.bxslider').bxSlider(); }); ご存知の方がいらっしゃいましたら対策を教えてください。 お願いいたします!

  • jQueryでの画像切り替え処理について

    前回の質問の続きになります。 一列に配置したボタンを、マウスオーバー時、クリック時にそれぞれ別の画像に切り替えたいと思っています。 (元画像A_offを、マウスオーバー時はA_on、クリック時はA_off_s3へと変更する。  A_off_s3の状態でマウスオーバーされた場合、A_offにはならず、A_off_s3のままとする。  A_off_s3が表示されている時に他のボタンB_offがクリックされたら、B_offはB_off_s3を、A_off_s3はA_offを表示する。) 色々なページを参考に、以下のようなスクリプトを書きました。 ---------- <head> <script type="text/javascript" src="script/jquery-1.11.0.min.js"></script> <script> $(function(){ var handler = $('ul#nav li a'); var url = document.URL; var urlId = url.substr(url.lastIndexOf('#')); var urlIdJudgment = urlId.lastIndexOf('#'); $('ul#nav').each(function(){ $('#tab-box > div:first').show(); var imgSrc = $('ul#nav li:first img').attr('src'); var imgDot = imgSrc.lastIndexOf('.'); var onSrc = imgSrc.substr(0, imgDot) + '_s3' + imgSrc.substr(imgDot, 4); $('ul#nav li:first img').attr('src',onSrc).addClass('tab-on'); }); handler.click(function() { var imgSrc = $(this).children('img').attr('src').replace(/_s3/g, ""); var imgDot = imgSrc.lastIndexOf('.'); var onSrc = imgSrc.substr(0, imgDot) + '_s3' + imgSrc.substr(imgDot, 4); $(this).children('img').attr('src',onSrc); var imgOff = $('ul#nav li img.tab-on').attr('src').replace(/_s3/g, ""); $('ul#nav li img.tab-on').attr('src',imgOff); $('ul#nav li img').removeClass('tab-on'); $(this).children('img').addClass('tab-on'); var imgSrc = $(this).children('img').attr('src').replace(/_s3/g, ""); var imgDot = imgSrc.lastIndexOf('.'); var onSrc = imgSrc.substr(0, imgDot) + '_s3' + imgSrc.substr(imgDot, 4); $(this).children('img').attr('src',onSrc); return false; }) }); $(function(){ $('a img').hover(function(){ $(this).attr('src', $(this).attr('src').replace('_off', '_on')); }, function(){ if (!$(this).hasClass('currentPage')) { $(this).attr('src', $(this).attr('src').replace('_on', '_off')); } }); }); </script> </head> <body onload="MM_preloadImages('img/A_off.jpg','img/A_on.jpg','img/A_off_s3.jpg','img/B_off.jpg','img/B_on.jpg','img/B_off_s3.jpg','img/C_off.jpg','img/C_on.jpg','img/C_off_s3.jpg')"> <div id="tab-box"> <ul id="nav" class="clearFix"> <li><a href="xxx"><img src="img/A_off.jpg" width="134" height="36" alt="" id="A" /></a></li> <li><a href="yyy"><img src="img/B_off.jpg" width="134" height="36" alt="" id="B" /></a></li> <li><a href="zzz"><img src="img/C_off.jpg" width="134" height="36" alt="" id="C" /></a></li> </ul> </div> ---------- 上記のスクリプトで実行をすると、クリック時に?マークが表示され、カーソルが離れると○_off_s3の画像が表示されます。 また、○_off_s3の画像が表示されている時に、○_off_s3にカーソルを合わせると、?マークが表示され、カーソルが離れると○_off_s3が表示されます。 また、○_off_s3の名称をわかりやすいものにしようと思い、○_off_cに変更し、スクリプトの"_s3"を”_c”に変更したところ、スクリプトが正常に実行されなかったのも気になっています。 原因がわかる方がいらっしゃれば、アドバイスをお願いいたします。

  • 画像を使用したタブを複数設置

    下記、サイトを参考にタブ切り替え式のjQueryを設置しました。 http://web.showjin.me/2011/05/jquery_tab_image.html これを同じファイル内に複数設置したく 同じscriptをjsファイルに3つコピーし 設置しましたが、エラーで動かなくなったので 各、ul.btn_tab li aのtab部分tab01、tab02、tab03とし、 .container_tabをcontainer_tab01~03、 a.selectedをa.selected01~03と それぞれ変更してみました。 上記の方法で動作は実現できたのですが、 これをもっとスマートなscriptにする方法があればご教授頂けないでしょうか。 どうぞ宜しくお願い致します。 id、classを修正し、以下を3パターン設置しています。 javascript ================ /* クリックしたときに出る点線を防ぐ(IE対策)*/ $(function(){ $("ul.btn_tab li a").focus(function(){ $(this).blur(); }); }) /* タブボタンのon/offとタブの内容を切り替える */ $(function(){ /* 初期設定 */ $("a.selected img").attr("src",$("a.selected img").attr("src").replace(/^(.+)(\.[a-z]+)$/,"$1_on$2")); $(".container_tab div:not("+$("ul.btn_tab li a.selected").attr("href")+")").hide(); /* クリック時の処理 */ $("ul.btn_tab li a").click(function(){ // 今のul.btn_tab li a.selectedのhrefの値を保持しておく var name1=$("ul.btn_tab li a.selected").attr("href"); $("a.selected img").attr("src",$("a.selected img").attr("src").replace(/^(.+)_on(\.[a-z]+)$/,"$1$2")); $("ul.btn_tab li a").removeClass("selected"); $(this).addClass("selected"); /* クリックした画像はmouseoverで_onが付けられているので、そのままだと_on_onとなり、画像へのパスが通らなくなる。 なので、今付いている_onをいったん削除してから再度_onを付け直す */ $("img",this).attr("src",$("img",this).attr("src").replace(/^(.+)_on(\.[a-z]+)$/,"$1$2")); $("img",this).attr("src",$("img",this).attr("src").replace(/^(.+)(\.[a-z]+)$/,"$1_on$2")); // 保持しておいたhrefの値のdivの内容がフェードアウトしたら、クリックされたボタンのhrefの値のdivの内容をフェードインする $(name1).fadeOut(500,function(){ // クリックされたul.btn_tab li a.selectedのhrefの値を保持 var name2=$("ul.btn_tab li a.selected").attr("href"); $(name2).fadeIn(500); }); return false; }) }) /* マウスオーバー時の処理 */ $(function(){ $("ul.btn_tab a").mouseover(function(){ /* セレクタがついているかどうかの条件判断はマウスオーバーとマウスアウトのそれぞれに対して設定する。 マウスオーバー時だけだと、クリックした後、マウスアウトするときに_onが外されて通常時の画像になってしまうため */ var className = $(this).attr('class'); if(className!='selected'){ $("img",this).attr("src",$("img",this).attr("src").replace(/^(.+)(\.[a-z]+)$/, "$1_on$2")) } }).mouseout(function(){ var className2 = $(this).attr('class'); if(className2!='selected'){ $("img",this).attr("src",$("img",this).attr("src").replace(/^(.+)_on(\.[a-z]+)$/,"$1$2")) } }) })

  • 初心者です jQueryのマウスオーバーについて

    jQueryを使った画像を使ったメニューを作成しています。 <ul class="drop2">をマウスオーバーしたときに親の位置にある画像1.gifが画像1_o.gifに 切り替わるようにしたいと思っています。 調べながら作ってみたのですが、画像の切替がうまくいきません。 parentを使わずに画像1.gifをdivで囲って指定すれば切り替わったのですが、2つ以上メニューを 作ると、他のulにマウスオーバーしたときも切り替わってしまいます。 ご教授して頂けると嬉しいです。 よろしくお願いいたします。 ■スクリプト部分 jQuery(function ($) { $('ul.drop2').mouseover(function () { // console.log('mouseover'); デバック用 var onSrc = $(this).parent('ul.drop1 a img').attr('src').replace('.gif', '_o.gif'); $(this).parent('ul.drop1 a img').attr('src', onSrc); }); $('ul.drop2').mouseout(function () { var onSrc =$(this).parent('ul.drop1 a img').attr('src').replace('_o.gif', '.gif'); $(this).parent('ul.drop1 a img').attr('src', onSrc); }); }); ■html部分 <ul class="drop1"> <li><a href="/"><img src="画像1.gif" alt="HOME" /></a> <ul class="drop2"> <li><a href="#"><img src="画像1-1.gif" alt="HOME" /></a></li> <li><a href="#"><img src="画像1-2.gif" alt="HOME" /></a></li> </ul> </li> </ul>

  • jQueryのclickイベントハンドラ

    最近jQueryを勉強中でして、練習の意味で自分で以下のようなページを作ってみました。 【ページの内容】 犬、猫、鳥の画像ボタンを配置して、クリックすると各ボタンのalt属性をアラート表示する 【実際のhtml】 <div class="header"> <ul class="menu"> <li><a href="index.html" id="btn1"><img src="dog.png" alt="Dog"></a></li> <li><a href="index.html" id="btn2"><img src="cat.png" alt="Cat"></a></li> <li><a href="index.html" id="btn3"><img src="bird.png" alt="Bird"></a></li> </ul> </div> 【実際のscript】 $(function(){ var btn1 = $('#btn1'); var photo1 = btn1.find('img'); var name1 = photo1.attr('alt'); btn1.click(function(){ alert(name1); }); var btn2 = $('#btn2'); var photo2 = btn2.find('img'); var name2 = photo2.attr('alt'); btn2.click(function(){ alert(name2); }); var btn3 = $('#btn3'); var photo3 = btn3.find('img'); var name3 = photo3.attr('alt'); btn3.click(function(){ alert(name3); }); }); 上記で一応やりたいことは再現はできるのですが、scriptが冗長なのでもっと短くしたいです。 しかしどんなスクリプトにすればよいかわかりません。 宜しければアドバイスお願いいたします。

  • リンク前後で画像を変えたい

    こんにちわ。 少し質問させていただきます。 タイトルそのままですが、 リンク前とリンク後で画像を変えたいのですが、 どうすればよろしいでしょうか? 以前にこちらでロールオーバーの質問をした時に a1_off.pngをa1_on.pngに名前で変えるやり方を教えて 頂きました。(質問自体は少し違いますが・・・) 切り替える画像の種類が多いので同様にリンク後に a1_linkbefore.pngからa1_linkafter.png a2_linkbefore.pngからa2_linkafter.png のように名前で変えたいと考えたいのですが そのような事ができるのでしょうか? できるのであれば、ご教授お願いしたいです。 ちなみにソースはこのような形です。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitio … <html xmlns="http://www.w3.org/1999/xhtml"> <html lang="ja"> <head> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript">google.load('jquery','1');</script> <script type="text/javascript"> $().ready ( function() { $('a.link').each ( function() { var imgObj = $(this).find('img'); var imgSrc = imgObj.attr('src'); $(this).mouseover ( function() { imgObj.attr ( 'src', imgSrc.replace ( /off.png/, 'on.png' ) ); }).mouseout ( function() { imgObj.attr ( 'src', imgSrc ); }) }); }); </script> <link rel="stylesheet" type="text/css" href="style.css" /> </head> <body> <p class="クラス1"> <a href="a1.html" class="クラスA-1"> <span class="クラスA-1">A1</span> <img src="a1.png" border="0"> </a></p> <p class="クラス2"> <a href="a2.html" class="クラスA-2"> <span class="クラスA-2">A2</span> <img src="a2.png" border="0"> </a></p> </body> </html> よろしくお願いします。

  • NETSCAPEで表示がうまくいかない

    折りたたみメニューのようなのを作成してます。 IEだと問題なく動くのですが、 NETSCAPEになると、マウスオーバー・オフで ロールオーバーの画像が変わらなかったり 表示が消えるはずの箇所が残ったりします。 NETSCAPEでも、ちゃんと動く用にしたいです。 どなたかご助言を頂けないでしょうか? ソースの中を抜粋しました <A href ="BOOK.html" onMouseOver="On('img10');" onMouseOut="Off('img10');"> <IMG src ="10-1.png" border="0" NAME = "img10" alt = ""> </A></DIV> <DIV class="Lmenu_Rmenu"> <A href ="CD.html" onMouseOver="On('img11');" onMouseOut="Off('img11');"> <IMG src ="11-1.png" border="0" NAME = "img11" alt = ""> </A></DIV> <DIV class="Lmenu_Rmenu"> <A href ="DVD.html" onMouseOver="On('img12');" onMouseOut="Off('img12');"> <IMG src ="12-1.png" border="0" NAME = "img12" alt = ""> </A></DIV> </DIV></div> <SCRIPT type="text/javascript" src="java.js"></SCRIPT> var img1on = new Image(); var img1off = new Image();  ・  ・ var img12on = new Image(); var img12off = new Image(); img1off.src = "1-1.png"; // 普段の画像 img1on.src = "1-2.png"; // ポイント時の画像  ・  ・ img12off.src = "12-1.png"; img12on.src = "12-2.png"; // ポイント時の処理 function On(name) { if (document.images) { document.images[name].src = eval(name + 'on.src'); } } // 放した時の処理 function Off(name) { if (document.images) { document.images[name].src = eval(name + 'off.src'); } }

  • jqueryのロールオーバーについて

    jqueryのロールオーバー設定に関してご質問です。 あるサイトのコーディングを行ってます。 サイト内のナビーゲーションボタンを瓶の画像でまとめてます。 各瓶の画像にリンクを付け、 マウスを乗せるとその瓶が開いた画像が 切り替わりでフェードインの感じで出てくるという設定を目指しているのですが、 うまくいきません。 色々やった結果マウスを当てると、 切り替わりで空いた瓶がフェードで出るのですが、 その画像奥に閉じた瓶がそのまま残ってて重なってる感じです。 こちらはどのようにすれば上手く画像奥の瓶は消えるのでしょうか? ちなみに画像はpngです。 フェードの切り替わりは是非そのまま使用したいと考えてます。 あとマウスを外せばまた閉じた瓶がフェードで出るという感じを目指してます。 どなたかご教示いただいてもよろしいでしょうか? 一応下記htmlとjsコードも載せておきます。 ▼html <script src="../lib/jquery1.8.1.min.js"></script> <script src="../js/jquery.tgImageRollover.js"></script> <script type="text/javascript"> jQuery(function(){ $(this).tgImageRollover({ selector : 'img.rollover', // セレクタ ←(7) attach : '_on', // ファイル名末尾句 ←(8) onFadeTime : 600, // カーソルON時のアニメーション時間 ←(9) offFadeTime : 400 // カーソルOFF時のアニメーション時間 ←(10) }); }); </script> <a href="#"><img class="rollover" src="../img/nav01.png" alt="" width="100" height="50"></a> <a href="#"><img class="rollover" src="../img/nav02.png" alt="" width="100" height="50"></a> ▼jquery.tgImageRollover.js ;(function($){ $.fn.tgImageRollover = function(options){ var opts = $.extend({}, $.fn.tgImageRollover.defaults, options); $(opts.selector).each( function(){ this.onImage = $(this).attr('src').replace(/^(.+)(\.[a-z]+)$/,"$1"+ opts.attach +"$2"); this.onHtml = $('<img src="'+this.onImage+'" alt="" style="position:absolute; opacity:0;">'); $(this).before(this.onHtml); $(this.onHtml).hover( function(){ $(this).stop().animate({'opacity': '1'}, opts.onFadeTime); }, function(){ $(this).stop().animate({'opacity': '0'}, opts.offFadeTime); } ) } ) } // default option $.fn.tgImageRollover.defaults = { selector : 'img.rollover', attach : '_on', onFadeTime : 600, offFadeTime : 400, }; })(jQuery);

  • jQueryの$(this)について

    閲覧ありがとうございます。 初歩的な質問で申し訳ないのですがthisのことがすこし混乱してしまい、わからなくなってしまったので下記の場合のthisはどこを読み込むか教えてもらえると助かります。 目的:aをクリックしたときimgのsrcにaのhrefに指定してあるものを埋め込む処理 $(function(){ $("a").click(function(){ $("ul li img").fadeOut(function(){ $(this).attr(src,$("a").attr("href")).fadeIn(); }); return false; });

  • JQueryを使ってcssを書き換え

    何となくコードを見てさわる程度の初心者です。 以下のようなソースを組みました。 <div id="slide"> <a href="01.htm"><img src="01.jpg" alt="01" id="alttxt" /></a> </div> <div id="slidenavi"> <ul> <li><a href="01.html"><img src="s_01.jpg" alt="01" class="b_01.jpg" /></a><span class="active"></span></li> <li><a href="02.htm"><img src="s_02.jpg" alt="02" class="b_02.jpg" /></a><span class="active"></span></li> <li><a href="03.html"><img src="s_03.jpg" alt="03" class="b_03.jpg" /></a><span class="active"></span></li> </ul> </div> #slideがメインエリアで、#slidenaviがメインエリアの画像とリンク先を切り替えるナビゲーションボタンになっています。 ナビに連動したメインエリア用の画像ファイル名は #slidenavi の img の classに入れておいて、それを読み込んで代入するというおかしなやり方で呼び出していますが、ここまではうまくいきました。 問題はここからです。 最初の状態では<span class="active"></span>はcssの設定でdisplay: noneとしてあります。 そして#slidenaviのボタンにマウスが乗ると、その部分の<span class="active"></span>をdisplay: blockとして表示したいのですが、これがどうしてもうまくいきません。 この部分も含めて、おかしな書き方になっている部分があれば教えてもらえないでしょうか。 jsファイルは以下の通りです。 $(function(){ $('#slidenavi ul li a').fadeTo(0,0.4); $('#slidenavi ul li a').hover(function(){ $(this).fadeTo(300,1.0); }, function(){ $(this).fadeTo(300,0.4); }) $('#slidenavi ul li img').mouseover(function(){ var bglink = $(this).attr("class"); var altTxt = $(this).attr("alt"); $("#slide img").attr("src","images/home/main/"+bglink); $("#slide img").attr("alt",altTxt); $("#slide span.active").css("display","block"); }); $('#slidenavi ul li a').mouseover(function(){ var Href = $(this).attr('href'); var Tget = $(this).attr('target'); $("#slide a").attr("href", Href); $("#slide a").attr("target", Tget); $("#slide a").click(function() { window.open(Href,'_self'); return false; }); }); });

専門家に質問してみよう