Abdallah Abdallah - 4 months ago 8
Javascript Question

passing jquery selector as a parameter

enter image description hereI Want to pass a jquery selector to a function but it didn't work , what is the problem ?

$(".university .seeMap").one("click",function(){
HideMap($(this));
});
function ShowMap(element){
$(element).html('See The Map &nbsp; <i class="zmdi zmdi-pin"></i>');
$(element).one("click",HideMap(element));
$(element).next(".university-map").fadeOutn();
}
function HideMap(element){
$(element).html('Hide The Map &nbsp; <i class="zmdi zmdi-pin"></i>');
$(element).one("click",ShowMap(element));
$(element).next(".university-map").fadeIn();
}

Answer

You're not passing a selector, you're passing a jQuery instance.

The problem is that $(element).one("click",ShowMap(element)); calls ShowMap(element) and passes its return value into one, exactly the way foo(bar()) calls bar and passes its return value into foo.

Since you're calling them immediately, your code crashes the browser because HideMap calls ShowMap which calls HideMap which calls ShowMap...forever until you get (drum roll please) a stack overflow.

If you want to "bake" an argument into a function, you can use Function#bind or jQuery's own $.proxy:

$(element).one("click",HideMap.bind(null, element));
// ---------------------------^^^^^^^^^^^^

or

$(element).one("click",$.proxy(HideMap, null, element));
// --------------------^^^^^^^^^^^^^^^^^^^^^^

In both cases, they create a new function that, when called, will call the original with the given this value (you're not using this, so I've used null above1) along with any arguments you supply to bind/proxy.


1 When you use null for the thisArg argument, the function will either be called with null (in strict mode) or with a reference to the global object (in loose mode).


Side note: You're repeatedly re-wrapping the element, running it through $() repeatedly for no reason. It's harmless, but pointless.

Instead, I suggest writing ShowMap and HideMap such taht they expect the element to already be wrapped:

$(".university .seeMap").one("click",function(){
    HideMap($(this));
});
function ShowMap(element){
    element.html('See The Map &nbsp; <i class="zmdi zmdi-pin"></i>');
    element.one("click",HideMap.bind(null, element));
    element.next(".university-map").fadeOutn();
}
function HideMap(element){
    element.html('Hide The Map &nbsp; <i class="zmdi zmdi-pin"></i>');
    element.one("click",ShowMap.bind(null, element));
    element.next(".university-map").fadeIn();
}
Comments