[AJAX] Het terugkrijgen van HTML met javascript

Pagina: 1
Acties:
  • 408 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb AJAX werkend in zoverre dat ik de html die door een .php bestand wordt gegenereerd in een div kan zetten. Maar nu doet zich een probleem voor als de html ook nog javascript bevat. In dit geval gebeurd er namelijk helemaal niks meer met de javascript.

Bijvoorbeeld als de volgende html door ajax in een div wordt geladen:

code:
1
2
3
<script language="Javascript">
    alert ("Test");
</script>


dan wordt die alert dus niet weergegeven...

Weet iemand waardoor dit gebeurd en wellicht een oplossing hiervoor?

[ Voor 5% gewijzigd door Verwijderd op 19-04-2006 16:22 ]


Acties:
  • 0 Henk 'm!

Verwijderd

AFAIK wordt javascript alleen bij het laden van een pagina of bij het aanroepen van een functie uitgevoerd, niet als je het met AJAX op je site neerzet.

De oplossing weet ik niet precies, maar ik denk niet dat je de 1e bent met dit probleem...

Acties:
  • 0 Henk 'm!

  • Cubix
  • Registratie: Juni 2001
  • Niet online
Dit soort javascript wordt (blijkbaar) alleen uitgevoerd wanneer de pagina de eerste keer wordt aangeroepen, en niet wanneer iets als innerhtml er nog iets bij duwt.

Wat wel werkt is de html voorzien van eventhandlers zoals onclick().

Als oplossing voor jouw probleem zou ik de gewenste javascript laten uitvoeren wanneer de server het juiste (ajax) respons heeft gegeven. Minder flexibel helaas.

Acties:
  • 0 Henk 'm!

  • funkwurm
  • Registratie: December 2005
  • Laatst online: 22-02-2021
Wat je kunt doen is enkel en alleen javascript sturen (dus zonder <script>-tags of wat dan ook) en die dan eval()ueren. Zoiets als eval(ajax.responseText); dus, een beetje het JSON principe.

Acties:
  • 0 Henk 'm!

  • marko77
  • Registratie: Februari 2002
  • Laatst online: 06-05 19:41
Waarom wil je dit überhaupt? met AJAX (javascript) een javascript alert genereren die dan uitgevoerd dient te worden.

Het lijkt me handiger om dit gewoon in dezelfde aanroep als de AJAX aanroep te doen, dat scheelt ook weer geneuzel.

Mijn rig


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dit was alleen een voorbeeld om het probleem te demonstreren, het gaat niet om een alert maar om een ander stuk javascript dat hetzelfde probleem oproept.

Acties:
  • 0 Henk 'm!

  • lawnmower
  • Registratie: November 2000
  • Laatst online: 08-09 12:02

lawnmower

Elvis lives..

Kun je niet een functie terug geven, en die vervolgens aan het einde van je ajax-functie aanroepen?

Acties:
  • 0 Henk 'm!

  • funkwurm
  • Registratie: December 2005
  • Laatst online: 22-02-2021
@lawnmower: Volgens mij niet, want voordat je een functie kunt aanroepen moet je de functie declaratie wel "uitvoeren".

@TS: heb je eval() al geprobeerd? Lukt dat?

Acties:
  • 0 Henk 'm!

  • Blackbird-ce
  • Registratie: September 2005
  • Laatst online: 20:05
Wordt een "body onLoad" gedraaid op het moment dat je de pagina binnenhaalt? In dat geval kun je in elke pagina bovenaan een extra function maken (initializeAll() o.i.d.) waar je simpelweg alle scriptjes of referenties anar te draaien functions in opneemt.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Je zou zoiets kunnen doen, maar persoonlijk vind ik dat wel een beetje lelijk:
JavaScript:
1
2
3
var html = xmlhttp.responseText;
var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
while ((match = re.exec(html))) eval(match[2]);

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Sorry voor de zeer late reply, maar ik heb de bovenstaande eval code geprobeerd maar ik krijg het niet werkend, doe ik hier iets fout?

document.getElementById(frame).innerHTML = o.responseText;
var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
while ((match = re.exec(document.getElementById(frame).innerHTML))) eval(match[2]);

