jQuery templates in script tags disappear when loading partial HTML through AJAX
I have a problem with jQuery tmpl plugin.
Here is a test case for you to try (because of console.log it does not work on Internet Explorer without Firebug).
A file ajaxed_tpl.html:
<div id="some_inner">
<script id="my_tmlp" type="text/x-jquery-tmpl">
<li>
<img src="${imgSource}" alt="image" />
<h2> ${username} </h2>
</li>
</script>
<script type="text/javascript">
alert('I am here!');
</script>
</div>
<div> I don't need this through AJAX</div>
test.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.tmpl.js"></script>
</head>
<body>
<div id="response_cont"></div>
<script type="text/javascript">
$.ajax({
type: "GET",
url: "ajaxed_tpl.html",
cache: false,
success: function(data) {
// it is ok if I fill entire data into HTML
$("#response_cont").html(data);
console.log($("#my_tmlp").html());
}
});
</script>
</body>
</html>
This one loads fine - I get the alert and the template html() looks ok.
But I also get the "I don't need this through AJAX" line. So obviously I need to load just the inner part of div id="some_inner" but also I need to execute the Javascripts, so the only way to do it is to insert data into DOM before I get the some_inner div.
So let's modify test.html a bit:
success: function(data) {
// I need only the certain element with all the scripts and templates inside
var evaledHtml = $("<div>").html(data).find("#some_inner").html();
$("#response_cont").html(evaledHtml);
// at this point Javascripts got executed, I get that alert()
console.log($("#my_tmlp").html());
// but the template script is gone - console logs null!!!
}
Oh, man, where did the template go? Why Javascript in script tags got executed, but the template in script tags is gone?
But now let's modify the template in ajaxed_tpl.html:
<div id="my_tmlp" style="display:none;">
<li>
<img src="${imgSource}" alt="image" />
开发者_如何学Go <h2> ${username} </h2>
</li>
</div>
and run the test.html again. Yay! This time console.log outputs our template! It seems, if it is in div tags, it is not ripped out.
But there is a problem. If I put the template in div and not in script, the browser srews up my
<img src="${imgSource}" alt="image" />
so now it looks like:
<img src="$%7BimgSource%7D" alt="image">
Is there any way to load the template right (without browser encoding those ${} ) even if I load only part of data received through AJAX?
Why are those template script tags ripped out and who is doing that - browser or jQuery?
Note: below uses http://plugins.jquery.com/project/getAttributes
What this script does is filter out any script tags from your returned data for post processing. The script template tags have to be re-added in a certain way in order for them to be properly processed by tmpl. The other script tags are inserted after the html data has been added to work around any document.ready calls.
// remove any scripts from the data
var $data = $('<span />').append($(data).filter(':not(script)'));
// find the scripts so they can be added post element appended. this fixes document.ready bugs
var $scripts = $(data).filter('script');
// capture template scripts and add them as scripts
// bit of a ball ache but still does the job.
var $template_scripts = $scripts.filter('[type="text/x-jquery-tmpl"]');
$template_scripts.each(function()
{
var $script = $('<script />'),
attr = $.getAttributes($(this));
$script.attr(attr);
$data.append($script);
$script.text($(this).html());
});
// append the html
$("#response_cont").html($data);
// finally add the scripts after the html has been appended to work around any $(document).ready declarations in your scripts
$(document).append($scripts);
精彩评论