2

I am using JQuery .get method to retrieve some content from a webpage (page 1) and show it in a div in the main page. The problem is the content retrieved contains some javascript calls. The content is being displayed, but the Javascript methods are not getting executed. The .js file is being referenced across all the pages, so the availability of the js in the main is not a problem.

This is the code in the main page. URL of page 1 is given to the .get function:

$.get(url, function(response) {          
    var newContent = $(response).find("#right");      //Find the content section of the response
    var contentWrapper = $("#wrap");         //Find the content-wrapper where we are supposed to change the content.
    var oldContent = contentWrapper.find("#right");   //Find the old content which we should replace.

    oldContent.replaceWith(newContent);
});

This is the code in the #right (div) of Page 1

Some html tags...    
<p><script type="text/javascript">abc7();</script></p>
<p><script>s(30)</script></p>
Some html tags...

The functions abc7 and s are available in a .js (normal javascript file) that is being reference in the section of all pages

The s(30) should display a text field of size 30.

Ctroy
  • 577
  • 1
  • 10
  • 20
  • I found that this question is similar: http://stackoverflow.com/questions/4619668/executing-script-inside-div-retrieved-by-ajax However, the solution presented there doesn't serve my purpose. First, I am not sure what function would be called in the response from Page1. So, I cant call those scripts from my ajax. Is there a way out ? – Ctroy Nov 26 '11 at 14:43

2 Answers2

6

Inline JavaScript won't execute unless you run eval() on it. You can read more about that here:

An eval() solution could look something like this, but I would consider it bad practice:

$.get(url, function(response) {          
    var newContent = $(response).find("#right");      //Find the content section of the response
    var contentWrapper = $("#wrap");         //Find the content-wrapper where we are supposed to change the content.
    var oldContent = contentWrapper.find("#right");   //Find the old content which we should replace.

    oldContent.replaceWith(newContent);


    //Find all inline script tags in the new content and loop through them
    newContent.find("script").each(function() {
        var scriptContent = $(this).html(); //Grab the content of this tag
        eval(scriptContent); //Execute the content
    });
});

A better solution is to set a identifier/name on the #right tag and execute the code needed for that specific content.

Something like:

<div id="right" data-page-name="index">
    <!-- Content -->
</div>

<div id="right" data-page-name="about-us">
    <!-- Content -->
</div>

A simple solution that just passes the page name to a function that will execute the code depending on page would look something like this:

$.get(url, function(response) {          
    var newContent = $(response).find("#right");      //Find the content section of the response
    var contentWrapper = $("#wrap");         //Find the content-wrapper where we are supposed to change the content.
    var oldContent = contentWrapper.find("#right");   //Find the old content which we should replace.

    oldContent.replaceWith(newContent);

    var pageName = newContent.attr("data-page-name");

    pageSpecificActions(pageName);
});

function pageSpecificActions(pageName) {
    if (pageName == "index") {
        //Run the code for index page
    } else if (pageName == "about-us") {
        //Run the code for about us page.
    }   
};

This keeps the JavaScript code from being inline and doesn't use eval(). Even better would be to use events for when page content change, but this will be enough for now.

Community
  • 1
  • 1
Robin Andersson
  • 5,150
  • 3
  • 25
  • 44
  • I tried the first method (looping through script tags) and for some reason it didn't work. I just used an alert('test'); for testing purpose, but it didn't pop out the alert box. Would it be possible to test it in the sample code that you've set up earlier at http://pushstate.staticloud.com/index.htm. In my case, I am calling an javascript (not jquery) function that is in an external file included in both the pages. Thanks – Ctroy Nov 26 '11 at 16:49
  • When I tried newContent.find("script").each(function() {alert("here");}); I see no alert boxes, which seems that The response is not retrieving the script tags, However, when I tried to find("p"), I see multiple alert boxes... The page1 contains – Ctroy Nov 27 '11 at 05:07
  • It only looks for script tags inside the #right div, if you want to look at whole page1 you should do: response.find("script")... – Robin Andersson Nov 27 '11 at 08:26
  • Awesome answer. Those HTML5 data-attributes are sweet. – Aaron Gray Jun 29 '13 at 22:23
5

You can use .load() function instead of .get(). It automatically executes the scripts that are contained in the response.

Here is the documentation: .load()

ovunccetin
  • 8,443
  • 5
  • 42
  • 53
  • `load()` would append the contents of the response into the matched elements, not replace them, so it doesn't fully solve the problem. – Pawel Veselov Jul 01 '15 at 08:43