Wat ervaringen met AJAX (jQuery)

Door ikbenmelle op maandag 5 december 2011 16:58 - Reacties (11)
Categorie: JavaScript, Views: 5.001

Afgelopen week ben ik bezig geweest met het moderniseren en verbeteren van een site. Zo ben ik onder andere om de gebruikerservaring te stroomlijnen AJAX (via jQuery 1.7.1) gaan implemeteren. Ik liep echter tegen wat eigennaardigheden aan van AJAX (met jQuery) wanneer je dit gebruikt in combinatie met nieuwe technieken.

Safari bug met .ajax() en .load() method
Om de een of andere reden werkt de .ajax() method niet altijd onder de PC- en MAC-versie van Safari (versie 5). Typisch genoeg komt deze bug pas voor sinds een recente versie.. Onder iOS (4 en 5) komt deze bug niet voor.

Het volgende stukje code levert onverwacht gedrag op van Safari:

JavaScript:
1
2
3
4
5
6
7
8
$.ajax(
{
    url: 'ajax.php',
    success: function(data)
    {
        alert(data);
    }
});


De alert zou "null" zeggen.

Gelukkig heb ik een workaround gevonden in jQuery door de .load() en .ready() method te gebruiken:

JavaScript:
1
2
3
4
5
6
7
8
9
10
$('.ajax')
.load( location_url, function()
{

    $(this).ready( function()
    {
        $('.content')
        .html( $('.ajax .content').html() );
    });
});


Wanneer je de .ready() method zo gebruikt, omzijl je het probleem en heb je het voordeel dat de content altijd al volledig geladen is (afbeeldingen, etc.).

Trouwens: het ".ajax" is een <div>-element met de volgende CSS properties:

Cascading Stylesheet:
1
2
3
4
5
6
.ajax
{
    position:absolute; overflow:hidden;
    top:-9999px; left:-9999px;
    width:1200px;
}

Internet Explorer 7 en 8 en hun cache
Internet Explorer 7 en 8 kunnen crashen als je AJAX frequent inlaadt zonder aan te geven in de JavaScript code dat de niet gecached mag worden.

JavaScript:
1
2
3
4
5
6
7
8
9
10
$.ajax(
{
    url: 'ajax.php',
    cache: false,
    success: function(data)
    {
        $('.result')
        .html(data);
    }
});

Internet Explorer 7 en 8 i.c.m. HTML5 elementen
Wanneer je HTML5 elementen (o.a. <header>, etc) wilt gebruiken in Internet Explorer 7 en 8, worden deze niet juist gerenderd, maar dit is eenvoudig op te lossen door gebruik te maken van een framework zoals Boilerplate of een stukje JavaScript toe te voegen:

JavaScript:
1
2
3
4
5
6
7
<script type="text/javascript">
    document.createElement('header');
    document.createElement('footer');
    document.createElement('nav');
    document.createElement('article');
    document.createElement('section');
</script>


Echter werkt dit stukje code niet voor de HTML5 elementen die via jQuery .load() method ge´njecteerd worden in de pagina met de method .html(output).

De HTML5-code wordt als plain tekst weergegeven op de volgende wijze: "<:nav:>inhoud<:/nav:>" terwijl de wel breed ondersteunde elementen erin (zoals <div>) wel juist worden gerenderd.

Zodoende heb ik een aantal HTML5-elementen moeten vervangen voor <div> elementen om dit juist werkend te krijgen.


Aldus een aantal bevindingen.

Volgende: De volgende stap met Eve /DEVBOEK 08-'15 De volgende stap met Eve /DEVBOEK
Volgende: Windows Live - You, Bing, Mail, Messenger en Skydrive 11-'11 Windows Live - You, Bing, Mail, Messenger en Skydrive

Reacties


Door Tweakers user ZpAz, maandag 5 december 2011 18:00

Geef je Json terug? Dan moet je namelijk in je ajax request meegeven dat je Json formaat verwacht. Anders krijg je inderdaad een null terug.

$.get('url', function(data)
{
//data is nu een object
}, 'json');

Door Tweakers user sfranken, maandag 5 december 2011 18:06

Bij jQuery ajax() moet je een type meegeven. Dit kan GET en POST zijn.
http://api.jquery.com/jQuery.ajax/

Door Tweakers user kipusoep, maandag 5 december 2011 18:48

