Fonction de clic jQuery vs inline onclick
Question
J'essaie de réorganiser mon code et de le rendre plus discret.
Il existe principalement un lien pour effectuer une action. Si vous cliquez sur le lien, l'action est effectuée via ajax (le code ajax n'est pas sur le code ici) et le texte est remplacé par un autre texte, offrant à l'utilisateur la possibilité d'annuler l'action. Si l'utilisateur clique sur le lien Annuler, ajax rétablit la situation précédente et le texte proposant à l'utilisateur d'effectuer l'action à nouveau affichée.
J'ai créé une version simplifiée de mon problème dans un seul fichier HTML (code ci-dessous). Il y a deux paragraphes. Si vous cliquez sur le lien du premier paragraphe, qui utilise l'appel en ligne onclick, le code fonctionne comme prévu. Mais si vous cliquez sur le lien du deuxième paragraphe, qui utilise la fonction jQuery onclick, le lien Annuler ne fonctionne pas et je ne comprends pas pourquoi.
Une aide? Merci beaucoup!
<!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>
La solution
Puisque vous ajoutez dynamiquement de nouveaux articles au DOM, vous devrez enregistrer le gestionnaire de clics à nouveau sur les nouveaux articles.
Vous pouvez utiliser .live
pour cela.
Mettre à jour
Depuis jQuery 1.7, la méthode .on
est privilégiée. faire ceci.
Depuis jQuery 1.9, le .live
Cette méthode a été supprimée.
Autres conseils
Il suffit de démontrer l'utilisation de .end () pour une solution plus fluide:
$(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();
});
});
Etant donné que vous ajoutez de manière dynamique de nouveaux éléments au DOM, vous devrez enregistrer à nouveau le gestionnaire cliquez sur
sur les nouveaux éléments. jQuery définit le gestionnaire lorsque vous appelez $ ('...'). cliquez sur (...)
.
Wow !! Merci à vous tous!
J'ai lu des informations sur l'événement en direct et le code de travail final est le suivant:
$(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;
});
Auparavant, j'utilisais remove () pour supprimer le texte proposant de réaliser l'action. Je l'ai changé pour masquer / afficher afin que je n'ai pas à utiliser live également dans la première fonction.
Merci encore!
Le gestionnaire de clics n'est pas sélectionné lorsque vous ajoutez l'élément au DOM. Essayez d’utiliser jQuery pour enregistrer le gestionnaire de clics en modifiant les lignes ressemblant à ceci:
$("#" + placeId + " .actions").append("<span class=\"added\">Added!</span> <a class=\"undoadd\" href=\"#\" onclick=\"undoAddPlace('" + placeId + "'); return false;\">Undo</a>")
Pour
$("#" + 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;
});
Vous pourrez peut-être le faire plus simplement, mais il semblerait que vous puissiez ajouter plusieurs parties au paragraphe, alors je suis devenu conservateur. Vous pourriez aussi probablement enchaîner en append, mais je pensais que la nouvelle sélection rendait le point plus clair.