views:

211

answers:

3

I have a document with one CSS linked in. How can I replace the current CSS with one coming from a document that I just fetched with AJAX request using jQuery?

Here's the code I am trying right now, but with no success so far:

$(function() {
    $.get('next_page.html', function(data, textStatus) {
        $('link[rel=stylesheet]:first')
            .attr('href', $(data).find('link[rel=stylesheet]:first').attr('href'));
    });
});

Update: $.find() does not work in any browser (tested Firefox 3.5, Chrome and Safari 3 on Mac), but $.filter() found the stylesheet only in Firefox 3.5 - still nothing in Chrome and Safari 3.

It should be plain simple, right - replace the current CSS href with the new one, and voilá?

For some reason, jQuery fails to find anything inside the <head> tag that is coming from AJAX request. Furthermore, jQuery even fails to find the whole <head> itself from the AJAX data. In other words, $(data).find('head').size() inside the callback function returns 0.

I am using jQuery 1.4.


UPDATE Feb 10, 2010: I filed a bug about this to jQuery and they agreed it is not possible to find anything from the <head> tag from an ajax data. Here's the response I got:

http://dev.jquery.com/ticket/6061#comment:1 — "Yep, that's correct - parsing straight HTML we only guarantee the contents of the body element. If you wish to access the XML of the page directly then I recommend that you explicitly make the file .xhtml or request it as XML, for example:"

+1  A: 

Try this:

$.load('next_page.html', function(data) {
    $('link[rel=stylesheet]:first').replaceWith($(data).find('link[rel=stylesheet]:first'));
});

You were not actually making an AJAX call in your own example, perhaps that was the problem or you just forgot to add the .load part? This should work just fine, given that it is inside the $(document).ready(function() { ... }); block.

Tatu Ulmanen
sorry, I did forgot the .get part.. I edited my question so it's correct now.
Martin Tajur
still, this does not solve the problem because $(data).find('link[rel=stylesheet]') is not found
Martin Tajur
@Martin, what does your `data` look like?
Tatu Ulmanen
data is a full xhtml 1.0 transitional page
Martin Tajur
have you validated it? perhaps it's more transitional than you think
reinierpost
+2  A: 

This jquery should do it:

  $(document).ready(function() {
        $.get("next_page.html", function(data) {
            $("link[rel='stylesheet']").attr("href", $(data).filter("link[rel='stylesheet']").attr("href"));
        });
    });
ryanulit
I concur. That'll do the trick.
Andrew Dyster
This does not work either! :( Seems jQuery is failing to find the whole <head> tag from ajax data.
Martin Tajur
Update: $.filter() finds the stylesheet in Firefox (ver 3.5 on Mac), but does not work neither in Google Chrome nor Safari (on Mac). So it's unfortunately still not solved.
Martin Tajur
Ah, I only tested in IE and Firefox. Back to the drawing board...
ryanulit
It doesn't seem to be a problem with the response type. I tested that and it is text/html in IE, FF, and Chrome (don't have Safari to test). For some reason, the attr("href") after filter won't find the href attribute value. Is there a reason you use a different page to get the url for the new stylesheet? Why don't you just use a link on the page and take the url from there?
ryanulit
+1  A: 

This is valid as per jQuery dev team — "parsing straight HTML we only guarantee the contents of the body element. If you wish to access the XML of the page directly then I recommend that you explicitly make the file .xhtml or request it as XML, for example:"

$.ajax({ dataType: "xml", file: "some.html", success: function(data){ ... });
Martin Tajur