如何从 运行 停止 Jquery 功能?

How to stop Jquery function from running?

这里是新手。可能是因为我已经困了,找不到解决办法。当我点击另一个按钮时,我试图停止一个功能。 到目前为止,这是代码:

当我单击按钮 (.start) 时,它会运行一个函数,该函数会随机打乱文本而不会完成。但是,我想单击按钮 #stop 并从 运行 停止该特定功能。我试过切换、preventDefault、event.stopPropagation()、setInterval 等……其中 None 有效。我试过把我的函数放在里面,也放在外面。

这是当前的js代码:

$(".start").click(function(){
    var getTextNodesIn = function(el) {
    // Look at all the page elements and returns the text nodes
    return $(el)
      .find(":not(iframe,script)")
      .addBack()
      .contents()
      .filter(function() {
        return this.nodeType == 3; // Text node types are type 3
      });
  };

  // var textNodes = getTextNodesIn($("p, h1, h2, h3","*"));
  var textNodes = getTextNodesIn($("p"));

  function isLetter(char) {
    return /^[\d]$/.test(char);
  }

  var wordsInTextNodes = [];
  for (var i = 0; i < textNodes.length; i++) {
    var node = textNodes[i];

    var words = [];

    var re = /\w+/g;
    var match;
    while ((match = re.exec(node.nodeValue)) != null) {
      var word = match[0];
      var position = match.index;

      words.push({
        length: word.length,
        position: position
      });
    }

    wordsInTextNodes[i] = words;
  }

  function messUpWords() {
    for (var i = 0; i < textNodes.length; i++) {
      var node = textNodes[i];

      for (var j = 0; j < wordsInTextNodes[i].length; j++) {
        // Only change a tenth of the words each round.
        if (Math.random() > 1 / 10) {
          continue;
        }

        var wordMeta = wordsInTextNodes[i][j];

        var word = node.nodeValue.slice(
          wordMeta.position,
          wordMeta.position + wordMeta.length
        );
        var before = node.nodeValue.slice(0, wordMeta.position);
        var after = node.nodeValue.slice(wordMeta.position + wordMeta.length);

        node.nodeValue = before + messUpWord(word) + after;
      }
    }
  }

  function messUpWord(word) {
    if (word.length < 3) {
      return word;
    }

    return word[0] + messUpMessyPart(word.slice(1, -1)) + word[word.length - 1];
  }

  function messUpMessyPart(messyPart) {
    if (messyPart.length < 2) {
      return messyPart;
    }

    var a, b;
    while (!(a < b)) {
      a = getRandomInt(0, messyPart.length - 1);
      b = getRandomInt(0, messyPart.length - 1);
    }

    return (
      messyPart.slice(0, a) +
      messyPart[b] +
      messyPart.slice(a + 1, b) +
      messyPart[a] +
      messyPart.slice(b + 1)
    );
  }

  // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
  function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
  }

  setInterval(messUpWords, 50);

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="controls pt-5">
<button class="start">Simulate</button>
<button id="stop">Stop</button>
</div>
<br>
<br>
<br>
<div>
  <h1>Trying</h1>

  <p>Friends who have dyslexia described to me how they experience reading. She <em>can</em> read, but it takes a lot of concentration, and the letters seems to "jump around".</p>
</div>

该功能运行良好。我只是很难让另一个按钮从 运行 停止此功能...任何帮助将不胜感激,祝大家度过愉快的一周。

您不能从 运行ning 开始停止一个函数,因为在 JavaScript 运行 时间环境中一次只能 运行 一个函数(single-threaded).当您单击按钮试图停止第一个函数时,实际发生的是第一个函数完成,然后与按钮关联的单击事件 运行s。而且,到那时,第一个功能已经完成,所以停止它已经来不及了。

您可以定期查看 asynchronous operations, which run outside of the JavaScript runtime. In your case, using setInterval() 到 运行 一个函数,这可能是最好的方法。这将允许您在调用之间检查是否发生了其他事情,这应该会在下一个时间间隔 运行ning 停止函数。

现在,您正在使用间隔计时器,但您没有设置对它的引用,因此您无法告诉它在需要时停止。解决方案是将一个变量与计时器相关联,然后调用 clearInterval() 并将计时器引用传递给它,如下所示:

let timer = null; // This will hold a reference to the timer so you can stop it later

$("#stop").on("click", function(){
  clearInterval(timer); // Stop the timer
});

$(".start").click(function(){
   var getTextNodesIn = function(el) {
   // Look at all the page elements and returns the text nodes
   return $(el).find(":not(iframe,script)")
               .addBack()
               .contents()
               .filter(function() {
                  return this.nodeType == 3; // Text node types are type 3
                });
  };

  // var textNodes = getTextNodesIn($("p, h1, h2, h3","*"));
  var textNodes = getTextNodesIn($("p"));

  function isLetter(char) {
    return /^[\d]$/.test(char);
  }

  var wordsInTextNodes = [];
  for (var i = 0; i < textNodes.length; i++) {
    var node = textNodes[i];

    var words = [];

    var re = /\w+/g;
    var match;
    while ((match = re.exec(node.nodeValue)) != null) {
      var word = match[0];
      var position = match.index;

      words.push({
        length: word.length,
        position: position
      });
    }

    wordsInTextNodes[i] = words;
  }

  function messUpWords() {
    for (var i = 0; i < textNodes.length; i++) {
      var node = textNodes[i];

      for (var j = 0; j < wordsInTextNodes[i].length; j++) {
        // Only change a tenth of the words each round.
        if (Math.random() > 1 / 10) {
          continue;
        }

        var wordMeta = wordsInTextNodes[i][j];

        var word = node.nodeValue.slice(
          wordMeta.position,
          wordMeta.position + wordMeta.length
        );
        var before = node.nodeValue.slice(0, wordMeta.position);
        var after = node.nodeValue.slice(wordMeta.position + wordMeta.length);

        node.nodeValue = before + messUpWord(word) + after;
      }
    }
  }

  function messUpWord(word) {
    if (word.length < 3) {
      return word;
    }

    return word[0] + messUpMessyPart(word.slice(1, -1)) + word[word.length - 1];
  }

  function messUpMessyPart(messyPart) {
    if (messyPart.length < 2) {
      return messyPart;
    }

    var a, b;
    while (!(a < b)) {
      a = getRandomInt(0, messyPart.length - 1);
      b = getRandomInt(0, messyPart.length - 1);
    }

    return (
      messyPart.slice(0, a) +
      messyPart[b] +
      messyPart.slice(a + 1, b) +
      messyPart[a] +
      messyPart.slice(b + 1)
    );
  }

  // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
  function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
  }

  timer = setInterval(messUpWords, 50); // Set interval reference to variable

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="controls pt-5">
<button class="start">Simulate</button>
<button id="stop">Stop</button>
</div>
<br>
<br>
<br>
<div>
  <h1>Trying</h1>

  <p>Friends who have dyslexia described to me how they experience reading. She <em>can</em> read, but it takes a lot of concentration, and the letters seems to "jump around".</p>
</div>

您可以在 messUpWords 函数的顶部检查是否已单击停止按钮。如果有,可以清除间隔,重新设置停止按钮标志,退出例程。

var stopBtnClicked = false;
var stopBtn = document.getElementById("stop");
stopBtn.addEventListener("click", function() {
  stopBtnClicked = true;
}, false);

$(".start").click(function() {
  var getTextNodesIn = function(el) {
    // Look at all the page elements and returns the text nodes
    return $(el)
      .find(":not(iframe,script)")
      .addBack()
      .contents()
      .filter(function() {
        return this.nodeType == 3; // Text node types are type 3
      });
  };

  // var textNodes = getTextNodesIn($("p, h1, h2, h3","*"));
  var textNodes = getTextNodesIn($("p"));

  function isLetter(char) {
    return /^[\d]$/.test(char);
  }

  var wordsInTextNodes = [];
  for (var i = 0; i < textNodes.length; i++) {
    var node = textNodes[i];

    var words = [];

    var re = /\w+/g;
    var match;
    while ((match = re.exec(node.nodeValue)) != null) {    
      var word = match[0];
      var position = match.index;

      words.push({
        length: word.length,
        position: position
      });
    }

    wordsInTextNodes[i] = words;
  }

  function messUpWords() {
    if (stopBtnClicked) {
      clearInterval(jumbleTimer);
      stopBtnClicked = false;
      return;
    }  
  
    for (var i = 0; i < textNodes.length; i++) {
      var node = textNodes[i];

      for (var j = 0; j < wordsInTextNodes[i].length; j++) {
        // Only change a tenth of the words each round.
        if (Math.random() > 1 / 10) {
          continue;
        }

        var wordMeta = wordsInTextNodes[i][j];

        var word = node.nodeValue.slice(
          wordMeta.position,
          wordMeta.position + wordMeta.length
        );
        var before = node.nodeValue.slice(0, wordMeta.position);
        var after = node.nodeValue.slice(wordMeta.position + wordMeta.length);

        node.nodeValue = before + messUpWord(word) + after;
      }
    }
  }

  function messUpWord(word) {
    if (word.length < 3) {
      return word;
    }

    return word[0] + messUpMessyPart(word.slice(1, -1)) + word[word.length - 1];
  }

  function messUpMessyPart(messyPart) {
    if (messyPart.length < 2) {
      return messyPart;
    }

    var a, b;
    while (!(a < b)) {
      a = getRandomInt(0, messyPart.length - 1);
      b = getRandomInt(0, messyPart.length - 1);
    }

    return (
      messyPart.slice(0, a) +
      messyPart[b] +
      messyPart.slice(a + 1, b) +
      messyPart[a] +
      messyPart.slice(b + 1)
    );
  }

  // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
  function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
  }

  var jumbleTimer = setInterval(messUpWords, 50);

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="controls pt-5">
  <button class="start">Simulate</button>
  <button id="stop">Stop</button>
</div>
<br>
<br>
<br>
<div>
  <h1>Trying</h1>

  <p>Friends who have dyslexia described to me how they experience reading. She <em>can</em> read, but it takes a lot of concentration, and the letters seems to "jump around".</p>
</div>