IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

jQuery Discussion :

Stopper l'action en cours et en exécuter une nouvelle


Sujet :

jQuery

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut Stopper l'action en cours et en exécuter une nouvelle
    Bonjour,

    J'ai un bouton et une div. Lorsque je clique sur le bouton (Timer), un compteur s'enclenche dans la div :

    https://jsfiddle.net/3dc6p4w7/1/

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <button id="Timer">Timer</button>
    <button id="Number">Number</button>
    <br><br>
    <br><br>
    <div id="myNote" value="1" >1</div>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $('#Timer').on('click',function(e) {
    	increment(1);
     $('#myNote').show(); 
    });
     
    function increment(i) {
      $('#myNote').text(i);
    	if(i < 10000) {
      	setTimeout(function() {
      		increment((i+1));
        }, 100);
    	}
    } 
     
     $('#Number').on('click',function() {
    	 $('#myNote').text("TEXTE");
    });
    J'ai un deuxième bouton (Number) qui affiche un texte dans la div lorsqu'on on y clique dessus.

    Je voudrai donc qu'en cliquant sur le deuxième bouton, après avoir cliqué sur le premier bouton, le compteur s'arrête et le texte s'affiche de façon permanente.

    En d'autre termes, comment puis-je faire pour arrêter l'action du premier bouton et lancer l'action du deuxième.

    Merci de votre aide,

    Arsène

  2. #2
    Expert confirmé
    Avatar de Doksuri
    Profil pro
    Développeur Web
    Inscrit en
    Juin 2006
    Messages
    2 452
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 452
    Points : 4 601
    Points
    4 601
    Par défaut
    passe par une variable globale pour savoir si tu dois faire tourner le script ou non
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    var running = false;
     
    $('#Timer').on('click',function(e) {
    	running = true;
        increment(1);
        $('#myNote').show();
    });
     
    function increment(i) {
        $('#myNote').text(i);
        if(i < 10000 && running) {
            setTimeout(function() {
                increment((i+1));
            }, 100);
        }
    }
     
    $('#Number').on('click',function() {
    	running = false;
        $('#myNote').text("TEXTE");
    });
    La forme des pyramides prouve que l'Homme a toujours tendance a en faire de moins en moins.

    Venez discuter sur le Chat de Développez !

  3. #3
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Bonjour,
    le plus simple reste d'utiliser la méthode clearTimeout ( iTimer), il te faut juste récupérer la variable iTimer.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var iTimer;
     
    function increment(i) {
      $('#myNote').text(i);
      if (i < 10000) {
        iTimer = setTimeout(function () {
          increment((i + 1));
        }, 1000);
      }
    }
    puis de la « killer » sur le click de l'autre bouton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $('#Number').on('click', function () {
      clearTimeout(iTimer);
      $('#myNote').text('TEXTE');
    });

  4. #4
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 661
    Points
    66 661
    Billets dans le blog
    1
    Par défaut
    oui ou encore plsu simplement avec un setInterval et un test de l'incrémzent qui déclenche un clearInterval ..
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Merci beaucoup,

    en fait dans le programme que j'ai construit, c'est plus compliqué. Au lieu d'un compteur j'ai une série de fonctions imbriquées qui remplissent un tableau en allant chercher des éléments dans une base de données locale. À un moment j'ai une boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while (i < j) {
     maFnct();
    i++;         
    };
    Pour que le script s'arrête, en suivant vos conseils, j'ai déclaré une variable globale : var running = true; et inséré ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (i < j) {         
    if (running === false) {
    alert(running);
    return false;  
    }; 
     maFnct();
    i++;         
    };
    Pour lancer l'arrêt du script, j'ai associé le code suivant à un bouton :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $("#monBtn").on("click", function () {
      running = false;
    });
    Je n'obtiens aucun message d'alert en cliquant sur le bouton et le script s'exécute jusqu'au bout.

    Pour être sûr que la fonction est toujours en train de s'exécuter, j'ai ajouté un setInterval() mais il n'a aucun effet:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (i < j) {
    if (running === false) {
    alert(running);
    return false;  
    }; 
    setInterval(maFnct(), 5000);
    i++;         
    };

    Si je mets setInterval("maFnct()", 5); le tableau ne s'affiche plus.

    Si je mets maFnct().delay(8); seulement la première ligne du tableau s'affiche .

  6. #6
    Expert confirmé
    Avatar de Doksuri
    Profil pro
    Développeur Web
    Inscrit en
    Juin 2006
    Messages
    2 452
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 452
    Points : 4 601
    Points
    4 601
    Par défaut
    1) le javascript va executer ton while(i<j) en un millieme de secondes... donc tu peux imaginer que le temps que tu cliques sur ton bouton, c'est deja trop tard
    c'est pour ca que tu ne vois pas ton alert()
    2) le 2eme argument pour le setInterval est en microsecondes (juste pour etre sur que tu le saches)
    La forme des pyramides prouve que l'Homme a toujours tendance a en faire de moins en moins.

    Venez discuter sur le Chat de Développez !

  7. #7
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Ton moteur javascript étant occupé à plein temps le click sur le <button> ne sera effectivement pris en compte qu'à la fin de la fonction, il faut donc le « suspendre » pour rendre la main au navigateur.

    Cela peut se faire en utilisant setTimeout pour mettre l'appel suivant dans la pile des appels.

    Voici un exemple de mise en place du setTimeout :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Affichage sur fonction longue</title>
    <meta name="Author" content="NoSmoking">
    <style>
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
      min-height: 100%;
      font: 1em/1.5 Verdana,sans-serif;
    }
    main {
      margin: auto;
      max-width: 60em;
    }
    #liste {
      width: 20em;
      padding: 0 .5em;
      max-height: 20em;
      border: 1px solid #888;
      overflow: auto;
      list-style: none;
    }
    </style>
    <body>
    <main>
      <p>
      <button id="btn_start">Start</button>
      <button id="btn_stop">Stop</button>
      </p>
      <div id="info">...</div>
      <ul id="liste"></ul>
    </main>
    <script>
    //////////////////////////////////////////////////////
    var bStop;
    var tabTimer = [];
     
    function addLigne(where) {
      var oLi = document.createElement('LI');
      var num = where.children.length;
      oLi.appendChild(document.createTextNode('ligne ' + num));
      where.appendChild(oLi);
      where.scrollTop = where.scrollHeight;
    }
     
    function startActionLongue() {
      document.querySelector('#info').textContent = 'Fonction en cours...';
      // flag d'arrêt
      bStop = false;
      var iTimer = null;
      var oDest = document.querySelector('#liste');
      var i = 0;
      var nbLigne = 10000;
      while (i < nbLigne && !bStop) {
        // met sur la pile d'appel
        iTimer = setTimeout(function () {
          addLigne(oDest);
        }, 10);
        i += 1;
        // sauve le timer
        tabTimer.push(iTimer);
      }
    }
     
    function stopActionLongue() {
      document.querySelector('#info').textContent = 'Fonction stoppée !';
      // flag d'arrêt
      bStop = true;
      // supprime les timers
      while (tabTimer.length) {
        clearTimeout(tabTimer.pop());
      }
    }
    // actions sur boutons
    document.querySelector('#btn_start').onclick = startActionLongue;
    document.querySelector('#btn_stop').onclick = stopActionLongue;
    </script>
    </body>
    </html>

    Pour la formation : Cours et tutoriels pour apprendre JavaScript

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Merci beaucoup pour toutes ces infos. Pour quelqu'un qui n'est pas expert, c'est un peu compliqué à première vue. Mais je vais bien étudier le code que vous m'avez fourni et j'espère réussir à l'appliquer dans mon application. Ça me semble un point très important de savoir stopper un script en cours.

    https://jsfiddle.net/3dc6p4w7/4/

    Le code est simple et efficace effectivement, il me reste encore à bien le comprendre.

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    J'essaye d'appliquer cette solution au programme que j'ai construit.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	   var i = arg1;		 
    		while (arg1 < arg2) {   
               iTimer = setTimeout(function () {
                   maFonction(i);
               },10);             
                maTable.push(iTimer);   
                i++;  
             }
    maFonction(i) permet d'extraire des données d'une base et de les insérer dans une nouvelle ligne de la table maTable.

    Avec ce code, je n'obtiens que la première ligne, la boucle ne s'exécute pas.

  10. #10
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    insérer dans une nouvelle ligne de la table maTable.
    si maTable est un HTMLElement alors il y à un soucis avec cette action maTable.push(iTimer) !

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    C'est bien ça, maTable est déclaré dans le code HTML :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <table id="maTable" align="center"></table>
    et maFonction(i) utilise append pour insérer des nouvelles lignes.

  12. #12
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    C'est bien ça, maTable est déclaré dans le code HTML :
    et donc !?!

  13. #13
    Membre actif
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Points : 273
    Points
    273
    Par défaut
    Et donc dans le code suivant il semble que ça fonctionne :

    https://jsfiddle.net/3dc6p4w7/12/

    Idem en rajoutant une table dans la Div principale : https://jsfiddle.net/3dc6p4w7/14/

    Si on Clique sur Timer et que de suite après on clique sur Number, ça stoppe le script enclenché par le clic sur le bouton Timer.

    Mais je comprends pas pourquoi, quand on Clique sur Timer, la durée de traitement est de 2 secondes au lieu de 30 et pourquoi les chiffres ne s'affichent pas toutes les 2 secondes les uns après les autres.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    var tabTimer = [];
    $('#Timer').on('click',function(e) {
    var i = 1; 
    while (i<=15) {
    increment(i);
    i++;
    }
    });
     
    function increment(i) {
    	if(i <= 15) {
      	iTimer = setTimeout(function() {
      		$('#myNote').append('<div id="fade'+i+'">'+i+'</div>');
          }, 2000);
    	}
       tabTimer.push(iTimer);  
    }
     
     
     $('#Number').on('click',function() { 
     while (tabTimer.length) {
        clearTimeout(tabTimer.pop());
      } 
    	 $('#myNote').text("TEXTE");
    });
    En fait, si on remplace 15 par 150 000, on s'aperçoit que ça marche plus : https://jsfiddle.net/3dc6p4w7/18/

    J'ai modifié le code mais ça marche toujours pas : https://jsfiddle.net/3dc6p4w7/19/

    Pour 15 000 c'est bon, mais pas pour 150 000 : https://jsfiddle.net/3dc6p4w7/23/

Discussions similaires

  1. Action > Go to report qui ouvre une nouvelle fenetre
    Par cherkaoui.h dans le forum SSRS
    Réponses: 2
    Dernier message: 20/09/2011, 11h10
  2. comment faire pour stopper une action en cours ?
    Par zabdaniel dans le forum C#
    Réponses: 1
    Dernier message: 15/01/2009, 16h07
  3. Exécuter une action quand on ferme le navigateur
    Par Leobaillard dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 08/01/2006, 12h41
  4. Réponses: 1
    Dernier message: 25/10/2005, 13h25
  5. Exécuter une action à la fermeture d'une fenêtre
    Par wwave dans le forum Servlets/JSP
    Réponses: 12
    Dernier message: 28/07/2005, 15h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo