SetInterval продолжает работать даже после удаления всего скрипта со страницы html

Я создал специальную функцию для репликации функции setInterval. Вот что я пытаюсь сделать:

<html>
   <head>
       <script id='scpt_a'>
            //custom setInterval function

     function interval(func,ti){

      try{
         func.call(null);
         }
       catch(err){
          throw new Error(err.toString());
         }
       setTimeout(()=>{interval(func,ti); },ti);
         }

       //custom setinterval function end

      $('#start).click(()=>{
          $('body').append("<script id='scpt_b'>interval(()=> 
          {console.info('hello');},10000);</script>");
       });

      $('#stop).click(()=>{
            $('#scpt_a').remove();
            $('#scpt_b').remove();
       });


       </script>
   </head>
   <body>
      <button id='start'>start</button>
       <button id='stop'>stop</button>
   </body>
</html>

всякий раз, когда я запускаю этот код, он работает нормально, т.е. когда я нажимаю на кнопка Пуск, он добавляет код, поэтому код выполняет его и продолжает печатать Привет. Теперь, когда я нажимаю кнопка остановки, это удаляет, добавленный скрипт, а также начальный (не добавленный) скрипт. Итак, поскольку скрипта нет, он должен прекратить выполнение, но этого не происходит.

Я использовал инструменты разработчика Chrome, где я увидел, что после нажатия кнопка остановкине было сценария (после добавления он был там) в документе HTML, но Привет все еще печатал на консоли.

пожалуйста, помогите мне разобраться, почему так происходит и как это исправить.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
485
2

Ответы 2

Когда вы добавляете скрипт на свою страницу, он анализируется браузером. Когда вы позже удалите тег сценария, это не имеет значения, сценарий уже был проанализирован, обработан и находится в памяти браузера. Таким образом, ваша функция interval будет продолжать работать, несмотря на то, что вы удалили тег скрипта со страницы.

Вот иллюстрация этого факта. Я добавил ссылку на jQuery, см. Первое предупреждение, затем удаляю его, а после этого удаляю тег сценария jQuery, и вы можете видеть, что я все еще могу использовать функцию jQuery $:

<script id = "s1" src = "https://code.jquery.com/jquery-3.3.1.js"></script>
<script>
	alert($);
  $("#s1").remove();
  alert($);
</script>

Как уже указывалось в ответе xxxmatko, удаление элемента скрипта из DOM не останавливает его запуск, если он уже был проанализирован.

Вам нужно придумать другое решение, чтобы отменить выполнение вашего интервала. Возможно, самый простой способ - использовать вместо нее стандартную функцию setInterval. Это можно сделать следующим образом:

// Start the interval:
let intervalID = setInterval(function() { /* your code */}, 10000);

// Stop the interval:
clearInterval(intervalID);

Однако, если вы настаиваете на настраиваемой функции интервала, такой как та, что в вашем примере, вы могли бы реализовать некоторые функции, которые позволят вам отменить интервал позже аналогичным образом. Например, вы можете проверить условие в функции интервала:

function interval(func,ti){
  /* your code */
  if ( /* some condition */ )
    setTimeout(()=>{interval(func,ti); },ti);
}

И когда щелкают $('#start') или $('#stop'), это условие устанавливается в истинное или ложное соответственно.

Более того, оба этих решения позволяют избежать еще одной проблемы в вашем коде: если пользователь дважды щелкнет $('#start'), вы получите два элемента скрипта (с одинаковым идентификатором!) В DOM.

Другие вопросы по теме