允许JS使用insertAdjacentHTML(Plain JS)在AJAX .responseText中运行的工作方法 [英] Working method to allow JS to run in AJAX .responseText with insertAdjacentHTML (Plain JS)

查看:87
本文介绍了允许JS使用insertAdjacentHTML(Plain JS)在AJAX .responseText中运行的工作方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读并尝试了许多方法,从帖子和Google上了解如何获取AJAX .responseText 以允许JS运行,而且没有一个方法不工作或给出了错误的结果我需要一个适用于 insertAdjacentHTML 的工作方法。

I read and I tried many methods from posts and from Google on how to get the AJAX .responseText to allow JS to run and none of the methods either don't work or gave glitchy results I need a working method that works with insertAdjacentHTML properly.

代码

a.php

<style>
  #main {
    max-height: 800px;
    width: 400px;
    display: -webkit-flex; /* Safari */
    -webkit-flex-direction: column-reverse; /* Safari 6.1+ */
    display: flex;
    flex-direction: column-reverse;
    overflow: auto;
  }
</style>

<script>
  document.addEventListener('DOMContentLoaded', function(){ 

    document.querySelector('#executeAjax').addEventListener('click', sendAjax);

    function sendAjax(){
      var xhr= new XMLHttpRequest();
      xhr.onreadystatechange = function(){

        if(xhr.readyState === 4){
          document.querySelector('#ajax').insertAdjacentHTML('beforeend', xhr.responseText);
        }
      }

      xhr.open('POST','b.php'); 
      xhr.send();
    }

  });

</script>

<button id='executeAjax'>Execute</button>

<div id="main">
  <div id='ajax'></div>
</div>

b.php

<style>
iframe{
  display: block;
  width: 100px;
  height: 100px;
}
</style>

<script>
   alert('Hello');
</script>

<script>
   alert('Hello again');
</script>

<iframe src="https://www.youtube.com/embed/tgbNymZ7vqY"></iframe>


推荐答案

如果我正确理解了这个问题,还有一些您在评论(和其他问题)中提到的问题,EASIEST解决方案是重构您的代码,以便 B.PHP 中的响应只是iframe src值(即不需要HTML),只需创建一个iframe并设置源 -

If I understand the question correctly, and some of the "issues" you've mentioned in comments (and other questions), the EASIEST solution is to refactor your code so that the response in B.PHP is just the iframe src value (i.e. no need for HTML), and just create an iframe and set the source -

因为从评论中可以看出,样式/脚本标签是每次都这样,你可以编程一次为这些元素获得一些其他的AJAX - 但我不会为此提供代码,因为这非常简单

since, as far as I can tell from comments, the style/script tags are the same each time, you can programatically just get some other AJAX for those elements once - but I'm not going to present code for that, as that is extremely simple

相反,对 B.PHP

中的输出进行微小更改的解决方案首先,给出独特 (即你只想加载/运行一次的那些)在 b.php 响应中返回的元素ID

Firstly, give the "unique" (i.e. the bits you only want to load/run once) elements that are returned in the b.php response an ID

<style id="onlyOnce1">
iframe{
  display: block;
  width: 100px;
  height: 100px;
}
</style>

<script id="onlyOnce2">
   alert('Hello');
</script>

<script id="onlyOnce3">
   alert('Hello again');
</script>

<iframe src="https://www.youtube.com/embed/tgbNymZ7vqY"></iframe>

现在,我之前建议的loadHTML代码:

Now, the loadHTML code I suggested earlier:

function loadHTML(text, dest, replace) {
    if (typeof dest == 'string') {
        dest = document.querySelector(dest);
    }
    var p = new DOMParser();
    var doc = p.parseFromString(text, 'text/html');
    var frag = document.createDocumentFragment();
    var id;
    while (doc.head.firstChild) {
        id = doc.head.firstChild.id;
        if(!(id && document.getElementById(id))) {
            // only add if id is not in DOM already
            frag.appendChild(doc.head.firstChild);
        }
    }
    while (doc.body.firstChild) {
        id = doc.head.firstChild.id;
        if(!(id && document.getElementById(id))) {
            // only add if id is not in DOM already
            frag.appendChild(doc.head.firstChild);
        }
    }
    [].forEach.call(frag.querySelectorAll('script'), function(script) {
        const scriptParent = script.parentNode || frag;
        const newScript = document.createElement('script');
        if (script.src) {
            newScript.src = script.src;
        } else {
            newScript.textContent = script.textContent;
        }
        scriptParent.replaceChild(newScript, script);
    });
    if (replace) {
        dest.innerHTML = '';
    }
    dest.appendChild(frag);
};

您可以按如下方式更改XHR代码

You'd change your XHR code as follows

document.addEventListener('DOMContentLoaded', function() { 
    document.querySelector('#executeAjax').addEventListener('click', sendAjax);
    function sendAjax() {
        const xhr = new XMLHttpRequest();
        xhr.addEventListener('load', function() {
            loadHTML(xhr.responseText, '#ajax');
        });
        xhr.open('POST','b.php'); 
        xhr.send();
    }
});

现在,第一次调用loadHTML时,将添加所有元素 - 但是在第二次及以后调用,具有特定ID的已经包含的元素(上例中的样式和脚本)将不会再次加载到DOM中

Now, the FIRST time you loadHTML is called, all elements will be added - but on second and subsequent calls, the "already" included elements with a particular ID (style and script in the above example) will not be loaded into the DOM again

这篇关于允许JS使用insertAdjacentHTML(Plain JS)在AJAX .responseText中运行的工作方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