2010-03-02 16 views
23

Tworzę proste wywołanie ajax, które pobiera treść określonego adresu URL i zapisuje go na stronie. Problem mam jest to, że zastępuje całą zawartość ciała z informacjiJavaScript Document.Write Zastępuje zawartość treści podczas korzystania z AJAX

tutaj jest 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", ""); 
})(); 

i tutaj jest 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> 

użyciu Firebug do wglądu, Nie widzę tekstu przed tekstem ani tekstu po nim, tylko <div id="mb_ad"> i treści ze strony test.html. Jeśli usunę połączenie ajax i po prostu zrobię 3 document.writes tekst przed, a tekst po będzie wyświetlany poprawnie. jQuery nie jest opcją, muszę to zrobić bez pomocy dużej biblioteki, ponieważ rozmiar i szybkość są istotą.

+2

nie mogę znaleźć tego, co może być nie tak z kodem, myślę, że potrzebujemy więcej kontroli/punkt przerwania. , ale dla "jQuery nie jest opcją", naprawdę nie zgadzam się, 24ko javascript (który jest prawdopodobnie buforowany jeśli korzystasz z google CDN) naprawdę nie robi różnicy na stronie. Jeśli masz tak silne wymagania, nie jestem pewien, czy strona internetowa, czy nawet aplikacja sieciowa, jest dobrym pomysłem. – Mathieu

+0

Ponadto można użyć biblioteki lekkiej, takiej jak DOMAssistant lub podobnej. – dusoft

+0

ma to związek z tym, że ten skrypt zostanie wstawiony do innych witryn, więc dodanie biblioteki takiej jak jquery do witryny, która prawdopodobnie używa innych bibliotek, lub może nawet sama jquery, spowoduje tylko problemy. –

Odpowiedz

41

Nie można użyć document.write po zakończeniu ładowania dokumentu. Jeśli to zrobisz, przeglądarka otworzy nowy dokument, który zastąpi bieżący.

Użyj właściwości innerHTML umieścić kod HTML wewnątrz elementu:

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

Put element przed skryptu, dzięki czemu masz pewność, że ono istnieje, gdy funkcja zwrotna jest wywoływana:

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

Nie ma znaczenia, gdzie umieszcza się scenariusz, ponieważ nic nie zostanie zapisane w dokumencie, w którym się znajduje.

+0

jest to w ogóle możliwe, aby osiągnąć to, co próbuję bez oddzielnego "div"? To ma być coś, co jest osadzone w witrynie klienta, a ja zostałem poproszony o zrobienie tego za pomocą pojedynczego wywołania skryptu. –

+0

Tak, możesz użyć document.write, aby zapisać div na stronie przed wykonaniem połączenia AJAX. – Guffa

+0

działa to świetnie, dzięki! –

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

Teraz możesz dołączyć ten węzeł, gdziekolwiek chcesz.

13

w przypadku nie można kontrolować zdalny skrypt może być w stanie napisać coś tak:

<script> 
var tmp = document.write; 

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

No to paskudny hack, ale wydaje się działać ...

0

można użyć <script>document.body.innerHTML+="//Your HTML Code Here";</script>

0

samą odpowiedź Leon Fedotow ale bardziej 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; 
} 
0

I miałem ten sam problem z następującego kodu:

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

Poniższy kod zastępuje document.write skutecznie:

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