删除仍在运行的js代码

问题描述 投票:0回答:2

js 代码保持运行,即使元素从页面中删除。
使用

react-js
编码时的第一个困难。因为页面没有重新加载所以初始脚本仍在运行,如
setInterval,websocket,etc
代码。下面的简单示例元素已被删除但仍在运行。如果我必须使用全局变量创建则无效。这将是一个安全漏洞

<button onclick="createNewJsCode()">create new js</button>
<button onclick="removeJsCode()">remove js</button>
<script>
  let id = ''
  function createNewJsCode(){
    let s = document.createElement('script')
    let code = 'setInterval(`console.log(new Date())`,500)'
    s.id = (id = crypto.randomUUID())
    s.appendChild(document.createTextNode(code));
    document.body.appendChild(s);
  }
  function removeJsCode(){
    document.getElementById(id).remove()
  }
</script>

javascript reactjs dom
2个回答
1
投票

被视为 React 问题,下面是在 React 组件中使用

setInterval
的示例。如果您使用某种形式的 React Router,下面的代码也将正确卸载/挂载等

const {useState, useEffect} = React;

function Page() {
  const [counter, setCounter] = useState(0);
  useEffect(() => {
    const i = setInterval(() => {
       console.log(new Date());
       setCounter(c => c +1);
    }, 1000);
    return () => {
      console.log('umount');
      clearInterval(i);
    }
  }, []);
  return <div>
    This is a page, and when unmounted will end the setInterval. <br/>Counter: {counter}, time: {new Date().toLocaleString()}<br/> Check console you will also see console logging of datetime finishes.
  </div>
}

function OtherInfo() {
  return <div>
    Notice how the timer stopped inside the console.  <br/>  If you click Show Page the component will be mounted again, this is kind of the basis of how React Router works in a Single Page Application (SPA).
  </div>
}

function App() {
  const [pageVis, setPageVis] = useState(true);
  return <div>
    {pageVis && <Page/>}
    {!pageVis && <OtherInfo/>}
    <hr/>
    {pageVis && <button onClick={() => setPageVis(false)}>Unmount Page</button>}
    {!pageVis && <button onClick={() => setPageVis(true)}>Show Page</button>}
  </div>
}


const root = ReactDOM.createRoot(document.querySelector('#mount'));
root.render(<App/>);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

<div id="mount"></div>


0
投票

你不能只删除

<script>
节点,你必须做一些更具体的清理工作。

setInterval
返回一个间隔 ID,您可以将其传递给
clearInterval
以停止它。

一般来说,我会说你的代码在 React 上下文中没有多大意义,但在你的情况下你可以这样做:

<button onclick="createNewJsCode()">create new js</button>
<button onclick="removeJsCode()">remove js</button>
<script>
  let id;
  let intervalId;
  function createNewJsCode(){
    let s = document.createElement('script')
    let code = 'intervalId = setInterval(`console.log(new Date())`,500)'
    s.id = (id = crypto.randomUUID())
    s.appendChild(document.createTextNode(code));
    document.body.appendChild(s);
  }
  function removeJsCode(){
    clearInterval(intervalId);
    document.getElementById(id).remove()
  }
</script>

© www.soinside.com 2019 - 2024. All rights reserved.