[ Voor 10% gewijzigd door Verwijderd op 29-06-2006 09:56 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Wat werkt er niet, want dit werkt prima:
HTML:
1
2
3
4
5
6
7
8
9
<div id="foo"></div>
<script type="text/javascript">

document.getElementById('foo').innerHTML = '<h1>foo!<\/h1><script type="text/javascript">alert(\'foo!\');<\/script>';

var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
while ((match = re.exec(document.getElementById('foo').innerHTML))) eval(match[2]);

</script>

?

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dat werkt inderdaad, alleen mijn script niet... Kan de javascript die included is in de orginele pagina niet meer aangeroepen worden door de code in die die eval of zo?

BTW Bij mij is de code in de eval dus een creatie van een object dat vervolgens zichtbaar moet worden gemaakt in een onclick. Bij het uitvoeren van die onclick krijg ik de foutmelding dat het object niet gedefinieerd is. Dus wellicht dat de js file voor het maken van dit object niet beschikbaar is?

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Ik heb al eerder gezegd dat deze methode niet optimaal is, maar heb je toevallig een praktisch concreet voorbeeld van wat je wilt bereiken en waar dit niet werkt?

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb een html pagina waarvan ik de inhoud van een div vul door een ajax request. De code die in de div komt te staan is:
code:
1
2
3
4
<script type="text/javascript">
    function test() { alert('foo'); }
</script>
<a href="#" onclick="test()">Test</a>


Ajax laadt de code er nu goed in alleen als ik op test click dan krijg ik de error te zien dat test niet gedefinieerd is.

Ik deze code heb ik in mijn ajax javascript verwerkt:
code:
1
2
3
        document.getElementById(frame).innerHTML = o.responseText;
        var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
        while ((match = re.exec(document.getElementById(frame).innerHTML))) eval(match[2]);

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

mmz, IE geeft de script-elements niet meer terug als je de innerHTML opvraagd. Dan is het dus zaak om de eval's uit te voeren op de responseText alvorens dat in de innerHTML te gooien:
JavaScript:
1
2
3
4
var responseText = '<script type="text/javascript">function test() { alert(\'foo\'); }<\/script><span onclick="test()">Test<\/span>';
var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
while ((match = re.exec(responseText))) eval(match[2]);
document.getElementById('foo').innerHTML = responseText;

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Werkt ook niet, maar ik test alles trouwens gewoon in firefox. Ik begrijp niet echt wat hier nu mis gaat...

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Verwijderd schreef op donderdag 29 juni 2006 @ 13:57:
Werkt ook niet, maar ik test alles trouwens gewoon in firefox. Ik begrijp niet echt wat hier nu mis gaat...
Mijn bovenstaande voorbeeld werkt hier prima in Ff 1.5.x :?

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dan zal het waarschijnlijk op de een of andere manier aan ajax liggen? Hier wordt er iets over geschreven, maar niet echt met een goeie oplossing: http://nerd.newburyportion.com/2005/08/ajaxian-limitation

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Ah inderdaad; als je mijn oplossing binnen een functie gebruikt zit je met een scope-issue.
Eerste oplossing die me te binnen schiet is deze:
in plaats van:
JavaScript:
1
2
3
function test()
{
}

dit doen:
JavaScript:
1
2
3
test = function()
{
}
(let op: zonder 'var'), maar ik kan vast wel wat niftigers bedenken :)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

de volgende 3 oplossingen werken in ieder geval in Firefox, maar niet in IE(7):
JavaScript:
1
2
3
window.eval(match[2]);
eval.call(window, match[2]);
setTimeout('eval(\''+match[2].replace(/'/g, '\\\'')+';\');', 10);

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

solved voor IE:
JavaScript:
1
2
3
4
if (window.execScript)
    window.execScript(match[2], 'javascript');
else
    setTimeout(match[2], 0);

:)

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Met test = function() kreeg ik het iig werkend in firefox, dat is iig al fijn. Nu nog verder kijken voor IE...

Maar in ieder geval bedankt voor alle hulp!

Ik ben nu hier aan het kijken, wellicht is hier de oplossing te vinden: http://nerd.newburyportion.com/2005/09/the-magic-eval

