访问javascript中的内联函数中的变量修改

时间:2009-12-23 03:37:47

标签: javascript jquery variables scope parameters

我正在尝试将局部变量传递给javascript中的内联函数,并让(内联)函数操作这些变量,然后能够访问包含函数中已更改的变量值。这甚至可能吗?以下是我正在使用的代码示例:

function addArtists(artist, request, origElm, xml){

//variables
var artistIdArray = [];

/*coding*/

//traverse xml
$('element', xml).each(function(){

/*coding*/ 

$.ajax({  
   /*parameters*/
   success: function(html) {
    var artistAbb = html;

    /*coding*/

    //add this element's id to the array of ids to make it draggable later
    artistIdArray.push(artistAbb);
    alert(artistIdArray[artistIdArray.length - 1]);

 }//end on success    

});//end ajax call

});//end each(function()

 alert(artistIdArray.length);

}

问题是我一直得到artistIdArray.length = 0,即使元素是多个元素在被添加到数组后被“警告”。

就像我说的,我不知道是否有可能没有全局变量或对象。有任何想法吗?我完全错了吗?

编辑:整个功能

function addArtists(artist, request, origElm, xml){  

//variables  
var artistIdArray = [];

//create ordered list
//set new <ol>s class
var olClass = "artists"; //holds the class of new <ol>

//create id for new <ol>
var olId = "artists"; //holds the id of new <ol>

//create actual <ol> element
var ol = $('<ol></ol>').attr('id',olId)
                      .addClass(olClass)
                      .appendTo(origElm);

//create the <li> elements from the returned xml
//create class for new <li>s, (just the request minus the 's')
var liClass = request.substring(0, request.length-1);
//traverse xml
$('element', xml).each(function(){

    //create id for new <li> based on artist abbreviation
    var artist = $(this).text();        

    $.ajax({
    url: "php/artistToAbb.php", 
        data: {artist: artist}, 
        dataType: "html", 
        async: true,
        success: function(html) {
    var artistAbb = html;

        //create li           
    var li = $('<li></li>').attr('id', artistAbb)
                           .addClass(liClass)
                           .appendTo(ol);   

    //create arrow icon/button for li
    var img = $('<img />').attr('id', artistAbb + 'ArrowImg')
                          .attr("src","images/16-arrow-right.png")
                          .attr('onclick', "expand(this, '" + artistAbb + "', 'years', 'danwoods')")
                          .addClass("expImg")
                          .appendTo(li);    

    var artistTxt = $('<h2>' + artist + '</h2>')
                       .addClass("artist_txt")
                       .attr('onMouseOver', 'catMouseOver(this)')
                       .attr('onMouseOut', 'catMouseOut(this)')
                       .appendTo(li);

    //tag the ol element's class
    $($(origElm)[0]).addClass('expanded');

    //add this element's id to the array of ids to make it draggable later
    artistIdArray.push(artistAbb);
    alert(artistIdArray[artistIdArray.length - 1]);

  }//end on success     

});//end ajax call

});//end each(function()

//make newly added artist elements draggable
for(var n = 0; n < artistIdArray.length; n++){
  //new Draggable(artistIdArray[n], {superghosting: true, detached: true, onEnd: catClearHighlight});
  alert(artistIdArray[n]);
}
alert(artistIdArray.length);  
}

3 个答案:

答案 0 :(得分:4)

更新:现在您已发布了整个代码。答案是你根本不应该将元素存储在临时数组中,而是在AJAX调用返回时为每个元素创建draggable。

问题是虽然可以在AJAX回调中访问数组,但是在AJAX调用完成之前,函数末尾的代码(在每个代码之外)执行,因此数组为空。如果在调用返回时创建每个draggable,则不需要中间存储变量,并且在插入DOM时创建draggable。另一种方法是让你的AJAX调用同步{aSync: false},但这也可能会占用浏览器,直到所有元素都返回。更好的IMO,可以使用AJAX调用的异步特性,并在创建时处理每个元素。

function addArtists(artist, request, origElm, xml){  

    //create ordered list
    //set new <ol>s class
    var olClass = "artists"; //holds the class of new <ol>

    //create id for new <ol>
    var olId = "artists"; //holds the id of new <ol>

    //create actual <ol> element
    var ol = $('<ol></ol>').attr('id',olId)
                          .addClass(olClass)
                          .appendTo(origElm);

    //create the <li> elements from the returned xml
    //create class for new <li>s, (just the request minus the 's')
    var liClass = request.substring(0, request.length-1);
    //traverse xml
    $('element', xml).each(function(){

            //create id for new <li> based on artist abbreviation
            var artist = $(this).text();            

            $.ajax({
        url: "php/artistToAbb.php", 
                data: {artist: artist}, 
                dataType: "html", 
                async: true,
                success: function(html) {
        var artistAbb = html;

                //create li                   
        var li = $('<li></li>').attr('id', artistAbb)
                               .addClass(liClass)
                               .appendTo(ol);   

        //create arrow icon/button for li
        var img = $('<img />').attr('id', artistAbb + 'ArrowImg')
                              .attr("src","images/16-arrow-right.png")
                              .attr('onclick', "expand(this, '" + artistAbb + "', 'years', 'danwoods')")
                              .addClass("expImg")
                              .appendTo(li);    

        var artistTxt = $('<h2>' + artist + '</h2>')
                           .addClass("artist_txt")
                           .attr('onMouseOver', 'catMouseOver(this)')
                           .attr('onMouseOut', 'catMouseOut(this)')
                           .appendTo(li);

        //tag the ol element's class
        $($(origElm)[0]).addClass('expanded');

        new Draggable(artistAbb, {superghosting: true, detached: true, onEnd: catClearHighlight});

      }//end on success     

    });//end ajax call

    });//end each(function()

}

答案 1 :(得分:1)

您根本不需要传递值,只需在内联函数中直接引用它们。

function addArtists(artist, request, origElm, xml){

//variables
var artistIdArray = new Array();
var artistNum = 0;

/*coding*/

//traverse xml  
$('element', xml).each(function(){

                  /*coding*/

    //add this element's id to the array of ids to make it draggable later
    artistIdArray[artistNum] = "some value";
    //alert(artistNum);
    artistNum++;

 }//end on success     

});//end ajax call

});//end each(function()

//test how many elements
 for(var n = 0; n < artistIdArray.length; n++)
   alert(n);

}

答案 2 :(得分:1)

我无法发现问题,它可能位于除了提供(和编辑)代码之外的其他地方。

但是,由于您已经在使用jQuery,请考虑将它们指定为“全局”jQuery属性。

var artistIdArray = [];

然后

$.artistIdArray = [];

然后使用它看起来像

$.artistIdArray.push(artistAbb);

然后你可以用同样的方式访问它

alert($.artistIdArray.length);
相关问题