29

I am creating a simple ajax call that retrieves the content of a specified url and writes it to the page. The problem I am having is that it replaces the entire body contents with this information

here is the JS:

(function(){
    var mb = window.mb = {};

    function get_ad(url, parameters){
        var result = "";
        var http_request = false;

        if (window.XMLHttpRequest) { // Mozilla, Safari,...
            http_request = new XMLHttpRequest();
            if (http_request.overrideMimeType) {
                http_request.overrideMimeType('text/html');
            }
        } else if (window.ActiveXObject) { // IE
            var avers = ["Microsoft.XmlHttp", "MSXML2.XmlHttp", "MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.4.0", "MSXML2.XmlHttp.5.0"];
            for (var i = avers.length -1; i >= 0; i--) {
                try {
                    http_request = new ActiveXObject(avers[i]);
                    if (http_request){
                        break;  
                    }
                } catch(e) {}
            }
        }
        if (!http_request) {
            alert('Cannot create XMLHTTP instance');
            return false;
        }

        http_request.onreadystatechange = function(){
                                              if (http_request.readyState == 4) {
                                                 if (http_request.status == 200) {
                                                    gen_output(http_request.responseText);
                                                 } else {
                                                    alert('Error');
                                                 }
                                              }
                                           }

        http_request.open('GET', url + parameters, true);
        http_request.send(null);
    }

    function gen_output(ad_content){
        document.write("<div id=\"mb_ad\">");
        document.write(ad_content);
        document.write("</div>");
    }

    get_ad("http://localhost/test/test.html", "");
})();

and here is the html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
    i am text before <br/>
    <script type="text/javascript" src="mb.js"></script>
    <br />
    i am text after 
</body>
</html>

using firebug to inspect, i do not see the text before or the text after, just the <div id="mb_ad"> and the content from the test.html page. If i remove the ajax call and just do 3 document.writes the text before and the text after will display properly. jQuery is not an option, I have to do this without the help of a large library as size and speed are of the essence.

4
  • 2
    I can't find what might be wrong with your code, I guess it need more inspection/break point. but for the "jQuery is not an option", I really don't agree, 24ko of javascript (which is probably cached if using google CDN) is really not making a difference on a webpage. If you have that strong requirement I'm not sure a website or even a network application is a good idea. Commented Mar 2, 2010 at 0:19
  • moreover, you could use lightweight library such as DOMAssistant or similar. Commented Mar 2, 2010 at 0:21
  • it has to do with the fact that this script will be inserted into other websites, so to add a library like jquery to a website that is probably using other libraries, or maybe even jquery itself, will just cause problems. Commented Mar 2, 2010 at 0:24
  • 2
    @downvoter care to comment as to why you downvoted a 5 year old question? Commented Jun 4, 2015 at 19:21

7 Answers 7

49

You can't use document.write once the document has completed loading. If you do, the browser will open a new document that replaces the current.

Use the innerHTML property to put HTML code inside an element:

function gen_output(ad_content){
  document.getElementById('mb_ad').innerHTML = ad_content;
}

Put the element before the script, so that you are sure that it exists when the callback function is called:

i am text before
<div id="mb_ad"></div>
i am text after
<script type="text/javascript" src="mb.js"></script>

It doesn't matter much where you place the script, as nothing will be written to the document where it is.

Sign up to request clarification or add additional context in comments.

2 Comments

is it at all possible to accomplish what i am trying without a separate div? This is supposed to be something that is embedded into a clients site, and I was asked to do it with a single script call.
Yes, you could use document.write to write the div to the page before making the AJAX call.
14

in case you cant control the remote script you might be able to write something like so:

<script>
var tmp = document.write;

document.write = function () {
  document.getElementById('someId').innerHTML = [].concat.apply([], arguments).join('');
};
</script>
<script .....>
document.write = tmp;

Well it is a nasty hack but it seems to work...

Comments

2
var div = document.createElement('div');
div.id = 'mb_ad';
div.innerHTML = ad_content;

Now, you can append this node wherever you want it to be.

Comments

0

you can use <script>document.body.innerHTML+="//Your HTML Code Here";</script>

Comments

0

Same Leon Fedotov answer but more jQuery

{
  var old_write = document.write;

  var $zone = $('.zone.zone_' + name);
  // redefine document.write in this closure
  document.write = function () {
    $zone.append([].concat.apply([], arguments).join(''));
  };
  // OA_output[name] contains dangerous document.write
  $zone.html(OA_output[name]);

  document.write = old_write;
}

Comments

0

I had the same problem with the following code :

$html[] = '<script>
           if($("#mf_dialogs").length == 0) {
               document.write("<div id=\"mf_dialogs\"></div>");
           }
           </script>';

The following code replaces document.write efficiently :

$html = '<div id="dialogHolder"></div>
         <script>
              if($("#mf_dialogs").length == 0) {
                  document.getElementById("dialogHolder").innerHTML="<div id=\"mf_dialogs\"></div>";
              }
         </script>';

Comments

0

The way you can emulate document.write somewhat is the following code:

<script>
  (function(script) {
    var parent = script.parentNode;
    var node = document.createTextNode('Surprise!');
    parent.replaceChild(node, script);
  })(document.currentScript);
</script>

This way you can put arbitrary HTML in place of a script element. If you have a simpler case, like you can wrap a script in another tag, you can do even simpler version.

<script>
  document.currentScript.parentElement.innerHTML = 'Surprise!';
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.