[RESOLU] on.("click") ne fonctionne qu'une fois

Eléphanteau du PHP | 33 Messages

10 mai 2017, 11:08

Bonjour

Voila j'ai un petit soucis avec mon JS. Je souhaite déclencher une fonction au clic sur des div qui comportent une certaine class CSS.

L’événement fonctionne très bien lors du premier clic puis après plus rien impossible de re-déclencher le JS. Je pensais d'abord que le clic était mal ciblé mais après plusieurs modification dans tous les sens je me suis aperçu que non. J'ai placé un console.log qui ne ressort même pas lors du second clic :(.

Je met mon code la en espérant avoir un peu d'aide sur le coup.

HTML
<div class="row">
	<section id="alpha_wrapper" class="col-sm-10 fullpage">
		<h1>Titre</h1>
		<div id="body-wrapper">                
			<div class="row card-list">
				<div id="1" class="col-sm-3 card-wrapper">
					<div id="1" class="card">
						<div class="card-background">
							<img src="">
						</div>
						<div class="card-title">
							Elmt 1
						</div>

					</div>
				</div>
				<div id="2" class="col-sm-3 card-wrapper">
					<div id="2" class="card">
						<div class="card-background">
							<img src="">
						</div>
						<div class="card-title">
							Elmt 2
						</div>

					</div>
				</div>
				<div id="3" class="col-sm-3 card-wrapper">
					<div id="3" class="card">
						<div class="card-background">
							<img src="">
						</div>
						<div class="card-title">
							Elmt 3
						</div>

					</div>
				</div>
				<div id="4" class="col-sm-3 card-wrapper">
					<div id="4" class="card">
						<div class="card-background">
							<img src="">
						</div>
						<div class="card-title">
							Elmt 4
						</div>

					</div>
				</div>
			</div>
		</div>
	</section>
	<section id="beta_wrapper">
	</section>
</div>

Et le JS
<script>
$(function(){
    //Variable global
    oAlphaWrapper = $("#alpha_wrapper");
    oBetaWrapper = $("#beta_wrapper");
    oBodyWrapper = $("#body-wrapper");

    $(".card").on("click", function (){
        console.log(oAlphaWrapper.hasClass("fullpage"));
        if( oAlphaWrapper.hasClass("fullpage") == true ){
            moveAllBody( $(this) );
            oAlphaWrapper.removeClass("fullpage");
        }
        else{
            console.log('Enfin !');
            addBodyDashboard( $(this) );
        }
    });
});

var moveAllBody = function( oCard ){

    var oSelector = $(".card-wrapper");

    oBodyWrapper.fadeOut().filter( oSelector.removeClass("col-sm-3") ).filter( oSelector.addClass("col-sm-6") );
    oContentRefactor = oBodyWrapper.html();
    //
    oAlphaWrapper.removeClass("col-sm-10").addClass("col-sm-8");
    //
    oBetaWrapper.html("<div class='light-title'><h6>Petit titre</h6></div>" + oContentRefactor).addClass("col-sm-2").fadeIn();
    oBodyWrapper.empty();
    addBodyDashboard(oCard);
    oBodyWrapper.fadeIn();


};

var addBodyDashboard = function( oCard ){
    console.log('add');
    oBodyWrapper.append("<div>L\'id de la case est " + oCard.attr("id") +"</div>").fadeIn();
};
</script>

Merci

Eléphant du PHP | 130 Messages

10 mai 2017, 11:59

Bonjour,

cela vient du fait que tu reinitialise oBodyWrapper, regarde de ce côter :

Code : Tout sélectionner

oBodyWrapper.empty();

Eléphanteau du PHP | 33 Messages

10 mai 2017, 13:17

J'ai modifié ca par oBodyWrapper.html('') ou encore $("#body-wrapper").empty() et même $("#body-wrapper").html('') mais toujours le même problème.

Si je le supprime ca fonctionne sur les div qui reste dans ma section alpha mais pas dans les div qui ont été copié dans la section beta ce que je cherche a faire ....

Eléphant du PHP | 130 Messages

10 mai 2017, 14:04

Le problème c'est que ton empty vide ta div ou est situé ta classe "card" du coup l’événement javascript n'est plus appelé. Il faut rééxécuter le javascript..

<div id="body-wrapper">                
      <div class="row card-list">
        <div id="1" class="col-sm-3 card-wrapper">
          <div id="1" class="card">
            <div class="card-background">
              <img src="">
            </div>
            <div class="card-title">
              Elmt 1
            </div>

          </div>
        </div>

Eléphanteau du PHP | 33 Messages

10 mai 2017, 15:01

Mon Dieu merci !

Je pensai que le problème venait du JS qui ne trouvait pas mes div ...
Mais pourquoi je dois le reload alors que les div que je déplace possèdent elles aussi la classe "card" ?

Y'as t'il un autre moyen de faire sans avoir a reload le fichier JS ?

Un grand merci quand même !

Eléphant du PHP | 130 Messages

10 mai 2017, 18:01

Quand tu appels ton js il va attribuer à tout tes élément présent dans la page contenant la classe card l’événement onclick que tu lui as spécifié.
Si tu ajoutes un autre élément avec la classe card (après l'appel de ton js) il ne sera pas pris en compte.

Ce que tu fais c'est de supprimer ta div contenant ton élément avec la classe card et tu le reconstruit du coup ton js n'est pas appliqué dessus.

Ce que tu peux faire c'est externaliser ta fonction javascript et l'appeler à la fin de moveAllBody.
Tu peux faire quelque chose de ce genre (bien sur à retravailler).

$(function(){

    //Variable global
    oAlphaWrapper = $("#alpha_wrapper");
    oBetaWrapper = $("#beta_wrapper");
    oBodyWrapper = $("#body-wrapper");

    $(".card").on("click", function (){
		toto(oAlphaWrapper, $(this));
	});
});


var toto = function toto(oAlphaWrapper, elem){
	console.log(oAlphaWrapper.hasClass("fullpage"));
	if( oAlphaWrapper.hasClass("fullpage") == true ){
		moveAllBody( elem );
		oAlphaWrapper.removeClass("fullpage");
	}
	else{
		console.log('Enfin !');
		addBodyDashboard( elem );
	}
}

var moveAllBody = function( oCard ){

    var oSelector = $(".card-wrapper");

    oBodyWrapper.fadeOut().filter( oSelector.removeClass("col-sm-3") ).filter( oSelector.addClass("col-sm-6") );
    oContentRefactor = oBodyWrapper.html();
    //
    oAlphaWrapper.removeClass("col-sm-10").addClass("col-sm-8");
    //
    oBetaWrapper.html("<div class='light-title'><h6>Petit titre</h6></div>" + oContentRefactor).addClass("col-sm-2").fadeIn();
    oBodyWrapper.empty();
    addBodyDashboard(oCard);
    oBodyWrapper.fadeIn();
	
	$(".card").on("click", function (){
		toto(oAlphaWrapper, $(this));
	});
};

var addBodyDashboard = function( oCard ){
    console.log('add');
    oBodyWrapper.append("<div>L\'id de la case est " + oCard.attr("id") +"</div>").fadeIn();
};

Eléphanteau du PHP | 33 Messages

11 mai 2017, 14:16

J'avais déjà testé cette méthode mais le même bug. Seul le reset du JS fonctionne pour le moment. Je vais continuer a chercher parce que ca me turlupine cette affaire.

Eléphant du PHP | 130 Messages

11 mai 2017, 14:54

Je ne comprend pas ce que tu veux faire exactement si c'est juste afficher la valeur de l'id sur lequel tu as cliqué tu fais juste une div dans laquelle tu affiches le résultat :
<div class="row">
  <section id="alpha_wrapper" class="col-sm-10 fullpage">
    <h1>Titre</h1>
	<div id="resultat"></div>
    <div id="body-wrapper">                
      <div class="row card-list">
        <div id="1" class="col-sm-3 card-wrapper">
          <div id="1" class="card">
            <div class="card-background">
              <img src="">
            </div>
            <div class="card-title">
              Elmt 1
            </div>

          </div>
        </div>
        <div id="2" class="col-sm-3 card-wrapper">
          <div id="2" class="card">
            <div class="card-background">
              <img src="">
            </div>
            <div class="card-title">
              Elmt 2
            </div>

          </div>
        </div>
        <div id="3" class="col-sm-3 card-wrapper">
          <div id="3" class="card">
            <div class="card-background">
              <img src="">
            </div>
            <div class="card-title">
              Elmt 3
            </div>

          </div>
        </div>
        <div id="4" class="col-sm-3 card-wrapper">
          <div id="4" class="card">
            <div class="card-background">
              <img src="">
            </div>
            <div class="card-title">
              Elmt 4
            </div>

          </div>
        </div>
      </div>
    </div>
  </section>
  <section id="beta_wrapper">
  </section>
</div>
$(function(){
    $(".card").on("click", function (){
		$('#resultat').fadeOut();
		$('#resultat').html("<div>L\'id de la case est " + $(this).attr('id') +"</div><div class='light-title'><h6>Petit titre</h6></div>");
		$('#resultat').fadeIn();
  });
});

ynx
Mammouth du PHP | 586 Messages

11 mai 2017, 15:05

Salut,

Une autre solution possible pour que tes événements soit déclenchés même sur les éléments html qui ont été ajoutés en javascript est d'utiliser les 'delegated event'.
Dans ton cas par exemple :
$("#body-wrapper").on("click", ".card", function() {
    // ...
});
Plus d'explications ici : https://learn.jquery.com/events/event-delegation/

Bonne journée,

Eléphanteau du PHP | 33 Messages

11 mai 2017, 15:14

Merci Ynx j'allais justement la poster je viens de la trouver mdr j'ai fais ca
<script>
$(document).on("click", ".card", function (){
 .....
}
</script>
Plus safe encore ^^ Merci a vous !

Eléphanteau du PHP | 33 Messages

11 mai 2017, 15:15

Salut,

Une autre solution possible pour que tes événements soit déclenchés même sur les éléments html qui ont été ajoutés en javascript est d'utiliser les 'delegated event'.
Dans ton cas par exemple :
$("#body-wrapper").on("click", ".card", function() {
    // ...
});
Plus d'explications ici : https://learn.jquery.com/events/event-delegation/

Bonne journée,
Merci pour le lien également c'est une partie que j'avais oublié sur le JS :D