jQuery ajax laod script does not load

Hi all,

First post. Lurked for a bit while learning and thanks for all the indirect help.

I am having trouble with jumping into ajax.

My old application is all php and I was trying to switch it to ajax for the users who have javascript so there is less page refreshing but also to keep the links working for those who don’t or don’t want the change.

here is a test files I’ve been working with:

<html>
<head><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script></head>
<body>
	<div>
		<div id="content">
			<script type="text/javascript">
				$('h1').live('click', function(){ alert('I clicked H1');});
			</script>
			<h1>Can you see me now?</h1>
		</div>
	</div>
</body>
</html>

Loaded just like that everything works fine.

However, when loaded via ajax from this file:
(jQuery is loaded above this and this is all in <head>)



$(document).ready(function(){

	
$.ajax({
	url: thisurl,
	success: function(html){
		var stuff = $("#content", html);
		$("#main").empty();
		$("#main").append(stuff);	
		},
	error: function() {
		alert("AJAX ERROR");
		}
});

Everything is closed properly, etc. even if it doesn’t show here, this is just an excerpt

thisurl is a variable that pulls the href field from my hijax script.

so, for the ajax call, i just want the stuff in the content div, and not the whole page. If I take off the Content I get the whole page and all the javascript works. Like this, with the Content, the javascript doesn’t run and doesn’t appear to load into the DOM.

I hope that enough info. Any help would be appreciated as I’m sure I’ve tried all the stupid ideas I’ve had to fix this and none have worked. Thanks!

JQuery actually has an ajax function capable of loading a page fragment. It’s called $.load, and you can see its use here: http://api.jquery.com/load/

If you’d like to be able to do this without using $.load, take a look at the jquery source to see how they’ve done it and implement it yourself.

I hope this helps!

thanks for the response. I am familiar with .load and used that first but it didn’t work and my example using .ajax does essentially the same thing as

$(‘#main’).load(thisurl + ’ Content’);

The problem is that when I select only the content div element, none of the included scripts work. If I load the whole page without that restriction, everything works but I get a bunch of crap that I don’t need in ajax from the head and such. I would only need that stuff if someone were to visit the page without javascript, which happens a lot as I have a lot of people on blackberries with either no or crappy js support.

my knowledge of both js and javascript is pretty limited beyond simple things.

I tried doing a GetElementsByTagName(“script”) and then pass that into eval() but that didn’t work. Though it does seem as though I have to manually eval the scripts because when I check they are in the DOM (the whole page is loaded and then jquery takes out the div Content and puts it where it should be).

This whole thing really isn’t making much sense as I don’t understand why jQuery or browsers would not retrieve the scripts for an element but does so for the entire file? I searched the internet before posting and it does seem to be a fairly common problem but I haven’t found any solutions.

Someone on another forum posted some prototype code:

  ScriptFragment: '<script[^>]*>([\\\\S\\\\s]*?)<\\/script>'

  extractScripts: function() {
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    });
  }

  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  }

that is supposed to work but I can’t figure out what it’s doing. Any ideas?

Here is a link to that post http://stackoverflow.com/questions/303026/using-jquery-load-breaks-links-to-other-library-resources

This too might help someone smart http://forum.jquery.com/topic/jquery-removing-script-tags-from-html-string-when-using-html

I’ve just gone and tested your code. The setup I have is this:

load.html


<html>
<head><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script></head>
<body>
    <div id="main">

    </div>
	<script language="javascript" type="text/javascript">
	$(document).ready(function(){
 
   
		$.ajax({
			url: 'ajax.html',
			success: function(html){
				var stuff = $("#content", html);
				$("#main").empty();
				$("#main").append(stuff);   
				},
			error: function() {
				alert("AJAX ERROR");
				}
		});
});
	</script>
</body>
</html>

ajax.html


<html>
<head><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script></head>
<body>
    <div>
        <div id="content">
            <script type="text/javascript">
                $('h1').live('click', function(){ alert('I clicked H1');});
            </script>
            <h1>Can you see me now?</h1>
        </div>
    </div>
</body>
</html>

And it seems to be working just fine, aside from the script you have inside Content. The element and the text are loading into the page fine for me though, so perhaps your error is elsewhere. Have you looked at your JS Error panel, or perhaps firebug?

If the script support is your main concern, is there a reason you need elements like that to load in JS that can’t just be placed on the page and used when necessary? $.live is meant to handle events on elements that have been dynamically created - not to run as dynamically created JS.

Right, the problems is that the script doesn’t work. Like if you click on “Can you see me now?” when after .ajax has run, you should get the alert. I don’t when I run that, using FF.

Just to be safe, if you load ajax.html on it’s own, you will get the alert when clicking on the text. When you load load.html, you will see the text, but if you click on it, you will not get the alert. That happens for you to? How to get that script to execute from load.html is the question.

Thanks!

Looking at that prototype code, it’s really not something you want to get into. eval is notorious for horrendous performance, but I’ll walk you through what it’s doing anyway:

ScriptFragment: '<script[^>]*>([\\\\S\\\\s]*?)<\\/script>' 
//This is creating a regular expression pattern that will detect scripts and get the code between their tags.
 
  extractScripts: function() {

    var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); 
// This makes a regex object with the pattern created earlier to make an array matching your scripts. The i flag makes it case insensitive, m makes it help recognize multiline scripts, and g makes it global so it will work with multiple scripts on the page.

    var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); 
//This does the same as the last function, except without the global flag, it will only match the first script.

    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    }); //This causes the regex objects to attempt their matches. If the global fails, it falls back to the non-global, and returns the script as an array.
  }
 
  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  }
//This function calls the extractScripts function and runs every script returned to it by using .map(), and returning eval'd scripts. Not a pretty sight.


If you want your H1 to fire an event after it’s been loaded, you should place the pertinent JS on the page you’re on and use .live or .delegate to enable it to handle events even when loading after the rest of the page.

To do this, you place this line inside your pages $(document).ready(), like so:

<html>
<head><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script></head>
<body>
    <div id="main">

    </div>
    <script language="javascript" type="text/javascript">
    $(document).ready(function(){
 
    $('h1').live('click', function(){ alert('I clicked H1');});
        $.ajax({
            url: 'ajax.html',
            success: function(html){
                var stuff = $("#content", html);
                $("#main").empty();
                $("#main").append(stuff);   
                },
            error: function() {
                alert("AJAX ERROR");
                }
        });
});
    </script>
</body>
</html>

This will make it so any H1’s on the page at load or created after load will fire this event when clicked.