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?
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.