[ Voor 30% gewijzigd door Verwijderd op 29-06-2006 15:34 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Verwijderd schreef op donderdag 29 juni 2006 @ 15:26:
Met test = function() kreeg ik het iig werkend in firefox, dat is iig al fijn. Nu nog verder kijken voor IE...

Maar in ieder geval bedankt voor alle hulp!

Ik ben nu hier aan het kijken, wellicht is hier de oplossing te vinden: http://nerd.newburyportion.com/2005/09/the-magic-eval
Op basis daarvan kwam ik ook op mijn laatste oplossing ;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Resumerend:
zet dit ergens los in je script:
JavaScript:
1
2
3
4
5
6
7
if (!window.execScript)
{
    window.execScript = function(script)
    {
        setTimeout(script, 0);
    }
}

en doe vervolgens dan dit:
JavaScript:
1
2
3
4
    var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
    while ((match = re.exec(o.responseText))
        window.execScript(match[2], 'javascript');
    document.getElementById(frame).innerHTML = o.responseText;

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Weer een beetje late reply maar met nog een opmerking. De laatste code hier gepost werkt perfect, totdat ik met ingewikkeldere code begon te werken. Toen werkte vanalles niet meer in IE. Ik ben toen eens het hele if execScript verhaal weggelaten en gewoon setTimeout(script, 0); dus voor alle browsers gedaan.

Dit bleek te werken in IE en ook nog in firefox... Dus dan is de oplossing nog simpeler.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Verwijderd schreef op woensdag 05 juli 2006 @ 10:47:
[...]
Dit bleek te werken in IE ...
Mmz, in IE7 kreeg ik dat niet werkend; dat kan natuurlijk een bug zijn (logischerwijs zou het ook gewoon moeten werken), maar het is maar dat je het weet ;)

[ Voor 3% gewijzigd door crisp op 05-07-2006 12:35 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

crisp schreef op donderdag 29 juni 2006 @ 15:49:
Resumerend:
zet dit ergens los in je script:
JavaScript:
1
2
3
4
5
6
7
if (!window.execScript)
{
    window.execScript = function(script)
    {
        setTimeout(script, 0);
    }
}

en doe vervolgens dan dit:
JavaScript:
1
2
3
4
    var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
    while ((match = re.exec(o.responseText))
        window.execScript(match[2], 'javascript');
    document.getElementById(frame).innerHTML = o.responseText;
Er zit een kleine fout in het voorbeeld van de moderator. In de volgende code:

JavaScript:
1
2
3
 
    while ((match = re.exec(o.responseText)) 
 


Staat er een ( teveel na de while. Ik wou dit even verbeteren (leek me wel nuttig, ongeacht dat het een tijd na de laatste reactie in het topic was). De juiste code is dus:

JavaScript:
1
2
3
4
    var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
    while (match = re.exec(o.responseText))
        window.execScript(match[2], 'javascript');
    document.getElementById(frame).innerHTML = o.responseText;

[ Voor 52% gewijzigd door Verwijderd op 18-07-2007 16:31 ]


Acties:
  • 0 Henk 'm!

  • kunnen
  • Registratie: Februari 2004
  • Niet online
Mocht je gewoon een goed werkende optie willen, ga dan voor het Prototype library, deze heeft een ingebouwde functie die precies dit doet:

JavaScript:
1
new Ajax.Updater('container', "request.html", {evalScripts:true});

Acties:
  • 0 Henk 'm!

Verwijderd

Een library gebruiken voor 1 specifieke functionaliteit lijkt me weinig nuttig...

Meeste mensen hebben zelf al een uitgebreide library in het project waar ze mee bezig zijn, daarin een klein stukje functionaliteit verwerken is veel gemakkelijker.

Overigens, oude }:O

Laat die koe maar lekker rotten in de sloot

[ Voor 13% gewijzigd door Verwijderd op 19-07-2007 02:53 ]


Acties:
  • 0 Henk 'm!

  • WaarAnders
  • Registratie: Juni 2001
  • Laatst online: 20-07 21:31
krijgen we dan dit idee?
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function stateChanged() 
{ 
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
 { 
 if (!window.execScript)
{
    window.execScript = function(script)
    {
        setTimeout(script, 0);
    }
}
 var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
    while ((match = re.exec(o.responseText))
        window.execScript(match[2], 'javascript');
    document.getElementById(frame).innerHTML = o.responseText;
 } 
}

Acties:
  • 0 Henk 'm!

  • soulrider
  • Registratie: April 2005
  • Laatst online: 27-11-2017
heb je trouwens al gezocht hier op GoT ?
want dit is al een paar keer langs gekomen.

de oplossing die ik toen al gegeven had (en welke ook via google nog steeds vindbaar is)

http://www.activewidgets.com/javascript.forum.6114.43/dynamic-load-javascript-from-javascript.html

code:
1
2
3
4
5
var script = document.createElement('script'); 
    script.type = 'text/javascript'; 
    script.src = 'snip.js'; 
    document.getElementsByTagName('head')[0].appendChild(script);  
    getSomething();


maw: niet zomaar .innerhtml of .innertext van je script ding aanpassen
maar via de DOM element maken, text/source aanpassen ev. zelfs het type, en dan een append doen...
let er wel op dan wordt ie telkens toegevoegd. vervelend als je meerdere .js moet toevoegen aan je pagina.


je kan ev. ook al een lege <script>-tag aanmaken en dan met .js/ajax dat aanpassen

http://ajaxpatterns.org/On-Demand_Javascript geeft ook veel info
(1ste of 2de link als je bij google gaat kijken onder "ajax loading javascript")

offtopic:
ik maak er bv gebruik van in een menu waar de html via een ajax-request richting een .php wordt aangepast, en gelijk tijdig ook de bijhorende javascript wordt achterna geladen - voorbeeld op www.soulrider.be/iDTV/tv - en dan op die ok-knop rammen van de zapper die je zie - dit werkt in IE6, IE7 en FF - maar hier wordt de source verwezen naar een andere .js - soortgelijk kan je die script tag ook gaan vullen met info die je pas nadien gebruikt)

[ Voor 5% gewijzigd door soulrider op 20-07-2007 12:03 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Beetje oud topic, maar geen nut om hier vandaag weer een nieuwe over te openen.

Ik heb al een tijdje ajax werkend op mijn pagina, maar door fckeditor in een ajax pagina te hebben zitten kom ik een beetje in de knel met het vereiste om <script></script> op mijn opgevraagde pagina uit te voeren.

Ik heb om ajax op mijn site uit te voeren een compact ajaxscript gevonden die ik voor elke pagecall kan hergebruiken (geen zin om hele frameworks erachter te installeren)

dit script is op zich fantastisch maar moet het helaas standaard zonder de optie doen om <script> areas uit te voeren. Vandaar dat ik een beetje heb lopen mengen met bovenstaande code.

dit is het resultaat:

NB: dit is onderdeel van de gehele ajaxpage() functie dus het gedeelte waarin de GET/POST vars worden meegestuurd zitten in de gehele functie:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function loadpage(page_request, containerid){

if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1))

var re = /<script(\s[^>]*)?>([\s\S]*?)<\/script>/gi, match;
while ((match = re.exec(page_request.responseText)))
{
    if (window.ActiveXObject)
    {
    window.execScript(match[2], 'javascript');
    }
    else /* (window.XMLHttpRequest) */
    {
    window.eval(match[2]);
    }
}
document.getElementById(containerid).innerHTML=page_request.responseText

}


het script werkt op op zich perfect op elke browser.... maar toch krijg ik bij elke opgevraagde pagina een aantal keren een "re has no properties" error. Volgens de debugger gaat het dan specifiek om deze regel:

code:
1
while ((match = re.exec(page_request.responseText)))


Nu probeer ik te bedenken waarom die wel werkt terwijl hij geen property heeft, maar klaarblijkelijk heeft dat met de werking van de eval() of de execScript() functies te maken (of beiden).

Heeft iemand een idee hoe ik dit kan voorkomen?
Of heb ik de syntax net niet goed gebruikt?

P.S. voor de personen die geinteresseerd zijn in het complete originele ajaxpage script:
(heb m volgens mij aangepast om via post ipv get te sturen)
http://www.dynamicdrive.com/dynamicindex17/ajaxcontent.htm

voorbeeldgebruik van de bovengenoemde scripts:
code:
1
<input type="button" onclick="ajaxpage('bronpagina.php', 'doelcontainer', 'var1=foo&var2=bar'); loadobjs('extrascript.js, 'anderestijl.css');" />


(bij loadobjs mag je een maar ook meerdere bestanden toevoegen waarbij het niet uitmaakt of je alleen .js, .css of beiden gebruikt).

Acties:
  • 0 Henk 'm!

  • MrDummy
  • Registratie: April 2000
  • Laatst online: 25-07 12:00

MrDummy

Nog steeds gek op anime...

Andere JS script uitvoeren via javascript? Dat ken ik. Ik doe dat truc altijd met "alternatieve ajax".
Het werkt via engine.js als motor die andere php / html codes aanroept en vervolgens waarden teruggeeft aan andere JS code. En zo kan men zelfs doorgaan met verschillende JS codes hier en daar, automatisch opgebouwd met vooral php. Alternatieve Ajax maakt dat allemaal mogelijk waar normale Ajax lastiger te doen is. In feite zit in engine.js ook eval() code die andere JS codes uitvoert.

Pas op met eval(). Gebruik die niet zomaar in formulieren, dan loop je kans dat iemand JS code via inputvelden injecteert en vervolgens kan inbreken. Ik laat het zelf indirect via PHP lopen.

Alternatieve ajax heeft klein nadeel: het moet via url doorgegeven worden dus uitvoer.php?inhoud=blaat&werk=enable&opslag=yes dus dat kan kwetsbaar zijn.
Het voordeel is dat het geen nadelen kent van ajax http request.
Pagina: 1