I'm using $.ajax()
to load new pages on my site if certain conditions are met (a flash-based radio player being active). However, I'd prefer not to modify the server-side output for this case.
Now I need a way to embed both the response on my page (that's easily done using .replaceWith()
) but also execute javascripts embedded on this page.
One thought I had was creating a dummy div like <div id="onload" data-onload="functionname" data-onload-args="json-for-the-function-args">
but maybe there's a better way that doesn't require changing my html code (i.e. a pure js/jquery solution).
Note that using $(elem).load()
is not possible as it does not evaluate any scripts if only a fragment of the retrieved document is used:
// inject the contents of the document in, removing the scripts
// to avoid any 'Permissio开发者_JS百科n Denied' errors in IE
I don't know any details about this IE problem but of course whatever code you are going to suggest should not cause errors in recent IE versions (I don't care about IE6).
Something along the lines of:
$('container').html(text_from_ajax_request);
$('container script').each(function(){
var $this = $(this);
src = $this.attr('src');
src ? $.getScript(src) : eval($(this).text());
});
Actually I solved it using a kind of dirty solution that works fine though:
I surround the actual content parts with comments that are not used anywhere else in my server-side template.
Then I fetch the whole content with dataType: 'text'
and use string functions to extract the interesting part (this is safe since I look for the first starting comment and the last ending comment, so the actual content cannot cause any problems even if it contains those comments for some reason).
After this I use .html()
to update my element. The important thing is that I do not create a DOM element from the retrieved html code since that would break the script tags.
Have you tried using load()? http://api.jquery.com/load/
I believe it should parse scripts and execute them for you.
EDIT:
Ok, either the bit about load() not being usable as is wasn't in the question or I didn't spot it. With that in mind I created a new version of load without the script stripping and it seems to work find in IE6,7,8, Chrome and Firefox... not really sure why the jQuery library does that:
<script type="text/javascript">
$(function() {
setTimeout(function() {
$('#target').load2('inject.html #inject');
}, 5000);
});
jQuery.fn.extend({
load2: function(url, params, callback) {
if (typeof url !== "string" && _load) {
return _load.apply(this, arguments);
// Don't do a request if no elements are being requested
} else if (!this.length) {
return this;
}
var off = url.indexOf(" ");
if (off >= 0) {
var selector = url.slice(off, url.length);
url = url.slice(0, off);
}
// Default to a GET request
var type = "GET";
// If the second parameter was provided
if (params) {
// If it's a function
if (jQuery.isFunction(params)) {
// We assume that it's the callback
callback = params;
params = undefined;
// Otherwise, build a param string
} else if (typeof params === "object") {
params = jQuery.param(params, jQuery.ajaxSettings.traditional);
type = "POST";
}
}
var self = this;
// Request the remote document
jQuery.ajax({
url: url,
type: type,
dataType: "html",
data: params,
// Complete callback (responseText is used internally)
complete: function(jqXHR, status, responseText) {
// Store the response as specified by the jqXHR object
responseText = jqXHR.responseText;
// If successful, inject the HTML into all the matched elements
if (jqXHR.isResolved()) {
// #4825: Get the actual response in case
// a dataFilter is present in ajaxSettings
jqXHR.done(function(r) {
responseText = r;
});
// See if a selector was specified
self.html(selector ?
// Create a dummy div to hold the results
jQuery("<div>")
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append(responseText/*.replace(rscript, "")*/)
// Locate the specified elements
.find(selector) :
// If not, just inject the full result
responseText);
}
if (callback) {
self.each(callback, [responseText, status, jqXHR]);
}
}
});
return this;
}
});
</script>
精彩评论