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 gav
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 -
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
Instead, a solution with minimal changes to what is output in B.PHP
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>
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);
};
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();
}
});
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
After you have insertAdjacentHTML-ed, how about eval-ing the scripts manually.
document.querySelectorAll('#ajax script').forEach(script => {
script.remove()
eval(script.innerHTML)
})