ugrás a tartalomhoz

Jquery plugin probléma

C_hris · 2009. Jún. 7. (V), 09.03
Sziasztok!

Adott a következő kód

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">  
       
<head>

    <title></title>  
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>  
    <script>  
 
(function($){
var opts;
 
  //-----------------------------------------------
$.fn.plugintest = function(options)
       {
  opts = $.extend({}, $.fn.plugintest.defaults, options);

  return this.each(function()
        {
       
        $(this).bind("click",
          function(event)
       {                
        $.fn.dosomething( $(this) );
      });

    });
           
  };
 
  //-----------------------------------------------
  $.fn.dosomething = function(obj)
       {
       $(obj).css('color', opts.color);
       };
       
  //-----------------------------------------------
  $.fn.plugintest.defaults =
      {
      color    : 'blue'
      };
 
})(jQuery);
       
    </script>  
       
    <script type="text/javascript">  
    $(document).ready(function() {  
        $('#box1').plugintest();  
        $('#box2').plugintest( { color    : 'red' } );  
        $('#box3').plugintest( { color    : 'green' } );  
    });    
    </script>  
    <style>  
      body {font-family:arial;}  
    </style>  
</head>      
<body>  
 
<div id="box1">Box1</div>
<div id="box2">Box2</div>
<div id="box3">Box2</div>


 
</body>  
</html>


Miért van az, hogy ha kattintok a szövegekre akkor mindig zöld lesz annak ellenére, hogy különböző options lett megadva a paramétereknél.
 
1

Valahogy így...

Ustak · 2009. Jún. 7. (V), 10.12
Ha újra elolvasnám a cikkemet, biztos pontosan el tudnám magyarázni, és ha előkaparnám a könyvet a polcról, akkor is, de tömören a lényeg annyi, hogy a fenti kódodban mivel a javascript a változóra magára emlékszik, és nem a a változó értékére, ezért a lefutott kód után mindig az utolsó értéket fogja lehozni a click-re. Ezt most egy paraméter átadással (Z=i) és egy tömbbel megoldottam, de tuti van ügyesebb módja, remélem lesz aki megoldja optimálisabban:-)
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"      
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">    
  3. <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">    
  4.          
  5.        <head>  
  6.   
  7.            <title></title>    
  8.                <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>    
  9.                    <script>    
  10.                       
  11.                     (function($){  
  12.                         var opts = [];  
  13.                         var i=0;  
  14.                         //-----------------------------------------------  
  15.                         $.fn.plugintest = function(options) {  
  16.                             opts.push($.extend({}, $.fn.plugintest.defaults, options));  
  17.                             return this.each(function() {       
  18.                                 var z=i;   
  19.                                 $(this).bind("click"function(event) {                  
  20.                                             $.fn.dosomething( $(this),opts[z]);  
  21.                                         });  
  22.                                 i++;  
  23.                                 });  
  24.                                                        
  25.                         };  
  26.                                                           
  27.                         //-----------------------------------------------  
  28.                          $.fn.dosomething = function(obj,opts) {  
  29.                                 $(obj).css('color',opts.color);  
  30.                         };  
  31.                         //-----------------------------------------------  
  32.                         $.fn.plugintest.defaults = {  
  33.                                 color    : 'blue'  
  34.                         };  
  35.                     })(jQuery);  
  36.                              
  37.                     </script>    
  38.                                         
  39.                     <script type="text/javascript">    
  40.                     $(document).ready(function() {    
  41.                     $('#box1').plugintest();    
  42.                     $('#box2').plugintest( { color    : 'red' } );    
  43.                     $('#box3').plugintest( { color    : 'green' } );    
  44.                     });      
  45.                     </script>    
  46.                     <style>    
  47.                     body {font-family:arial;}    
  48.                     </style>    
  49.                     </head>        
  50.                     <body>    
  51.                                                                    
  52.                         <div id="box1">Box1</div>  
  53.                         <div id="box2">Box2</div>  
  54.                         <div id="box3">Box2</div>  
  55.                     </body>    
  56.                     </html>  
Üdv:
Gábor
2

...

C_hris · 2009. Jún. 7. (V), 10.46
Köszi.
Ezzel csak az a baj hogy mindig át kell adni az opts paramétert.

Úgy próbálkoztam még hogy átadtam a data-val az options-t minden elemnek, de biztos kell lennie szebb megoldásnak.

(function($){
var opts;
  //-----------------------------------------------
$.fn.plugintest = function(options)
    {
  opts = $.extend({}, $.fn.plugintest.defaults, options);

  return this.each(function()
        {
        $(this).data('opts', opts);  
       
        $(this).bind("click",
          function(event)
       {    
        $.fn.dosomething( $(this) );
      });

    });
           
  };
 
  //-----------------------------------------------
  $.fn.dosomething = function(obj)
       {
       color=$(obj).data('opts').color;
             
       $(obj).css('color', color);
       };
       
  //-----------------------------------------------
  $.fn.plugintest.defaults =
      {
      color    : 'blue'
      };
 
})(jQuery);
3

A data

Ustak · 2009. Jún. 7. (V), 10.53
szerintem jó ötlet, pillanatnyilag nem jut olyan eszembe, ahogy így vagy úgy ne kelljen újabb változót felhasználni.
4

A szép megoldás az, hogy

tgr · 2009. Jún. 7. (V), 16.08
A szép megoldás az, hogy átadod paraméterként, de ha ezt valamiért mindenáron el akarod kerülni, akkor használj cikluson belüli lokális változókat. Javascriptben egy függvény látja annak azt a scope-ot, ahol definiálták (ezt hívják úgy, hogy closure), tehát amikor pl. az alábbi példában kiiratod az i-t, akkor valójában a globális scope "i" nevű változójának aktuális értékét iratod ki ötször egymás után (amit az első for ciklus feltolt 5-re, és a kiiratások során végig annyi is marad):
  1. var i, a = [];  
  2. for (i=0; i<5; i++) {  
  3.   a.push(function() {  
  4.     console.log(i);  
  5.   });  
  6. }  
  7.   
  8. // eredmény: 5, 5, 5, 5, 5  
  9. for (var j=0; j<5; j++) {  
  10.   a[j]();  
  11. }  
A megoldás az, hogy minden ciklusban létrehozol egy új változót, és azt adod át (nekem a példában ehhez kellett egy névtelen függvény, mert JS-ben a for ciklusnak nincs saját scope-ja; a te példádban az each() ezt megoldja). Ebben az esetben létrejön 5 névtelen függvény, mindegyiknek van egy k nevű változója, így kiiratáskor 5 különböző változót iratsz ki:
  1. var i, a = [];  
  2. for (i=0; i<5; i++) {  
  3.   (function() {  
  4.     var k=i;  
  5.     a.push(function() {  
  6.       console.log(k);  
  7.     });  
  8.   })();  
  9. }  
  10.   
  11. // eredmény: 0, 1, 2, 3, 4  
  12. for (var j=0; j<5; j++) {  
  13.   a[j]();  
  14. }  
Vagyis a te esetedben az each()-nek paraméterül adott függvény elején kell valami var localopts = opts; parancs, és utána a localopts-ra hivatkozni. De closure-rel paraméterezni egy publikus függvényt roppant ronda megoldás szvsz.