JQueryのclick(fnc)で指定された関数中のthis

このQ&Aのポイント
  • JQueryのclick(fnc)で関数中のthisの扱いについてお尋ねします。下記コードでは仮に2つのクラスをモデルとコントローラとして、コントローラからモデルの関数を呼び出しています。
  • value="HTML Tag"のボタンは期待したとおりに'chicken crows.'を表示しますが、value="JQuery"のボタンはcrow()中のthis.modelがundifinedになってしまいます。
  • 後者では$.fn.controllers.chickenController.crowをinputタグにコピーしてそれを実行しているのではないかと思います。そのためかthisはHTML Inputを指します。thisを使用する以外にモデルのcrow()を実行する方法はありませんでしょうか?
回答を見る
  • ベストアンサー

JQueryのclick(fnc)で指定された関数中のthis

JQueryのclick(fnc)で関数中のthisの扱いについてお尋ねします。 下記コードでは仮に2つのクラスをモデルとコントローラとして、コントローラからモデルの関数を呼び出しています。value="HTML Tag"のボタンは期待したとおりに'chicken crows.'を表示しますが、value="JQuery"のボタンはcrow()中のthis.modelがundifinedになってしまいます。後者では$.fn.controllers.chickenController.crowをinputタグにコピーしてそれを実行しているのではないかと思います。そのためかthisはHTML Inputを指します。 thisを使用する以外にモデルのcrow()を実行する方法はありませんでしょうか?条件としてはモデルとコントローラのオブジェクトのペアは複数有りうり、コンストラクタやプロトタイプ中で一意の変数を定義できない点にご注意ください。 <script tyoe="text/javascript" src="jquery-1.3.2.min.js" ></script> <script type="text/javascript"> $(function(){ //名前空間 $.fn.models = new Object(); var models = $.fn.models; // コンストラクタ models.bird = function(type){this.type = type;} // インスタンスメソッド models.bird.prototype = {  crow: function(){ alert(this.type + ' crowed.');} } var chicken = new models.bird('chicken'); //名前空間 $.fn.controllers = new Object(); var controllers = $.fn.controllers; // コンストラクタ controllers.birdController = function(model){this.model = model;} // インスタンスメソッド controllers.birdController.prototype = {  crow: function(){   this.model.crow(); // JQuryの場合thisはHTML Inputを指します。  } } $.fn.controllers.chickenController = new controllers.birdController(chicken); $('#b').click($.fn.controllers.chickenController.crow); }); </script> <html> <body>  <input type="button" onclick="$.fn.controllers.chickenController.crow();" value="HTML Tag" />  <input type="button" id="b" value="JQuery" /> </body> </html>

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

  • ベストアンサー
  • atse
  • ベストアンサー率83% (36/43)
回答No.1

value="HTML Tag"のボタンとモデルは違えど同じ動作をしたいのならば $('#b').click($.fn.controllers.chickenController.crow); ではなくて、 $('#b').click(function(){$.fn.controllers.chickenController.crow();}); とするのでは。 以前のままだと質問者さんの認識通り、 元の関数とは別物として#bのclickにコピーされたものが代入されるかと思います。

yu090jp
質問者

お礼

ありがとうございます。ご指摘のとおり無名関数を使用したら動作しました。助かりました。 $(#b).click(fnc)で指定した場合、下記のようなことが行われていると解釈しましたが、正しいでしょうか? ○動作した場合、HTMLInput.onclick = function(){return function(){$.fn.controllers.chickenController.crow();}} ×動作しない場合、HTMLInput.onclick = function(){return $.fn.controllers.chickenController.crow; } だとすればonclick='alert(this);'はHTMLInput.onclick = function(){return alert(this);} であり、'object HTMLInputelement'を表示するのも筋が通っています。

その他の回答 (1)

  • atse
  • ベストアンサー率83% (36/43)
回答No.2

> $(#b).click(fnc)で指定した場合、下記のようなことが行われていると解釈しましたが、正しいでしょうか? > ○動作した場合、HTMLInput.onclick = function(){return function(){$.fn.controllers.chickenController.crow();}} > ×動作しない場合、HTMLInput.onclick = function(){return $.fn.controllers.chickenController.crow; } それだとonclickによってfunctionがreturnされるだけなので、 そのように書くとしたら、 HTMLInput.onclick = (function(){return function(){$.fn.controllers.chickenController.crow();};})(); HTMLInput.onclick = (function(){return $.fn.controllers.chickenController.crow;})(); みたいな感じなので、よって、 動作○ HTMLInput.onclick = function(){$.fn.controllers.chickenController.crow();}; 動作× HTMLInput.onclick = $.fn.controllers.chickenController.crow; といった記述表現の違いになります。 でも言いたいことは伝わってきたので、仰っていることで解釈は合っていると思いますよ。

yu090jp
質問者

お礼

なるほど、ありがとうございます。 onclick="var foo = 'bar';" と onclick="function(){alert('bar');}" はDom上で関数であるかどうかによって分岐されないだろうと思ってfunctionでくるんでしまいました。 例えば下記のようなことがわざわざDomのロード中に行われることはないと思ったので。 if(typeof(dosth) == 'function'){ HtmlInput.onclick = dosth; }else{ HtmlInput.onclick = function(){dosth}; } 掲題の件自体は解決したので。終了とさせて頂きます。 ありがとうございました。大変助かりました。

関連するQ&A

  • jQueryのvar jQueryの仕組みについて

    jQuery-1.6.2のソースコードを見ているのですが質問させてください。 25行目の var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); }, そして100行めの jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function( selector, context, rootjQuery ) { の意味が分かりません。 PHP等のclassになれているとJSのクラスは戸惑うことが多いのですが、この例は最たるもので、自分の中のJSでのclassは (1)スーパークラスのプロパティをcall()、apply()で継承 (2)スーパークラスのメソッドをprototypeオブジェクトで継承 (3)インスタンスのデータ型判定に必要なプロパティをconstructorで調整 だったのですが、スーパークラスがどの行のどれなのかも分かりません。 型やメソッド名からこれらがclassを意味しているのは分かるのですが、いったいどの部分がclass定義、継承を行っているのか教えていただけませんでしょうか? なぜこれらがclassになっているのかが理解できません。 分るのは、jQuery.prototype.constructor = jQueryで、それをjQuery.fnに代入((3))している事です。 329行目の、jQuery.fn.init.prototype = jQuery.fn;の右辺がnew {$class}の形であれば(2)のプロトタイプチェーンの形だと分るのですが。 (1)は、init内でメンバ変数を定義したりしているので、classなのかな、という程度しか分っておりません。 jQuery.fnがコンストラクタで、jQueryがインスタンスで、var jQueryは親クラスをinitしたもの?・・・と混乱しております。 質問内容も文章が混乱していて申し訳ないです。

  • jQueryの仕組みについて質問です

    お世話になります。現在jQueryのコードを読んでいるのですが、どうしてもわからないところがあります。 jQuery1.11.1の2774行目、jQuery.merge(...)と自分自身を呼び出していますが、これはjQuery中でどのような処理をして実現しているのでしょうか?jQuery.merge = function(){...};としているわけでもないのに呼び出せているのが理解できません。 mergeメソッド自体は、450行目、jQuery.extend内で定義されているようです。 以下簡易化したjQueryです。 var window = this; // ブラウザ以外で実行する場合のみ必要 (function(){ jQuery = window.jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); }; jQuery.fn = jQuery.prototype = { hello: function(){ console.log("hello from fn!"); // ここをjQuery.logと書けるようにしたい } }; jQuery.extend = jQuery.fn.extend = function() {}; jQuery.extend({ log: function(msg){ console.log(msg); } }); init = jQuery.fn.init = function( selector, context ) { console.log("Hello"); }; init.prototype = jQuery.fn; // ここをjQuery.logと書けるようにしたい } )(); jQuery().hello();

  • thisとvar ?

    javascript初心者です。 コンストラクタ(プロトタイプ)とクロージャを学んでいますが、 コンストラクタ(プロトタイプ)では、関数内にthisで変数宣言、クロージャはvarで宣言しています。 この違いの理由は何でしょうか?漠然とした質問ですみません。 thisとvarでの変数宣言の違いなど教えていただけないでしょうか? コンストラクタ-------------------- function Person(n){ this.name = n; } Person.prototype.city = 'Tokyo'; Person.prototype.moveTo = function(c){ document.write(this.name + ': Moving to... ' + c + '<br>'); Person.prototype.city = c; } クロージャ------------------- function Person(n, a){ var name = n; var age = a; return { getName: function() { return name; }, setAge: function(i){ if( 0<= i ){ age = i; } }, getAge: function(){ return age; } } }

  • jQueryとprototypeの共存

    prototype.jsとjQuery.js、そのプラグインであるjquery.cycle.all.pack.jsを共存させ、データベースから取り出した画像にエフェクトをかけて表示したいと思っています。 ライブラリの共存には'jQuery.noConflict();'を使うところまでは調べたのですが、その使い方がよくわかりません。現在は以下のようにプログラムを書いていますが、jqueryの効果が出ていません。使い方、描き方の間違い等ありましたらご指摘お願いいたします。 <script type="text/javascript" src="./js/prototype.js"></script> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/jquery.cycle.all.pack.js"></script> <script type="text/javascript"> <!-- jQuery.noConflict(); function loadHello(){ new Ajax.Request( './php/Search2.php', { onComplete : function( httpObj ){ $('検索結果表示領域').innerHTML = httpObj.responseText; } } );} jQuery(function() {     jQuery(".sample").cycle( { fx:'shuffle', delay: -2000 }); }); // --></script> </head> <body onLoad="loadHello()"> <ul id="sample"> <div id="検索結果表示領域"></div> </ul> </body> </html>

  • 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について教えてください。

    JQUERYについて教えてください。 readyがDOMを読み終わってから実行しろという意味は分かったのですが、 あったりなかったりするfunction()はどんな意味なのでしょうか? function(){ $(this).stop().animate({'marginBottom':'60px'},150); },function(){ $(this).stop().animate({'marginBottom':'0px'},120); こちらにあるのですがメソッドに一個必須なのでしょうか? 例 <script type="text/javascript"> $(document).ready(function(){ $('div#goto_top').hover( function(){ $(this).stop().animate({'marginBottom':'60px'},150); },function(){ $(this).stop().animate({'marginBottom':'0px'},120); </script>

  • jQueryの関数内の変数について教えてください

    jQueryで外部の関数の中にある変数の値の取得方法について教えてください。 文法等全く分かっていない、初心者で大変恐縮しております。 外部にある変数の値を取得し、その値を必要な変数に代入したいと思っております。 下記に大まかなコードを記述いたしました。 サイトを開いた時に「mLivre」を実行し、リサイズ処理をした時に もう一度「mLivre」を実行しております。 「var mLivre」内にある数値を、「jQuery(window).resize」の中の 「 jQuery.fn.mLivre」の中にある変数に代入しようと思っております。 私のやりたいことは、「mLivre」というプラグイン(下記※参考サイト)を レスポンシブにしたいと思っております。 「mLivre」は画像を本の様にめくってくれるスクリプトです。 下記のコードの流れで、ブラウザサイズに合わせて表示の大きさを 変えることができましたが、リサイズするごとに初期化され ページが1ページ目からになってしまうので、 リサイズ後も変わらないページで表示させたいと思っております。 ※参考サイト http://coliss.com/articles/build-websites/operation/javascript/jquery-plugin-mlivre.html 全くの初心者で大変恐縮しておりますが、 ご享受いただけたらと思います。 また、記述についてもご指摘いらだけたら幸いです。 宜しくお願いいたします。 -------ソースコード---------- //実行外部ファイル jQuery('#slide').mLivre({ }); //コアファイル (function(jQuery) { jQuery.fn.mLivre = function(options,num) { }; jQuery(window).resize(function(){ var mLivre={ //ここにある変数の値を取得してリサイズ内の jQuery.fn.mLivreに渡したい。 } jQuery.fn.mLivre = function(options,num) { //この中の変数に代入したい }; jQuery('#slide').mLivre({  //リサイズ後の実行部 }) ; }); })(jQuery); var mLivre={ //ここにある変数の値を取得してリサイズ内の jQuery.fn.mLivreに渡したい。 }

  • このjqueryが稀に動かない

    画像が無いときに表示されるscriptですが稀に動かない時があります10分の4位動かないです。どのようにすればよろしいでしょうか? <script type="text/javascript" src="/kadenkoujiya1242/js/jquery.js"></script> <script type="text/javascript" src="/kadenkoujiya1242/js/noimg.js"></script> $(function () { $('img').error(function(){ $(this).attr({src:'/kadenkoujiya1242/img/noimg.png',alt:'画像が見つかりません'}); }); });

  • jQueryのアニメーションについて

    jQueryのアニメーションについて聞きたいです。 チェックボックスと連動してボックスが表示されるアニメーションはわかりましたが、表示される際のアニメーションはどうすればいいかわかりません。 フロートで横並びになった一番・二番・三番の三つのボックスがあり、三番のみが表示されている場合、三番のボックスが一番左に表示されています。 そこで二番のチェックボックスにチェックをして、二番のボックスを表示ると、二番が左で三番がその右に表示されます。 その際、三番が右にずれるときにアニメーションでスライドできないでしょうか。 現在のソースです。 【CSS/Script】 <script type='text/javascript' src='http://code.jquery.com/jquery-1.7.1.js'></script> <style type='text/css'> input{margin:80px 0 0 80px;} div{ display:none; margin:25px; padding:25px; background:#eee; width:200px; height:150px; float:left; } </style> <script type='text/javascript'> $(window).load(function(){ $('#check1').click(function() { $("#box1").slideToggle(this.checked); }); $('#check2').click(function() { $("#box2").slideToggle(this.checked); }); $('#check3').click(function() { $("#box3").slideToggle(this.checked); }); }); </script> 【HTML】 <p> <label><input type="checkbox" id="check1">一番</label> <label><input type="checkbox" id="check2">二番</label> <label><input type="checkbox" id="check3">三番</label> </p> <div id="box1">一番を押してでるのです</div> <div id="box2">さては二番を押したから</div> <div id="box3">どれかと思えば三番でした</div> よろしくお願いいたします。

  • prototype+jquery+プラグイン

    prototype.jsとjqueryとプラグイン系の読み込み方が良くわかりません。 クロスブラウザ対応のMP3プレイヤーを導入したく追加したのですが 順番を並べ変えたりいろいろしましたが導入する事ができずにこまっています。 何かいい方法はないでしょうか? エラーの内容も順序によって様々です・・・・ <script type="text/javascript" src="prototype.js"></script> <script type="text/javascript" src="lightbox.js"></script> <script type="text/javascript" src="lightbox_shortcut_keys_addon.js"></script> <script type="text/javascript" src="slide3/script/jquery-1.2.2.js"></script> <script type="text/javascript" src="jquery.cycle.all.js"></script> <script type="text/javascript" src="jquery.easing.1.3.js"></script> <script type="text/javascript" src="jquery.jcarousel.pack.js"></script> <script type="text/javascript"> jQuery.noConflict(); var $j = jQuery; </script> 以下追加===================================================== <script type="text/javascript" src="jquery-1.4.2.js"></script> <script type="text/javascript" src="jquery.compat-1.3.js"></script> <script type="text/javascript" src="jquery.jplayer.min.js"></script> <script type="text/javascript"> jQuery.noConflict(); var $j = jQuery; $j(document).ready(function(){ $("#mp3").jPlayer(); }); </script>

専門家に質問してみよう