0

This way does not work (elements are pulled in from with in the function ).

    function styleTwitter1( pair_array )
    {
        var i;
        var input;
        var label;
        var font_size;

        for ( i = 0; i < pair_array.length; i+=2 ) 
        {
/*
*/
            input = document.getElementById( pair_array[ i ] );
            label = document.getElementById( pair_array[ i + 1 ] );
/*
*/
            label.fontSize = window.getComputedStyle( label, null ).getPropertyValue("font-size");
/*
*/
            input.addEventListener( "keypress", function()
            { 
                label.style.opacity = 0; 
            }, false );
/*
*/
            input.addEventListener( "focus", function()
            { 
                if( input.value === '' )
                {
                    label.style.opacity = 0.2; 
                    input.style.border = '1px solid #888888'; 
                }
            } , false );
/*
*/
            input.addEventListener( "blur", function()
            {
                if( input.value === '' )
                {
                    label.style.opacity = 1;
                    new EffectsFont( label ).fade( 'up', 150 );
                    input.style.border = '1px solid #dddddd'; 
                }   
            } , false );
/*
*/
        }
    }

However, this way does (elements are injected from outside the function).

    function initTwitterStyle( input, label )
    {
/*
*/
        input.addEventListener( "keypress", function()
        { 
            label.style.opacity = 0; 
        }, false );
/*
*/
        input.addEventListener( "focus", function()
        { 
            if( input.value === '' )
            {
                label.style.opacity = 0.2; 
                input.style.border = '1px solid #888888'; 
            }
        }, false );
/*
*/
        input.addEventListener( "blur", function()
        {
            if( input.value === '' )
            {
                label.style.opacity = 1;
                new EffectsFont( label ).fade( 'up', 150 );
                input.style.border = '1px solid #dddddd'; 
            }

        }, false );
/*
*/
    }

What I will end up doing if I can't figure out the difference is pull my array loop outside and just inject twitterStyle2 with elements.

Currently, I can't get an error code but only one pair is being initialized..and then EffectsFont does not work.

Jshint warns against creating function in loops but I don't understand why? What is the issue?

CS_2013
  • 1,158
  • 3
  • 13
  • 24
  • Define "doesn't work", do none of them work, or do they all act on, say, the last pair in the array? – Dave Newton May 19 '12 at 22:53
  • Could you post the HTML which you're using to call those functions? It'll be hard to guess what parameters you're passing to the functions otherwise. – Fabrício Matté May 19 '12 at 22:54
  • Need to know what `pair_array` actually is in the first example. – Andrew Leach May 19 '12 at 22:59
  • possible duplicate of [Javascript closures - variables vs parameters](http://stackoverflow.com/questions/5448731/javascript-closures-variables-vs-parameters) – Felix Kling May 19 '12 at 23:09
  • @FelixKling It's hard to consider these questions duplicates because it's really right to ask the hard question for this problem. – Ruan Mendes May 19 '12 at 23:20

2 Answers2

2

You have a closure problem. The handlers make a closure on the variable label. However, by the time the loop has finished, label will be the last element - All your handlers will treat label as the last element when they fire.

Eric
  • 95,302
  • 53
  • 242
  • 374
0

I call it freezing a closure variable, basically by using a self calling function which creates a new closure that is not shared.

var divs = [...];
for (var i=0; i < 10; i++) {
  // Here's the self calling function
  div.onclick = (function(i){
    return function() {
      console.log("Clicked div with index" + i);
    }
  })(i);// Passing the variable to the self calling function creating a new closure 
}

My preferred way, however, is to use https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

var divs = [...];
for (var i=0; i < 10; i++) {
  div.onclick = (function(i) {
      console.log("Clicked div with index" + i + "and id" + this.id );
    }
  }).bind(div, i);
}
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • I submitted and answer where I just put in a function called closureBuster..this works 'till I learn more advances things such as your answer. – CS_2013 May 20 '12 at 00:04