我阅读了文章,并从Google和Google尝试了许多方法,以获取如何使AJAX .responseText
能够运行JS的方法,但这些方法都不起作用或产生故障,我需要一个有效的方法可以与insertAdjacentHTML
正常使用。
代码
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>
答案 0 :(得分:0)
insertAdjacentHTML-ed后,如何手动评估脚本。
document.querySelectorAll('#ajax script').forEach(script => {
script.remove()
eval(script.innerHTML)
})
答案 1 :(得分:0)
如果我正确理解了该问题,以及您在注释(和其他问题)中提到的一些“问题”,则EASIEST解决方案是重构代码,以便B.PHP
中的响应只是iframe src值(即无需HTML),只需创建一个iframe并设置源-
因为据我所知,每次样式/脚本标签都是相同的,所以您可以通过编程方式只为这些元素获取一次其他AJAX,但是我不会为此提供代码,因为那非常简单
相反,该解决方案对B.PHP
中的输出进行了最小的更改
首先,为b.php
响应中返回的“唯一”(即您只希望加载/运行一次的位)元素指定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代码:
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代码
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中