2009-05-02 27 views
10

Estoy tratando de reorganizar mi código y hacerlo más discreto.jQuery haga clic en función vs en línea onclick

Principalmente, hay un enlace para realizar una acción. Si hace clic en el enlace, la acción se realiza a través de ajax (el código ajax no está en el código aquí) y el texto se reemplaza por otro texto, ofreciendo al usuario la posibilidad de deshacer la acción. Si el usuario hace clic en el enlace Deshacer, ajax restaura la situación anterior y el texto que ofrece al usuario realiza la acción que se muestra de nuevo.

He hecho una versión más simple de mi problema en un solo archivo html (código debajo). Hay dos párrafos. Si hace clic en el enlace del primer párrafo, que usa la llamada onclick en línea, el código funciona como se esperaba. Pero si hace clic en el enlace del segundo párrafo, que usa la función jQuery onclick, el enlace Deshacer no funciona, y no puedo entender por qué.

¿Algún ayuda? ¡Muchas gracias!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> 
    <title></title> 
    <script src="http://code.jquery.com/jquery-latest.js"></script> 
    <script> 
     $(function() {  
      $(".add2").click(function(){ 
       var placeId = $(this).parents(".place").attr("id"); 
       $("#" + placeId + " .add2").remove(); 
       $("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>"); 
       return false; 
      }) 
      $(".undoadd2").click(function(){ 
       var placeId = $(this).parents(".place").attr("id"); 
       $("#" + placeId + " .actions").find("span.added, a.add2").remove(); 
       $("#" + placeId + " .actions").append("<a class='add2' onclick='copyPlace(\"" + placeId + "\"); return false;' href='#'>Add place</a>"); 
       return false; 
      }) 
     }); 

     function addPlace(placeId){ 
      $("#" + placeId + " .add").remove(); 
      $("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" onclick=\"undoAddPlace('" + placeId + "'); return false;\">Undo</a>"); 
      return false; 
     } 

     function undoAddPlace(placeId){ 
      $("#" + placeId + " .actions").find("span.added, a.undoadd").remove(); 
      $("#" + placeId + " .actions").append("<a class='add' onclick='addPlace(\"" + placeId + "\"); return false;' href='#'>Add place</a>"); 
      return false; 
     } 
    </script> 

</head> 
<body id="home"> 
    <div class="place" id="3435910"> 
     <p class="actions"><a href="#" onclick="addPlace('3435910'); return false;" class="add">Add place</a></p> 
    </div> 

    <div class="place" id="3435912"> 
     <p class="actions"><a href="#" class="add2">Add place</a></p> 
    </div> 
</body> 
</html> 

Respuesta

15

Desde va a añadir dinámicamente nuevas elementos al DOM, que tendrá que registrar el controlador de clic de nuevo en los nuevos artículos.

Puede usar .live para esto.


actualización manera

Desde jQuery 1.7, se prefiere el método .on para hacer esto.

Desde jQuery 1.9 se ha eliminado el método .live.

+0

vivo sólo funcionará si el selector es exactamente el mismo. En este caso, creo que el selector es único para cada elemento DOM. – tvanfosson

+0

Gracias @wolfr. No sabía que esto existía. –

+0

Gran respuesta. Sabía que mi código js funcionaba, pero no podía entender qué estaba pasando ... después de leer su respuesta, me di cuenta de que me estaba vinculando a las etiquetas de anclaje procesadas a través de asp.net mvc webgrid ... otra vez, gracias por la ayuda @Wolfr –

2

Dado que va a agregar dinámicamente nuevos elementos al DOM, tendrá que registrar el manejador click nuevo en los nuevos artículos. jQuery configura el controlador cuando llama al $('...').click(...).

1

El controlador de clics no se recoge cuando se agrega el elemento al DOM. Intente utilizar jQuery para registrar el controlador de clic cambiando la línea (s) que se parecen:

$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" onclick=\"undoAddPlace('" + placeId + "'); return false;\">Undo</a>") 

Para

$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" >Undo</a>"); 
$('#' + placeId + " .actions").find("span:last").find("a").click(function() { 
    undoAddPlace(placeId); 
    return false; 
}); 

Usted puede ser capaz de hacerlo más simple, pero parece que usted podría agregue más de un tramo al párrafo, así que fui conservador. También es posible que la cadena se anexe, pero pensé que el reselecto aclaraba el punto.

2

¡Guau! ¡Gracias a todos ustedes!

He leído sobre el evento en vivo y el código de trabajo final es:

$(function() {  
      $(".add2").click(function(){ 
       var placeId = $(this).parents(".place").attr("id"); 
       $("#" + placeId + " .add2").hide(); 
       $("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>"); 
       return false; 
      }) 
      $('.undoadd2').live('click', function(){ 
       var placeId = $(this).parents(".place").attr("id"); 
       $("#" + placeId + " .actions").find("span.added, a.undoadd2").remove(); 
       $("#" + placeId + " .add2").show(); 
       return false; 
      }); 

Anteriormente he utilizado remove() para eliminar el texto que ofrece para realizar la acción. Lo cambié por hide/show para que no tenga que usar live también en la primera función.

¡Gracias nuevamente!

4

Justo lo que demuestra el uso de .end() para una solución más fluido:

$(function() {   
    $(".add2").click(function(){ 
      return $(this).parents(".place") 
       .find(".add2") 
        .hide() 
       .end() 
       .find(".actions") 
        .append("<span class=\"added\">Added!</span> <a class=\"undoadd2\" href=\"#\">Undo</a>"); 
    }); 
    $('.undoadd2').live('click', function(){ 
      return $(this).parents(".place") 
       .find(".actions") 
        .find("span.added, a.undoadd2") 
         .remove() 
        .end() 
       .end() 
       .find(".add2") 
        .show(); 
    }); 
});