Jquery novice to ninja questions

I’m working my way through Sitepoint’s jQuery novice to ninja book, and as a learning project am reworking a site I wrote many years ago using frames, Left frame was menu, right was content…

I’ve dumped the frames and made the menu into an accordion, made that sticky at the left top of my screen, and then used the ajax functions to pull content into a div on the right hand side, it all works well and I’ve learnt a lot in the process.

But… there are some problems I can’t seem to ‘fix’.

  1. When I click on a link and pull in the new content, I want the <title> in the <head> to change. I thought that since head and body are both siblings in the DOM I could target the <title> in the same way as a P or any other element and write a new value in which would then change the text in the tab at the top of the browser but it doesn’t seem to work. I even tried adding <title id=“title_text”> and targeting #title_text, but it doesn’t change that way either.


    $(document).ready(function() { $("a#menu_item_1").click(function () { $('#title_text').replaceWith("New title text for item 1"); }); });


    I thought the above would work, I’m trying to say ‘If the ‘a’ link with the id menu_item_1 is clicked, replace the the contents of id title_text with the new text’… But it doesn’t…?
    So question 1 is ‘can I manipulate items in the head in the same way as body, and will the browser reflect that change’?
    .
  2. Maintaining state… Having popped a new piece of content into the content div, via an ajax call, if I hit browser refresh, it doesn’t remember the current state, it resets the page content div to the original version before the DOM was manipulated, closes the accordion to it’s original state too… I don’t know where to start on fixing that.
    .
  3. Cache… If I notice that a piece of content inserted via an ajax call has a typo and correct it, I still see the first version on re-clicking the link, I have to clear cache for the ajax call to get the new revised version. Can I make the ajax call always request a fresh version, at least until I have finished development? In production where I’m just calling ‘finished’ static pages, then this would waste bandwidth, so I’d only want to do this for testing. One way is, I think, to ‘POST’ the link and add a ‘time of click’ time-stamp to the url each time so the browser thinks it is totally new page. Any other thoughts?
    .
  4. Bookmark. Finally, because there is no new page url, just DOM manipulation I can’t bookmark a particular set of content, just the home page. Again I can’t see away around that…

None of these points are covered in the book, so in a sense I’ve learned a lot, but been left at a point where I have good looking, new site, but despite all the bells and whistles don’t have one I’d feel happy putting into production.

Any ideas on any of these points would be much appreciated! (I’m using firefox btw)

