开发者

jQuery: Is it possible to assign a DOM element to a variable for later use?

I'm working on a project that is using jQuery, which I'm much more familiar with Mootools.

I'll start with my code first.

var customNamespace = {
    status: 'closed',
    popup: $('#popup'),

    showPopup: function() {
        // ...  
    }
}

$(document).ready(function(){
    console.log($('#popup'));
    console.log(customNamespace.popup);
    console.log($(customNamespace.popup));

    $('#popup').fadeIn('slow');
    (customNamespace.popup).fadeIn('slow');
    $(customNamespace.popup).fadeIn('slow');
});

My goal is to not have jQuery traverse the DOM everytime I want to do something with the #popup div, so I wanted to save it to a variable to use it throughout my script.

When the page loads, the console prints out the object 3 tim开发者_运维技巧es as I would expect, so I assumed that for each method, the fadeIn would just work. But it doesn't, only

$('#popup').fadeIn('slow');

Actually fades in the div.

Even if I remove my namespace hash, and just save the object to a global variable, and do a

var globalVariable = $('#popup');
.
.
.
globalVariable.fadeIn('slow');

Also does not work as I thought it would. Can jQuery do what I am trying to do?


You want to be careful that the DOM is actually loaded before you run your selector and assign it to the variable, but otherwise you can store a reference to a DOM element in a variable with no problems.

var globalVariable;

$(document).ready(function(){ 
    globalVariable = $('#popup');
    console.log($('#popup')); 
    console.log(globalVariable); 

    $('#popup').fadeIn('slow'); 
    globalVariable.fadeIn('slow'); 
});


Where are you assigning your global variables?

If it is outside the document.ready declaration, then you may well be assigning it something that has not been loaded.

Try this:

$(document).ready(function(){ 
    var customNamespace = { 
        status: 'closed', 
        popup: $('#popup'), 

        showPopup: function() { 
            // ...   
        } 
    } 
    console.log($('#popup')); 
    console.log(customNamespace.popup); 
    console.log($(customNamespace.popup)); 

    $('#popup').fadeIn('slow'); 
    (customNamespace.popup).fadeIn('slow'); 
    $(customNamespace.popup).fadeIn('slow'); 
}); 

What happens when you try to output .length? :

console.log($('#popup').length); 
console.log(customNamespace.popup.length); 
console.log($(customNamespace.popup.length)); 


Sure, that works. It's actually a good thing to do improve performance.


Everything you get back from $() will always be an object. Your problem is that when customNamespace is assigned, and the code is executed, the DOM element #popup does not yet exist, and as such, you'll end up with a zero-length object in that example.

To check whether you've found an object in jQuery, you don't check the result for null, you check its length.

To be sure that the DOM nodes exist when your code is executed, defer it to DOMReady:

$(document).ready(function() {
   ...
}); 


Use data method and avoid storing data inside the DOM. Some developers have a habit of storing data in the HTML attributes like fx.:

$('selector').attr('alt', 'data being stored');

// later the data can be retrieved using: $('selector').attr('alt');

HTML attributes is not meant to store data like that and the "alt" as a parameter name does not really make sense. The right alternative in most cases is using the data method in jQuery. It allows you to associate data with an element on the page.

$('selector').data('paramtername', 'data being stored');

// then later getting the data with $('selector').data('paramtername');

This approach allows you to store data with meaningful names and it is more flexible as you can store as much data as you want on any element on the page. For more information about data() and removeData(), see here jQuery internals One classical use of this is saving the default value of a input field because you want to clear it on focus.

        <form id="testform">
 <input type="text" class="clear" value="Always cleared" />
 <input type="text" class="clear once" value="Cleared only once" />
 <input type="text" value="Normal text" />
</form>

$(function() {
 //Go through every input field with clear class using each function
 //(NB! "clear once" is two classes clear and once)
 $('#testform input.clear').each(function(){
   //use the data function to save the data
   $(this).data( "txt", $.trim($(this).val()) );
 }).focus(function(){
   // On focus test for default saved value and if not the same clear it
   if ( $.trim($(this).val()) === $(this).data("txt") ) {
     $(this).val("");
   }
 }).blur(function(){
   // Use blur event to reset default value in field that have class clear
   // but ignore if class once is present
   if ( $.trim($(this).val()) === "" && !$(this).hasClass("once") ) {
     //Restore saved data
     $(this).val( $(this).data("txt") );
   }
 });
});

Demo here : link text


I like to structure my script similar to this. For me it keeps all my page controls together. It also allows me to maintain my scripts more easily for each page.

/*   CONTROLS GLOBAL  */
var Controls;


var Class = {
    create: function () {
        return function () {
            this.initialize.apply(this, arguments);
        }
    }
}

//Set up page control objects
PageControls = Class.create();
PageControls.prototype = {
    initialize: function () {

        //Use jquery to initialize our controls, 
        //one should probably use more appropriate names other than ctrl1, ctrl2 .. 
        //but for demo purposes  ...
        this.ctrl1 = $($("#Control1"));
        this.ctrl2 = $($("#Control2"));
        this.ctrl3 = $($("#Control3"));

    }
}

Once ready ...

$(document).ready(function () {

    /* Initialize our global page controls */
    Controls = new PageControls();

    //Now we can use our controls
    Controls.ctrl1.val("Text for control 1");
    Controls.ctrl2.val("Text for control 2");
    Controls.ctrl3.val("Text for control 3");
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