问题
Page 1 has a Menu with id (#navigation), with a link called Page2 and DIV with id (global_content) that shows contents when the link Page2 is clicked. In the same page (Page 1) I wrote a jquery load function, so that when I click the link it should display the content without page reload. The load event works fine, the content is shown, but without the script tags that the Page 2 has.
This is the code in Page 1
<script>
jQuery(document).ready(function() {
//jQuery('#navigation li a').click(function(){
jQuery('#navigation li').on('click', 'a', function(){
var toLoad = jQuery(this).attr('href')+' #global_content';
jQuery('#global_content').fadeOut('fast',loadContent);
jQuery('#load').remove();
jQuery('#wrapper').append('<span id="load">LOADING...</span>');
jQuery('#load').fadeIn('normal');
function loadContent() {
jQuery('#global_content').load(toLoad, function() {
jQuery('#global_content').fadeIn('fast', hideLoader());
});
}
function showNewContent() {
jQuery('#global_content').show('normal',hideLoader());
}
function hideLoader() {
jQuery('#load').fadeOut('normal');
}
return false;
});
}); </script>
This is the code in Page 2
<div id="wall-feed-scripts">
<script type="text/javascript">
Wall.runonce.add(function () {
var feed = new Wall.Feed({
feed_uid: 'wall_91007',
enableComposer: 1,
url_wall: '/widget/index/name/wall.feed',
last_id: 38,
subject_guid: '',
fbpage_id: 0 });
feed.params = {"mode":"recent","list_id":0,"type":""};
feed.watcher = new Wall.UpdateHandler({
baseUrl: en4.core.baseUrl,
basePath: en4.core.basePath,
identity: 4,
delay: 30000,
last_id: 38,
subject_guid: '',
feed_uid: 'wall_91007'
});
try {
setTimeout(function () {
feed.watcher.start();
}, 1250);
} catch (e) {
}
});
</script>
</div>
<div class="wallFeed">
some content
</div>
But the output i get is
<div id="wall-feed-scripts"></div>
<div class="wallFeed">
some content
</div>
Can you help please?
回答1:
You can bypass the restrictions of jQuery.load stripping <script> tags by using jquery.ajax directly, which is the underlying method used for the shorthand methods load
, get
, post
etc..
We'll use jquery.html, which uses innerHTML
, to update the DOM.
var toLoad = this.href,
toLoadSelector = '#global_content';
...
function loadContent() {
jQuery.ajax({
url: toLoad,
success: function(data,status,jqXHR) {
data = jQuery(data).find( toLoadSelector );
jQuery('#global_content').html(data).fadeIn('fast', hideLoader());
}
});
}
As you see, we apply the selector toLoadSelector
('#global_content'
) on the reponse to only insert the desired portion of the page.
UPDATE
A better approach is to introduce some parameters to the loadContent
function so it is more easily reusable. Here's an updated (and tested) version:
<script>
jQuery(function($) {
$('#navigation li a').on('click', function() {
loadContent( '#global_content', this.href, '#global_content' );
return false;
});
function loadContent(target, url, selector) {
$(target).fadeOut('fast', function() {
showLoader();
$.ajax({
url: url,
success: function(data,status,jqXHR) {
$(target).html($(data).find(selector).addBack(selector).children())
.fadeIn('fast', hideLoader());
}
});
});
}
function showLoader() {
$('#load').remove();
$('#wrapper').append('<span id="load">LOADING...</span>').fadeIn('normal');
}
function hideLoader() {
$('#load').fadeOut('normal');
}
});
</script>
A few notes on the changes:
jQuery(function() { ... })
is the same as
jQuery(document).ready( function() { ... } )
Specifying function($)
makes jQuery
available as $
within the function, which saves some typing.
Now, regarding this expression:
$(data).find(selector).addBack(selector).children()
Unfortunately, $("<div id='foo'>").find('#foo')
does not return any results: only descendants are matched. This means that if Page2 has the #global_content
div directly under <body>
, it will not work. Adding addBack(selector) makes it possible to match the top-level element itself. See this so question for more details.
The .children()
makes sure that the <div id='global_content'>
tag from Page2 is not itself included, otherwise Page1 will have
<div id="global_content">
<div id="global_content">
which is technically illegal, since an id
must be unique in a document.
回答2:
I recently had a similar issue. As noted in the comments, jQuery ignores script tags when loading content via load()
. Someone mentioned you should use $.getScript()
but that won't work in strict mode because stuff loaded via getScript()
is loaded via eval()
and can't access the global scope. So getScript()
will break your javascript. The only way around it is to use vanilla javascript.
// $.getScript() uses eval() which makes it impossible to define functions in
// the global namespace in strict mode. Hence the closure thing here...
(function (callback) {
var script = document.createElement("script");
script.setAttribute("src", "./app/js/sequences/autoloader.php");
script.addEventListener('load', callback);
document.body.appendChild(script);
})(function () {
// Callback funtion here
});
来源:https://stackoverflow.com/questions/34268224/jquery-load-doesnt-load-script-tags-in-div