2014-04-28 71 views
2

我有一个简单的前端在jQuery/HTML5(+后端生成的代码,不会带来问题,所以我会省略它)。目前正在使用的jQuery版本是1.8.3,并且不存在版本冲突(即没有加载其他jQuery版本 - 它在其他系统中多次出现)。jQuery:事件没有被触发的Ajax加载元素

前端调用以下程序:

detailAjaxCall("\/client\/orders\/detailsLoad\/id\/3"); 

$(".upLink").click(function(){ 
    console.log("subiendo"); 
    var id = $(this).closest("tr").data('detail-id'); 
    var url = "\/client\/orders\/detailMoveUp" + "/id/" + id; 
    detailAjaxCall(url); 
    return false; 
}); 

$(".downLink").click(function(){ 
    console.log("bajando"); 
    var id = $(this).closest("tr").data('detail-id'); 
    var url = "\/client\/orders\/detailMoveDown" + "/id/" + id; 
    detailAjaxCall(url); 
    return false; 
}); 

$(".delLink").click(function(){ 
    console.log("borrando"); 
    var id = $(this).closest("tr").data('detail-id'); 
    var url = "\/client\/orders\/detailDelete" + "/id/" + id; 
    detailAjaxCall(url); 
    return false; 
}); 

注意:URL字符串不是畸形。它们是由json导出器生成的(这段代码是从Google Chrome浏览器中的view source选项中提取的)。评估它们中的任何一个都将返回一个没有反斜杠的字符串。

detailAjaxCall("/client/orders/detailsLoad/id/<number>")实际工作:它返回预期的JSON代码,当我打的网址,并呈现此时,相应的表项:对的“<a></a>”一代

function detailAjaxCall(url) 
{ 
    $.get(
     url, 
     {}, 
     function(data, status, xhr) { 
      //todo refrescar(data); 
      var table = $("#detail-list"); 
      table.empty(); 
      if (data.length == 0) { 
       $("<tr></tr>").addClass("empty").append($("<td></td>").addClass("empty").text("No hay detalles para este pedido")).appendTo(table); 
      } else { 
       $.each(data, function(index, element) { 
        $("<tr></tr>") 
         .data('detail-id', element['id']) 
         .append(
          $("<td></td>") 
           .append(
            $("<span></span>").addClass("product-name").text(element['producto_nombre']) 
           ) 
           .append("<br />") 
           .append(
            $("<span></span>").addClass("product-dims").text(
             "Ancho: " + element['ancho'] + 
             ", Largo: " + element['largo'] + 
             ", Calibre: " + element['calibre'] 
            ) 
           ) 
         ) 
         .append($("<td></td>").addClass("quantity").text(element['cantidad'])) 
         .append($("<td></td>").addClass("price").text(element['precio'])) 
         .append(
          $("<td></td>") 
           .append(
            $("<a></a>").addClass("upLink").text("subir").attr("href", "javascript: void 0") 
           ).append(" ") 
           .append(
            $("<a></a>").addClass("downLink").text("bajar").attr("href", "javascript: void 0") 
           ).append(" ") 
           .append(
            $("<a></a>").addClass("delLink").text("eliminar").attr("href", "javascript: void 0") 
           ).append(" ") 
         ) 
         .appendTo(table); 
       }); 
      } 
     }, 
     'json' 
    ).fail(function(){ 
     $("#ajaxDetailErrorDialog").dialog("open"); 
    }); 
} 

讲究,因为我的问题是他们。他们都有类似delLink,upLinkdownLink

我的问题从这里开始:调用$(".delLink").click(callback)$(".upLink").click(callback)$(".downLink").click(callback)似乎不绑定事件到新创建的项目(它们在Ajax调用内部创建althought)。查看click方法的源代码,传递参数,就像致电on

所以:我做错了什么动态绑定事件,所以新创建的元素也会触发我的事件?

+1

通过只读标题,我认为你应该委托事件... https://learn.jquery.com/events/event-delegation/ –

+1

它的原因是,当你将类应用到那些元素,他们不存在页面,所以你必须在绑定事件添加到dom后再次将绑定事件应用到新添加的项目。 – Xerxes

+3

@xerxes或更好的,委托事件以避免多个标识处理程序 –

回答

6

您需要动态委派点击处理程序,因为您在创建新元素之前分配了点击处理程序。

例如,委托给document

$(document).on('click', '.upLink', function(){ 
    console.log("subiendo"); 
    var id = $(this).closest("tr").data('detail-id'); 
    var url = "\/client\/orders\/detailMoveUp" + "/id/" + id; 
    detailAjaxCall(url); 
    return false; 
}); 

这工作,因为在document所有点击都会由该处理程序进行检查,以查看它们是否匹配.upLink。即使您在分配后创建新元素,点击仍会通过此事件。

+0

是的,再次阅读jquery源代码和文档,并注意到.on调用是不同的(即非动态调用)。在10分钟内接受... –

+2

+1,但最好使用'$(“#detail-list”)。on(“click”,“.uplink”...' - 您附加事件越近处理程序更好 – Archer

+2

@LuisMasuelli,请参阅此答案以获取有关使用'.on'的不同方式的更多详细信息:http://stackoverflow.com/questions/1525664/jquery-how-to-bind-onclick-event-to -dynamically-added-html-element/17086311#17086311 – MrCode

相关问题