Thanks!

  1. $('#title_text').replaceWith("New title text for item 1");


    That’ll just replace the DOM element with some text. You would need to try something like this:


    $('title').text('New title')


    You can use the HEAD just like any DOM element:


    javascript var h = document.getElementsByTagName('head'); var t = h[0].getElementsByTagName('title'); alert(t[0].firstChild.nodeValue); // alerts title


    I’d avoid giving the TITLE an ID. It just doesn’t seem right, as there can’t possibly be more than one. But this is a case where using the abstraction layer (jQuery) makes things more complicated. Just use this:


    javascript document.title = 'New title'
  2. To get the page to “remember” the state it was last in, you need to be able to identify the user somehow. This is done with cookies, one way or another. Sessions (like in PHP) depend on them and you can do it with javascript alone, with cookies. You would need to store a variable like “collapsed=1” in order to find out whether the user wants the accordion collapsed when they open the page.

    An alternative is the DOM Storage API, which IE8 started supporting, and Firefox has supported since version 2.5 I believe. You’ll have to look the level of support up yourself. It’s nice because it’s less messy than dealing with cookies, but the level of support is not universal and it can be turned off by the user, just like cookies can be turned off.
  3. I don’t see the point of coding this in. Perhaps you’re not aware that ctrl+refresh deletes the cache for that particular page only, which is perfect for development.
  4. You can set the hash in the URL with javascript. (#whatever). If you load the page with this in the URL, then you can serve up the content you want, either on the server side (as the request variables will contain this) or via Ajax after page load.

Raffles:

Thank you very much!

I’ve tried your solution to 1 and it works…:smiley:

<html>
<head>
<title>Orig title</title>
<script src="jquery-1.4.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" language="javascript">
   
   	$(document).ready(function() {
		$("a#menu_1").click(function () {
      		document.title = 'New title';
		});
	});

</script>
</head>
<body>
	<a id="menu_1" href="#">Click to change contents of the title.</a> 
</body>
</html>

BTW I had also tried using the Jquery replaceWith() just targeting the title (ie no id) and the title text in the page tab vanishes and is replaced with the url… Which is normal behaviour for a page that has no <title></title> in the head.

I also tried $(‘title’).after(‘New Title’).remove(); Same thing, title text in page tab was replaced with URL.

So it looks to me that jQuery may not just successfully remove the title contents but also the whole node itself, hence firefox then finds no title node and so places the url in the page tab… A jQuery oopsie I think?

  1. I need to read some more!

  2. “ctrl+refresh deletes the cache for that particular page only” Wow, thanks I didn’t know that, and it will come in very handy!

  3. Sorry, I still don’t see how to force the hash into the browser’s url space so it can be bookmarked, and once saved/opened how do I make the browser instantly make an ajax call to fill the content div with the content pointed to by that hash?.. If you have time I’d appreciate a few more pointers!

Thanks again,

replaceWith was replacing this:

<head>
  <title>the original title</title>
  <link href="...">
</head>

With this:

<head>
  The new title
  <link href="...">
</head>

Which is not only not allowed, but also entirely removed the <title>, causing it to be replaced with the default URI string.

About 4, visit the documentation. You can change window.location.hash and that will affect the URL. Play with it. :slight_smile:

  1. “ctrl+refresh deletes the cache for that particular page only” Wow, thanks I didn’t know that, and it will come in very handy!

Sadly this doesn’t work, or at least not as expected! If I click refresh (the pair of circular arrows) the page resets to the pre-dom manipulated page in the same tab, however if I hold down ctrl while clicking refresh, the same happens but the pre-dom page opens in a new browser tab, leaving an un-refreshed page in the original tab… so now I have two tabs , and, add a new one each time I do ctrl+refresh! (Firefox 3.5.8 under Ubuntu BTW.)

Later: A quick Google tells me to hit Ctrl+F5 which doesn’t open a new page in a new tab! So that works!

But it doesn’t clear the cache! I am using the ‘Clear Cache’ Firefox add-on which does clear all the cache.

(For some reason the forum software isn’t producing an edit post button even though I’m logged in… Hence the new post…)

It only lets you edit things up to 30 minutes after posting.

Hmm, yes, it’s ctrl+F5 but apparently if you click the refresh button, it’s shift+click. I didn’t know that.

This is called a “hard refresh” and should force the browser to download fresh copies of the HTML, CSS, images and JavaScript, but it doesn’t clear cookies. Are you using sessions or anything of the sort? I don’t see why your server shouldn’t be delivering a fresh copy anyway, and the browser should not be caching the results of Ajax requests.

Raffles wrote:

and the browser should not be caching the results of Ajax requests

Actually my 'Googling indicates that the browser will cache pages retrieved via ajax if GET is the method, but not is POST is used… (Go figure?)

jQuery uses GET, as apparently it should , again Googling turns up this from w3.org http://www.w3.org/2001/tag/doc/whenToUseGet.html which indicates that the use of GET is correct.

So, I request a page, notice a typo, change it, request it again and see the old cached page… The solution most folk recommend is to add a time stamp to the url each time it is requested, causing the browser to think it is a new page and thus request it again.

“+Date()” appended to the request URL works a treat.

Eric, co-author of ‘Ajax in action’ has blog page on this: http://radio.javaranch.com/pascarello/2005/10/21/1129908221072.html

jQuery Novice to Ninta, page 373 has some options for $.ajax, one is to disable browser caching set the cache option to false…

I tried that and yes, my browser is no longer caching pages. So while developing and constantly changing pages add:

 $.ajaxSetup ({  
       cache: false  
    });

So my ajax.js file looks like:

 $.ajaxSetup ({  
       cache: false  
    });

$(function() {
	$("a.ajax").click(function() {
	
		$("div#contents").empty().load($(this).attr('href'));
		return false;
	});
});

Then I’ll change false to true when in production. Or, even easier, check if pages are served from localhost and set to false, if from a host on the web set to true.

Since some pages will change, I’m adding a class to page links that call changing content, and targeting that class to add a time stamp to only those URLs.

I posted about this at jQuery forums and was told:

According to the documentation, replaceWith “allows us to remove content from the DOM and insert new content in its place with a single call”. Hence the replacement of the title element with your text. It is working as expected. What you want instead is the text() function:


   1. $(function() {
   2.       $('#menu_1').click(function() {
   3.             $('title').text('New title');
   4.       });
   5. });

It’s a learning curve!

A browser won’t necessarily cache a GET request.

The behavior can vary depending on the browser, the settings for that browser, and the http headers that the webserver produces, and some other factors. But, sending the right http headers is the most important thing. It expresses a recommendation to the client(the browser) of how it should determine the “freshness” of a document.

When the http headers only express a vague instruction of how the document should be treated, or no instruction at all, the browser needs to make some decisions on its own, and the behavior is more likely to be inconsistent between browsers.

Hi, first time poster on this forum here. I’m currently working my way through this book and have hit a snag. The animate example introduced on page 52 doesn’t seem to work in ie8 - it’s fine in Safari and FF but for some reason it will only animate the first ‘p’ element on my html page in ie8, not all of them as it should (and does in the other browsers).

//document ready opening argument
$(function(){
//animate
$('p').animate({
    padding: '30px',
    borderBottom: '3px solid #8f8f8f',
    borderRight:'3px solid #bfbfbf'    
}, 2000);
//closing argument of document ready function
  }); 

This is the code (everything after the //animate comment and before //closing argument etc is as it is printed in the book) Anybody any ideas? I checked the errata and amendments and nothing listed (though it does mention a bug with ie and css but I don’t think that is the issue) Has anybody else managed to make this work?

bump:)

What version of jQuery are you using?

1.4.2.min

You may want to revert to using 1.3.2 which is the version that the book uses.

Out of curiosity, what pages numbers of the book cover that section you’re dealing with?

I did try reverting when I spotted the problem and it made no difference. The code is on page 52 (I’m not using the downloadable html pages or even the downloadable scripts - I just created a simple html page with various elemts and implement the scripts onto that page as appropriate)

Thanks. I’ve tested this now too, and it looks like animating the border styles are causing the trouble on IE.

Message: Invalid argument.
Line: 137
Char: 354
Code: 0
URI: http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js

Ah, ok - that’s all I really needed to know, that it isn’t just me being a numpty and missing something obvious (it also misses the right border in ie8 I’ve just noticed)

Thanks for checking - any idea how I submit an error report to the errata page for the book?

I’m not sure. The errata for the book at http://www.sitepoint.com/books/jquery1/errata.php says:

If you think you’ve spotted an error or typo in your copy of jQuery: Novice to Ninja check to see if it’s listed below. If not, pat yourself on the back! We’d love to know about it so we can list it here for future readers.

I’ll see what I can find out about reporting it.

Hey - give yourself a pat on the back! :slight_smile: