【问题标题】:Kill execution of a running script tag in Angular 11在 Angular 11 中终止运行脚本标签的执行
【发布时间】:2021-12-27 12:51:29
【问题描述】:

目前我有一个 Angular 组件,它使用 Renderer2 库将脚本标签列表附加到 DOM 中,这些脚本的代码是从外部源检索的。在下面的 sn-p 中,scripts 数组是源链接的列表。在这种情况下,我无法修改他们的 JS 代码:

  for(let i = 0; i<scripts.length; i++){
    let script = this.renderer2.createElement('script');
    script.type = `text/javascript`;
    script.src = scripts[i];
    this.appendedChildren.push(script);
    this.renderer2.appendChild(this._document.body, script);
}

我试图从 DOM 中删除它们,但脚本继续执行:

ngOnDestroy(){
  for(let i = 0; i<this.appendedChildren.length; i++)
    this.renderer2.removeChild(this._document.body, this.appendedChildren[i]);
}

我想要的是让 pid 或某种标识符能够杀死 ngOnDestroy() 中的 JS 脚本,以及这样做的方法。

【问题讨论】:

  • pid 是浏览器的标签,因为 Javascript 是单线程的。 DOM 中的每个 &lt;script&gt; 标记都不会产生一个新进程。一旦它被加载到内存中,简单地删除&lt;script&gt; 标记不会做任何事情。您尝试做的事情很难,因为加载的脚本只是添加到内存中的其余部分,并在同一个线程中执行。而且它也有点“肮脏”,试图杀死这样的运行脚本听起来并不干净。你的实际问题是什么(问题 X)而不是这个“问题 Y”?
  • 目前我从外部 API 获取源链接​​,这些是呈现广告的脚本。当用户触发某些条件(例如按下按钮)时,我需要停止展示这些广告。我很难看到与此不同的方法,我可以做的是从 src 获取 JS 代码并动态修改它(添加一些常用方法)以在组件完成某些操作时将其杀死,但这看起来很棘手确实很难。
  • 如果您需要隐藏广告,那么只需使用 CSS display:none?
  • 我一直在阅读我得到的脚本,问题是它们之间没有共同点,每个都生成一个img或一个iframe标签而不添加任何类或id,并且它们附加它进入身体,这使得它们无法被发现并因此隐藏它们。我会要求 API 开发人员在脚本生成的元素中添加一个类,之后我可以对其进行解析并隐藏广告,我没有看到任何其他可行的解决方案。感谢您的帮助,我将在收到消息后立即更新此主题。
  • 哎呀,听起来有点头疼:/ 祝你好运,那么

标签: javascript angular angular-renderer2


【解决方案1】:
constructor(private renderer: Renderer2) {}

let script = this.renderer.createElement('script');
script.type = `text/javascript`;
script.src = 'testme.js';
script.id = "testScriptName";
this.renderer.appendChild(this._document.body, script);

ngOnDestroy() {
var elem = document.querySelector("#testScriptName");
document.querySelector("#testScriptName").parentNode.removeChild(elem)
}

【讨论】:

  • 请试一试。 @Across
  • 如果脚本已经在运行,从 DOM 中删除它不会做任何事情。
【解决方案2】:

好的,我被告知了一种方法,它完美无缺。

我可以创建一个 iframe 并使用 iframe 中的 srcdoc 属性传递所有脚本,而不是创建脚本,这将是我想从 Angular 组件创建并附加到DOM,我应该为每个脚本创建一个 iframe:

  <iframe class="iframe-container" srcdoc='
  <html>
    <head></head>
    <body>
      <script src="https://script-source.com"></script>
    </body>
  </html>'>
</iframe>

因此,要从 Angular 组件创建和附加脚本,请注意我正在将该组件添加到附加的子数组中(我知道有更简洁的方法可以做到这一点,只是为了了解这个想法):

let iframe = this.renderer2.createElement('iframe');
iframe.setAttribute('class', 'iframe-ad');
iframe.setAttribute('srcdoc', `
  <html>
    <head></head>
    <body>
      <script src="https://src-example-url.com"></script>
    </body>
  </html>
`);

this.appendedChildren.push(iframe);
this.renderer2.appendChild(this._document.body.querySelector('div.iframe-holder'), iframe);

为了删除 iframe,只需将这些行添加到 ngOnDestroy() 中即可:

ngOnDestroy(){
  for(let i = 0; i<this.appendedChildren.length; i++){
    this.renderer2.removeChild(this._document.body, this.appendedChildren[i])
  }
}

【讨论】:

    猜你喜欢
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 2018-10-05
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多