Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

174
Visualizações
Iniciar <script> recién insertado después de una llamada AJAX y detener <script> eliminado después de otra llamada AJAX

Estoy haciendo una biblioteca de juguetes en la que el usuario puede modificar el DOM con AJAX, básicamente alrededor de:

 fetch("/newpage").then(r => r.text()).then(html => { var tmp = document.createElement('html'); tmp.innerHTML = html; document.querySelector("#container").outerHTML = tmp.querySelector("#container").outerHTML; // insert in the DOM

El usuario de la biblioteca puede decidir tener bloques <script> en el HTML insertado <div> , así que después de la inserción hago lo siguiente:

 for (const scr of document.querySelectorAll("#container script")) eval(scr.innerHTML);

como se explica en Ejecutar <script> inyectado por innerHTML después de la llamada AJAX .

Esto funciona bien. Pero luego, si se realiza otra llamada AJAX y #container se reemplaza nuevamente por otra cosa, y se elimina el <script> , debemos poder detener todos los scripts en ejecución que se originaron desde el <script> dentro #container . ¿Como hacer esto?

Ejemplo:

  • después de la llamada AJAX #1, #container contiene un <script> con código que se ejecuta periódicamente ( setInterval , etc.). Ahora se está ejecutando gracias a eval (ver arriba)

  • después de la llamada AJAX #2, #container se reemplaza por otra cosa, y este <script> ya no está aquí . Pero la tarea setInterval todavía se está ejecutando... ¿Cómo eliminar esto automáticamente cuando <script> desaparece después de la llamada AJAX #2?

Ideas: ¿podríamos asociar el valor de retorno de eval(..) a una variable, para que podamos realizar un seguimiento de esto y eliminar su ejecución más tarde?
O al insertar <script> con element.outerHTML = ... , ¿deberíamos agregar un identificador (id o clase) al <script> , para que luego podamos tomar medidas sobre el código que lanzó este bloque de script?

Nota: tampoco ¿Es posible detener la ejecución de JavaScript? ni ¿Cómo terminar el script en JavaScript? ni ejecutar <script> inyectado por innerHTML después de la llamada AJAX para resolver esta pregunta.

about 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Puede envolver el setTimeout antes de eval() el script. Cuando elimine el script, puede cancelar el registro de las tareas.

 function mockInternal() { const setTimeout = window.setTimeout; const setInterval = window.setInterval; // window.setImmediate // window.addEventListener const setTimeoutHandlers = []; const setIntervalHandlers = []; window.setTimeout = function mock_setTimeout(callback, delay) { const h = setTimeout(callback, delay); setTimeoutHandlers.push(h); return h; } window.setInterval = function mock_setInterval(callback, delay) { const h = setInterval(callback, delay); setIntervalHandlers.push(h); return h; } return function clearMockInternal() { window.setTimeout = setTimeout; window.setInterval = setInterval; setTimeoutHandlers.forEach(h => clearTimeout(h)); setIntervalHandlers.forEach(h => clearInterval(h)); } } const clearMockInternal = mockInternal(); eval(`setInterval(() => console.log(new Date()), 1000);`); setTimeout(() => { clearMockInternal(); console.log("should not log Date from now"); }, 6000);

about 4 years ago · Santiago Trujillo Relatório

0

Esta respuesta solo responde a su única pregunta (por intervalo), pero solo quiero compartirla. Puede devolver valores de su evaluación y usarlos para más adelante. Por ejemplo:

índice.html

 <html> <head> </head> <body> <button type="button" onclick="run1()">Run first method</button> <button type="button" onclick="run2()">Run second method</button> <div id="container"> </div> <script> var pro1, pro2; function run1() { if (pro2 != undefined && pro2 != null) { clearInterval(pro2); } fetch("page1.html").then(r => r.text()).then(html => { var tmp = document.createElement('html'); tmp.innerHTML = html; document.querySelector("#container").outerHTML = tmp.querySelector("#container").outerHTML; for (const scr of document.querySelectorAll("#container script")) { pro1 = eval(scr.innerHTML); } }); } function run2() { if (pro1 != undefined && pro1 != null) { clearInterval(pro1); } fetch("page2.html").then(r => r.text()).then(html => { var tmp = document.createElement('html'); tmp.innerHTML = html; document.querySelector("#container").outerHTML = tmp.querySelector("#container").outerHTML; for (const scr of document.querySelectorAll("#container script")) { var data = eval(scr.innerHTML); pro2 = data; } }); } </script> </body> </html>

pagina1.html

 <html> <head> </head> <body> <div id="container"> <script> test(); function test() { var i = 0; const interval = setInterval(function () { console.log(i); i++; }, 1000); return interval; }; </script> </div> </body> </html>

pagina2.html

 <html> <head> </head> <body> <div id="container"> <script> test(); function test() { var i = 9999; const interval = setInterval(function () { console.log(i); i--; }, 1000); return interval; }; </script> </div> </body> </html>

Cada vez que haga clic en un botón, se detendrá otro intervalo

Captura de pantalla para la muestra:

Muestra

Espero que esto ayude.

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda