5

I tried to use $("html").html(this.responseText);. Which replaces the content but it does not replace the head and body tags.

So for example if i want replace this content:

<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script>...</script>
<script>...</script>
</head>
<body>

<h1>This is a Heading</h1>


<script>...</script>
</body>
</html>

Then i check my HTML structure in inspector, and the result this:

<!DOCTYPE html>
<html>
<title>Page Title</title>
<script>...</script>
<script>...</script>

<h1>This is a Heading</h1>

<script>...</script>

</html>

And it messed my css so. I have tried without scripts, and it worked fine. What is the solution for this problem?

I have also tried with javascript approach

document.open();
document.write(this.responseText);
document.close(); 

But it confuses my javascripts. I am getting redeclaration syntax error.

My real code where i want to implement:

<script>
  
        var frm = $('#frm');
        var submitActors = frm.find('input[type=submit]');
        var submitActor = null;
        submitActors.click(function(event) {
                submitActor = this;  
        });
        
        frm.unbind('submit').submit(function () {
           
            var formAction = document.getElementById("frm").getAttribute('action'); // Get the form action.
            var data = "";
            var pageUrl = "";
            var test_uuid = "";
            var test_number = "";
            var qid = JSON.parse(sessionStorage.getItem('userChoice')).qid;
            
            
            
            if(submitActor.name == "cmdSave"){
                data = {
                    "cmdSave" : $("#cmdSave").val(),
                    "Answer": document.querySelector('input[name="Answer"]:checked').value,
                    "csrfmiddlewaretoken": document.querySelector('input[name=csrfmiddlewaretoken').value,
                    "qid": qid
                }
            }
            else if(submitActor.name == "cmdNext"){
                data = {
                    
                    "cmdNext": document.querySelector('#cmdNext').value,
                    "csrfmiddlewaretoken":document.querySelector('input[name=csrfmiddlewaretoken').value,
                    "qid": qid
                }
            }
            var httpRequest = new XMLHttpRequest();
            var formData = new FormData();
            
            
            
            Object.keys(data).forEach(function(key) {
                console.log(key, data[key]);
                formData.append(key, data[key]);
            });
                console.log(formData)
            httpRequest.onreadystatechange = function(){
                if ( this.readyState == 4 && this.status == 200 ) {
                var response = this.responseText;
                    console.log(this.responseText) // Display the result inside result element.

                    // 1.Option
                    {% comment %} document.open();
                    document.write(this.responseText);
                    document.close(); {% endcomment %}
                    
                    // 2.Option
                    
                    {% comment %} document.documentElement.innerHTML = this.responseText;  {% endcomment %}
                    
            
                    // 3.Option
                    $(document).ready(function(){
                        $("html").html(response);
                    });
                                                                             
                
                    test_number = document.getElementById("lblNrCrt").textContent;  
                    test_uuid = "{{test.uuid}}";
                    pageUrl = "/intro/" + test_uuid + "/" + test_number + "/";
                    window.history.pushState('', '', pageUrl);
                }
            };

            httpRequest.open("post", formAction);
            httpRequest.send(formData);

            return false;
        
        });

</script>

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Arnold96
  • 113
  • 1
  • 2
  • 10
  • 1
    If I do `document.querySelector('html').innerText = 'yolo'` it replaces everything. I'm not sure what jquery does, but this will do what you need – Jeanluca Scaljeri Oct 11 '19 at 07:00
  • Which browser is this on? `$("html").html("some text")` wipes out everything for me in Firefox. Also, are you sure the `this.responseText` doesn't happen to contain those tags? – VLAZ Oct 11 '19 at 07:04
  • The responsetext contains those tags, I checked. I am using Firefox – Arnold96 Oct 11 '19 at 07:09

5 Answers5

11

As I pointed out it can be done

document.querySelector('html').innerText = 'yolo';

But if you need to render HTML you should do

document.querySelector('html').innerHTML = '<div>yolo</div>';
Jeanluca Scaljeri
  • 26,343
  • 56
  • 205
  • 333
  • 2
    Just as an alternative, you can grab the body and go to its parent `document.body.parentElement`. Probably doesn't really give you any benefit *here* doing it that way but I've very occasionally found that finding the child and going to the parent is more useful than trying to find the parent. – VLAZ Oct 11 '19 at 07:06
  • It did not work if i post twice, the second time my javascript is not running. – Arnold96 Oct 11 '19 at 10:03
  • @Arnold96 Here is a working example: https://stackblitz.com/edit/typescript-3wubgf – Jeanluca Scaljeri Oct 11 '19 at 10:09
3

Using Chrome browser I found that the response (or any innerHTML you want to use as the new page) has to start strictly with the <head> tag. Not <html> or <!DOCTYPE html> or anything else, otherwise replacing innerHTML or using document.write(response) always outputs the whole content inside <body>...</body> tag.

Here is the snippet/page I used locally to try all suggestions I saw (and didn't work), until I tried condensing the new page content/string to "<head>...</head><body>...</body>".

document.querySelector("#replace-content-btn").addEventListener('click', function() {
  document.querySelector("html").innerHTML = `
    <head>
      <title>New Page Title</title>
    </head>
    <body>
      <p>New body content.<br>Inspect the head element!</p>
    </body>`;
});
<head>
  <title>Some Page Title</title>
</head>

<body>
  <p>Some body content.<br>Inspect the head element before and after button click.</p>
  <button type="button" id="replace-content-btn">Replace entire HTML</button>
</body>
1

JS: With innerHTML you can replaces all html content of element.

document.querySelector('html').innerHTML = '...'

Jquery:

$( document ).ready(function() {
  $('html').html('...');
});
miladfm
  • 1,508
  • 12
  • 20
1

find tag content in your string : function getByTag(tagname,htmlVal) { var tagHtmValue = $(htmlVal).find(tagname).html(); return tagHtmValue; }

replace head and and body content with the body and head in your response:

$("head").html(getByTag("head",this.responseTex)); $("body").html(getByTag("body",this.responseTex));

Mido elhawy
  • 469
  • 4
  • 11
0

I have tested below code works !...

let responseTxt="<html> \
<head><title>changed hello</title></head><body><h1>Changed body</h1></body></html>"
$(document).ready(()=>{
 $(".action").click(()=>{
  $("html").html(responseTxt)
 });

});
<html>
<head><title>hello</title></head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body>
<h1>hello</h1>
<button class="action">Change HTML</button>
</body>
</html>
siddesh
  • 41
  • 3
  • I have tried this solution and the $(document).ready(()=>{...} solved the problem, but in my real project it does not work...can something mess it? – Arnold96 Oct 11 '19 at 12:18
  • I updated a the question. so i have tried to put the entire javascript code into ready state but it didn't work anyway. – Arnold96 Oct 11 '19 at 12:30