Wat betreft "Zodoende heb ik een aantal HTML5-elementen moeten vervangen voor <div> elementen om dit juist werkend te krijgen.": http://www.modernizr.com/

Door Tweakers user Chris7, maandag 5 december 2011 19:52

Zelf gebruik ik het volgende script van Remy Sharp om HTML5-elementen in oudere IE-versies te gebruiken: http://html5shiv.googlecode.com/svn/trunk/html5.js
Ingebed in een conditional comment werkt dit voor mij prima. Eenvoudiger dan Modernizr, maar dan hoef je niet meer apart de [ document.createElement('header'); ] op te geven.

[Reactie gewijzigd op maandag 5 december 2011 19:52]


Door Tweakers user kaesve, maandag 5 december 2011 20:38

kipusoep schreef op maandag 05 december 2011 @ 18:48:
Wat betreft "Zodoende heb ik een aantal HTML5-elementen moeten vervangen voor <div> elementen om dit juist werkend te krijgen.": http://www.modernizr.com/
modernizer is natuurlijk superhip en zit daarom ook al in het genoemde boilerplate framework, maar er word in de blogpost ook genoemd dat deze methode blijkbaar niet werkt voor html5 tags die via jQuery worden geinjecteerd.

Door Tweakers user YopY, maandag 5 december 2011 20:42

Ik zou, als ik jou was, dit soort zaken eens als bugs bij jQuery melden - jQuery behoort immers cross-browser compatible te zijn. Als je voor specifieke browsers een workaround moet maken klopt er ˇf iets niet aan je code, ˇf aan jQuery (en dan is het een bug).

Sowieso kun je beter de $.get / $.post gebruiken dan de 'ruwe' $.ajax, zoals ook aangegeven wordt vergeet je de methode. En dan is het aan jQuery of de onderliggende browser om de juiste methode (get, post etc) te kiezen.

Door Tweakers user ikbenmelle, maandag 5 december 2011 22:03

Bedankt voor de reacties tot dusver. :)

@ZpAZ,
Er komt platte HTML terug, geen Json.

@sfranken,
Als ik me niet vergis is hoef je het "type" niet perse te definiŰren. Althans, dit staat niet in de documentatie van .ajax(). Mocht je "data" meezenden, dan gaat hij per default uit van de GET-methode.

Daarnaast, er wordt geen GET of POST gedaan. Maar als dit gedaan wordt, dan heb je dezelfde uitslag.

@kipusoep, kaesve,
Goed punt, ik zal het met Modernizr nogmaals aanzetten, had specifiek uit de code van Boilerplate gehaald. Wellicht dat Internet Explorer het dan juist interpreteerd.

@YopY,
Ben ik aan het overwegen, maar voordat ik het als bug ga submitten wil ik het uitvoeriger testen in verschillende contexten. Wellicht dat ik hier binnenkort de tijd voor neem.

Door Tweakers user Kwastie, maandag 5 december 2011 22:09

Hij detecteert het type aan de hand van content type, misschien is deze incorrect?

Door Tweakers user bdalenoord, dinsdag 6 december 2011 08:34

Welke methode gebruik je om de code in HTML5 naar de pagina te schrijven... als je dit doet middels bijv. een document.write zal inderdaad de code niet ge´nterpreteerd worden omdat dit pas gebeurt nadat de browser klaar is met het renderen...

Door MrAngry, dinsdag 6 december 2011 13:33

Ik heb met AJAX vooral slechte ervaring met het declareren van een besturingselement, het blijkt dat de ledenraad onvoorspelbaar m'n rechten intrekt en functies recalled.

Door Tweakers user ikbenmelle, dinsdag 6 december 2011 15:03

@Kwastie,
Goed punt. Ik zie zojuist dat in de .ajax() method by default een verwacht dataType (json, html, text, etc.) wordt gekozen. Wellicht dat hier iets mis gaat in Safari.

@bdalenoord,
Klopt, de code wordt pas ge´njecteerd nadat de pagina helemaal geladen is. De pagina wordt slechts eenmalig volledig geladen en vervolgens dynamisch meAJAX.

@MrAngry,
Mooie reactie, bij dezen een glimlacht van mijn zijde :)

Edit 15.03: overdadige hoeveelheid leeggelaten regels verwijderd.

[Reactie gewijzigd op dinsdag 6 december 2011 15:04]


Reageren is niet meer mogelijk