在JQuery动态点击处理程序中使用Ajax回调变量值

问题描述:

我正在做一个简单的ajax查询,它将值的可变长度列表作为JSON数据进行检索。我试图根据这些数据制作一个列表,这些数据具有基于我从JSON查询获得的值的点击功能。我可以使这项工作就好了通过写的onClick的方法到HTML这样的:在JQuery动态点击处理程序中使用Ajax回调变量值

function loadFooList() { 
    var list_area = $("#sidebar"); 
    list_area.html("<ul>") 
    $.ajax({ 
    type: 'GET', 
     url:'/data/foo/list', 
    dataType: 'json', 
    success: function (json) { 
     $.each(json, function(i, item) { 
     var link_id = "choosesfoo" + item.id; 
     list_area.html(list_area.html() 
        + "<li> <a href='#' onClick='alert(\"" + 
        link_id + "\");'>" + 
        item.name + "</a></li>"); 
     }); 
     list_area.html(list_area.html() + "</ul>"); 
    } 
    }); 
} 

我不喜欢写的onClick功能到HTML,我也想了解如何创建此同通过JQuery点击功能实现功能。

所以问题显然是可变范围。我天真的尝试在这里显然是行不通的,因为变量不再存在时点击情况:

function loadFooList2() { 
    var list_area = $("#sidebar"); 
    var link_ids = Array(); 
    list_area.html("<ul>") 
    $.ajax({ 
    type: 'GET', 
     url:'/data/foo/list', 
    dataType: 'json', 
    success: function (json) { 
     $.each(json, function(i, item) { 
     var link_id = "choosefoo" + item.id; 
     list_area.html(list_area.html() 
        + "<li> <a href='#' id='" + link_id + "'>"+item.name+"</a></li>"); 
     link_ids.push(link_id); 
     }); 
     list_area.html(list_area.html() + "</ul>"); 
     for (link_index=0; link_index<link_ids.length; link_index++) { 
     $("#" + link_ids[link_index]).click(function() { 
      alert(link_ids[i]); 
     }); 
     } 
    } 
    }); 
} 

很显然,我想做些别的事情不仅仅是提醒值,但警告呼叫有只要我能做到这一点,并继续前进。

我明白,我将不得不做一些处理函数,我通过一个状态变量。这适用于单个值(我可以存储整个link_ids数组就可以了,但是我不知道它们中的哪一个是这个链接的正确值),但是我如何对任意长度的列表执行此操作?

下面是一个例子from JQuery docs其中我试图复制:

// get some data 
var foobar = ...; 

// specify handler, it needs data as a paramter 
function handler(data) { 
    //... 
} 

// add click handler and pass foobar! 
$('a').click(function(){ 
    handler(foobar); 
}); 

// if you need the context of the original handler, use apply: 
$('a').click(function(){ 
    handler.apply(this, [foobar]); 
}); 

而且我在这里quess最后一个例子,“如果你需要原来的处理程序的情况下......”可能是什么我想但我不知道如何到达那里。我尝试将当前的link_id值存储到这个,从这个在应用函数中使用它(使用apply()),但我没有成功。根据FireFox,必要的值仍未定义。我正在使用JQuery 1.3.2。

那么对于这个相对基本的问题,什么是正确的解决方案?

使用append代替html()

function loadFooList() { 
    var ul = $('<ul>'); 
    $.ajax({ 
     type: 'GET', 
     url:'/data/foo/list', 
     dataType: 'json', 
     success: function (json) { 
      $.each(json, function(i, item) { 
       var link_id = "choosesfoo" + item.id; 
       var a = $('<a>').attr('href','#').bind('click', function(e) { 
        alert(link_id,item_name); 
        e.preventDefault(); 
       }); 
       $('<li>').append(a).appendTo(ul); 
      }); 
      ul.appendTo('#sidebar'); // this is where the DOM injection happens 
     } 
    }); 
} 
+0

您正在修改DOM很多。每当DOM被修改时,浏览器必须重新绘制,如果json返回的是一个长列表,这将会减慢很多。 – PetersenDidIt 2009-12-05 18:12:36

+0

@petersendidit:足够公平,只要持续注射ul,直到请求完成,如果你担心表现。 – David 2009-12-05 18:25:10

所以,问题似乎越来越让你的点击处理程序可以访问它与链接相关链接ID。请注意,如果它是字母数字,它将符合id属性的条件,您可以从中提取它。如果它是纯粹的数字,它将是一个非法的id属性。在这种情况下,您可以使用像rel这样的属性或jQuery.data()方法来将链接标识与链接一起存储。你也可以通过使用append来简化。我会显示两个例子。

var link = $("<li><a href='#' id='" + link_id + "'>" + item.name + "</a></li>"; 
link.click(function() { 
     alert($(this).attr('id')); 
    }); 
list_area.append(link); 

或(如数字)

var link = $("<li><a href='#'>" + item.name + "</a></li>"; 
link.data('identifier', link_id) 
    .click(function() { 
     alert($(this).data('identifier')); 
    }); 
list_area.append(link); 

试试这个:

function loadFooList() { 
    var list_area = $("#sidebar"); 
    $.ajax({ 
     type: 'GET', 
     url:'/data/foo/list', 
     dataType: 'json', 
     success: function (json) { 
      var out = '<ul>'; 
      $.each(json, function(i, item) { 
       var link_id = "choosefoo" + item.id; 
       out +="<li><a href='#' id='" + link_id + "'>"+item.name+"</a></li>"; 
      }); 
      out +="</ul>" 
      var $out = $(out); 
      $out.find('a').click(function(){ 
       var link_id = this.id; 
       var item_name = $(this).text(); 
       alert(link_id); 
       alert(link_name); 
      }) 
      list_area.html($out); 
     } 
    }); 
} 

使用多个追加导致浏览器连续重绘多次。你只想修改一次dom。