3

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?

4
  • 1
    This is by design, <scripts> are not loaded/executed. Commented Dec 14, 2015 at 13:26
  • You will want to use $.getScript() Commented Dec 14, 2015 at 13:27
  • @JayBlanchard, but getScripts() means i have to put the js script inside a file .js Commented Dec 14, 2015 at 13:39
  • So? What is the issue with that? You should separate your code as much as possible. Commented Dec 14, 2015 at 13:50

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

17 Comments

This code loads the header aswell. Is it possible to load only the #global_content contents?
Why should the OP "try this"? A good answer will always have an explanation of what was done and why it was done that way, not only for the OP but for future visitors to SO.
@Jay Where do you see "try this"?
@Alvin what do you mean, loads the header? This should replace the contents (innerHTML) of #global_content with whatever the toLoad url returns.
You haven't provided any explanation, so this is the equivalent of a "try this" answer.
|
1

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
});

1 Comment

Thank you for replying but it is not very clear to me how i should implement this code with my own code. Can you help me please?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.