简体   繁体   中英

calling javascript namespace function from within jquery

I want to populate a jquery ui modal dialog with values from an array in this module:

var WsdArrays = function() {
     var arr = [["the boy is going home", "wsd_aud1"],
      ["You and I are friends", "wsd_aud2"],
      ["He has a book of mine", "wsd_aud3"],
      ["He will run to his home", "wsd_aud4"],
      ...          ];         
    return {
        values: function(index1, index2) {
        return arr[index1][index2];
        }
    };
}(); 

this works OK when called like this:

console.log(WsdArrays.values(0, 0));

but it does not work when the module function is called within a jquery statement with arguments generated by the jquery click event thus:

jQuery("span.ws_dialog_icon").on("click",function(evnt) {
  jQuery("div#ws_dialog").dialog("open");
  evnt.stopPropagation();
  var elementId = evnt.target.id,
      index1 = elementId.substr(7), //strips chars from ids like "wsd_img01"
      index2 = 0,
      arrayVals = WsdArrays.values(index1, index2);
  jQuery("div#wsd_text").text(arrayVals);
});

What needs to be changed here?

Use window to make it more global.

So set it like so:

window.WsdArrays = function() {
     var arr = [["the boy is going home", "wsd_aud1"],
      ["You and I are friends", "wsd_aud2"],
      ["He has a book of mine", "wsd_aud3"],
      ["He will run to his home", "wsd_aud4"],
      ...          ];         
    return {
        values: function(index1, index2) {
        return arr[index1][index2];
        }
    };
}(); 

This way it will sit in the global namespace, if it is made within another function this will also work. If you declare it with var inside another function it will only be available within that function.

I think scoping is here indeed the main issue. But instead of littering the window /global namespace I suggest using another namespace:

var app=function($){
    var WsdArrays = function() {
        var arr = [["the boy is going home", "wsd_aud1"],
        ["You and I are friends", "wsd_aud2"],
        ["He has a book of mine", "wsd_aud3"],
        ["He will run to his home", "wsd_aud4"],
        ...          ];         
        return {
                 values: function(index1, index2) {
                         return arr[index1][index2];
               }
        };
    }();
    $("span.ws_dialog_icon").on("click",function(evnt) { 
       $("div#ws_dialog").dialog("open");
       evnt.stopPropagation();
       var elementId = evnt.target.id,
       index1 = elementId.substr(7), //strips chars from ids like "wsd_img01"
       index2 = 0,
       arrayVals = WsdArrays.values(index1, index2);
       $("div#wsd_text").text(arrayVals);
   });
}(jQuery);

So, there is no need for using global scope, and WsdArrays is visible to the onClick .

Besides: why aren't you using a dictionary-approach?

var WsdArrays=function(){
    var whatEverString={
         "wsd_aud1","the boy is going home",
         "wsd:auds","you and i are friends"
    };
    return {
        values:function(id){ return whatEverString[id]; }
    }
}

Another thing: Why are you encapsulating a simple function in an IFFE? Only for namespacing reasons? A simple function would be sufficient.

Try parseInt:

index1 = parseInt(elementId.substr(7)),

The reason is your index1 without parseInt is a string "01" after calling elementId.substr(7) for "wsd_img01" . This will cause problem as arr["01"] returns undefined which causes exception when you call arr["01"][index2] . As you can see in the following DEMO

When we use parseInt , index1 becomes 1 which does not cause problem.

DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM