I was wondering if there is a way to execute script within a ajax dynamically loaded content.
I've searched the web and this forum also an find a lot of answers, like
[Running scripts in an ajax-loaded page fragment
[1]: Running scripts in an ajax-loaded page fragment [1]
But none of this seems to work fine for me.
I'm not experienced as the author of the quoted post, so maybe we can find a solution more simple and quite for everyone.
For now i've implemented a tricky turnaround that smell to much of an hard-coded solution that is:
//EXECUTE AJAX REQUEST LET'S SAY SUCCESSFULLY,
$ajax([..]) //THEN
.ajaxSuccess(function(){
// LOCATE ANY OBJECT PRE-MARKED WITH A SPECIFIC CLASS
$(".script_target").each(function()
{
//DO SOMETHING BASED ON A PRESET ATTRIBUTE OF THIS SPECIFIC ELEMENT
//EXAMPLE: <div class=".script_target" transition="drop_down">...</div>
//WILL FIRE A SCRIPT RELATED TO drop_down CASE.
});
});
I know this is an ugly solution but i didn't came up with nothing better than this.
Can you help to improve this method?
Maybe there's a way to let the browser fire script within the loaded page automatically?
PS. I'm not going to use the eval() method if it's not the last solution, cause both security leak and global slowdown, AND be aware that the script launched need to modify objects loaded in the same fragment of the script.
Thanks in advance.
If I understand you correctly :
you use "load" to retrieve html content from the server, and you add it to the page.
later, you do an ajax call, and on the return of the ajax call, you want to act on the markup you added earlier
but, depending on the markup retrieved, you want to do something different in the ajax callback
So another question : before you load the markup, do you know what logic will be behind it, or do you actually need to "read" the returned HTML to understand what it will be used for ?
Otherwise maybe something like this would work :
In the callback of the "$.load" function, use $.data() to attach more information to created dom object
In the ajax callback, you should be able to access the "added" markup (with a class like you did, or with an id if possible), and read to "data" to known which behavior you should have ?
Hopefully I got your problem right, it could help if you were able to create a jsfiddle or something, just to make sure we understand it.
Hoping this helps.
EDIT : After your comment, it might be related to the selector you use when calling $.load().
There is a "Script Execution" section in the $.load documentation : http://api.jquery.com/load/ , that explains that the scripts are not executed if you add a selector in the url, like this :
$('#b').load('article.html #target');
Could this be your issue ?
Also, if possible, you could try and change your site so that instead of having the js code of each "page" of the gallery inside the page, you put it inside a separate javascript file, that you load at runtime (for example with require js).
This way, "loading" a page would be something along the lines of :
$.load("url_of_a_page_markup.html", function () {
require(["url_of_the_javascript_module.js"], function (TheJsModuleForThePage) {
TheJsModuleForThePage.doSomething();
});
});
If you structure your JS modules in a consistent way, and you define a convention for the name of markup and js files, you can generalize things so that a "gallery" manager deals with all this code loading, and you'll end up with well isolated js modules for each page.
Hoping this helps.
If you want to run a script in a ajax loaded page fragment you can use try to use jQuery.load function.
Have you considered a module loader like require.js or Lab.js?
There are many other people asking similar questions:
does anyone knows good ajax script loader
Where are scripts loaded after an ajax call?
getting jQuery scripts and content through ajax dynamically
dynamic script loader in JS
Edit: I think I misread your question. Will try and come up with a better answer. Sorry!
Best of luck to you!
I came across this same issue when I dynamically loaded some HTML to use inside a JQuery UI dialog (a help function for my application).
$('#helpMessage')
.load('./help/' + helpFile, function () {...do stuff after loading});
To make things simple I wanted to combine the unique script related to the help page within the HTML fragment that I load. Using the examples on the JQuery UI page I created a dialog with a Jquery UI button element.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Button - Icons</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.9.1.js"></script>
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script>
(function() {
$('#myButton') // My button element
.button() // Initialize it as a JQuery UI button object
.click(function (){ // Hook up the button click event
$('#correct')[0].play(); // to play a sound in an <audio> tag
});
});
</script>
</head>
<body>
This is my help file, this is my code. This is for reading, this is for fun.
<button id="myButton">Button Text</button>
</body>
</html>
The dialog would load and the HTML displayed, but the embedded script did not execute.
I realized that one simple change would fix it. The script is embedded in an anonymous function (a best practice and part of the JQuery UI demo code). By immediately invoking the anonymous function the script executed when I loaded the HTML fragment into my main page.
This:
<script>
(function() {
...
});
</script>
Became:
<script>
(function() {
...
})(); // Immediately invoke
</script>
Niceness.
Related
I'm using a version of jquery-ui-widget, 1.10.3, that works well with ajax-loaded page fragment#1 but triggers an error with page fragment#2 if fragment#2 was loaded after fragment#1.
This is strange because even if I try and override 1.10.3 with 1.8.21 when ajax-loading fragment#2 (yes I realize this is a bad hack), the code that uses the widget factory still tries to use 1.10.3 and so causes an error.
Note that this is not a problem during normal page load as 1.8.21 is outside of my ajax div id="ajax_content" and so is loaded every time.
How can I override 1.10.3 during ajax?
<html>
<div id="ajax_content">
Page fragment #1 content
<script src="jquery-ui-widget.1.10.3.js"></script>
</div
<script src="jquery-ui-widget.1.8.21.js"></script>
</html>
VS.
<html>
<div id="ajax_content">
Page fragment #2 content
<script src="jquery-ui-widget.1.8.21.js"></script>
//having this script here or not has no effect if 1.10.3 was already loaded
</div>
<script src="jquery-ui-widget.1.8.21.js"></script>
</html>
version of jquery-ui-widget won't have an effect. Rather the cause of your problem is that the script added to the innerHTML of your div id="ajax_content" will not execute.
A script added dynamically (which maybe received as a response of an ajax request or that dynamically added to the innerHTML using js or jQuery) doesn't execute. Also it is not recommended as per #Kevin B's comment. I worked around the same problem by either of the two solutions below:
Load entire script initially
Load a new page with the script in the head tag
You may disagree with the second solution here saying that the question was about the script received as a ajax response while I am suggesting you to rework your approach and use a separate page instead. This may not be appropriate to do in your scenario due to various reasons but if the only reason preventing you from doing so is that this will cause code duplication then you may explore using something like jsp:include.
I've been developing in javascript for a few months and I have been using $(document).ready(function(){ at the beginning of all my scripts. I've noticed other folks don't use this in their scripts but I can't seem to get mine working without it. I'd like to keep my code cleaner, but for all my google searches I can't seem to figure out how to get rid of it.
I know it tells the browser to execute my script as soon as the page loads but is there something global I can set so that I don't need to explicitly tell the browser to execute each of my scripts when the page loads? Or is it a more global problem with where in my html files the scripts are located?
You're needing document.ready probably because you're interacting with the DOM before it loads. How can the script manipulate elements that are not there yet?
If you stick your script at the end of the file you will not need it. It's also good practice to do so for a lot of Javascript files as they can take time to process (especially if they're hosted externally). Putting them at the end of the file often speeds up the page load time.
All $(document).ready(function() { ... }); or $(function() { ... }); does is wait for the document to be ready for manipulation. You should use $(document).ready(function() { ... }); or $(function() { ... }); if your scripts are inline or in the <head /> section because JavaScript executes in the order in which it appears on the page otherwise.
To do away with $(document).ready(function() { ... }); or $(function() { ... });, simply move your scripts down to the bottom of the page after all of your content, right before the closing </body> tag.
Putting the scripts at the bottom is really a best practice anyway. For this and other best practices, I recommend you take a look at Html5Boilerplate and Yahoo! Best Practices.
the $(document).ready() convention is part of jQuery, not just JavaScript. From their' documentation on the ready function:
This is the first thing to learn about jQuery: If you want an event to work on your page, you should call it inside the $(document).ready() function. Everything inside it will load as soon as the DOM is loaded and before the page contents are loaded.
So yes, it is required. jQuery does come with a shorthand for this though, so you could do the following:
$(function() {
//jquery code
};
I have an external javascript that contains something like:
document.writeln("<script type='text/javascript' src='...'></script>");
In the original html i have something link
<div id="banner">
<script type="text/javscript" src="<the external javascript above>"></script>
</div>
How can i load that delayed?
I've tried using window.setTimeout and append that javascript but its not working.
Its important that the javascript to be loaded inside that div so the document.writeln executes in the right place.
Thank you.
You can call your injection code on window.onload.
window.onload = function() {
inject();
doSomethingElse();
};
window.onload will wait until all assets have finished downloading, such as images and scripts. After scripts are downloaded, you can inject your code to page.
Maybe a better way to do it would be to add a delay to the script.
Also, if you use something other than 'document.writeln' for example:
$('#banner').append(...);
you can better direct where it goes.
There is an open source javascript library for doing this kind of thing: http://labjs.com/
I have used it in the past and it worked very well.
Its important that the javascript to be loaded inside that div so the document.writeln executes in the right place.
That is not entirely true. Especially if the div is empty you could simply use: document.getElementById('banner').innerHTML = "<h1>HTML-Output here.</h1>"
Bukko's answer would work as well if you are using jQuery. My answer is pure Javascript. With this newfound freedom you should be able to simply put the loading of your script at the bottom of the page or use a custom body.onload() function
Edit: or simply follow Samet's suggestions in conjunction with the .innerHTML. Hope this helps.
I have no idea how to describe this accurately/intelligently because it seems to be completely impossible, yet there must some reason for it.
I am trying to leverage jquery, jquery-ui, qtip (tooltip for jquery) and highcharts (javascript charting), but for purpose of post I could just as easily been only using jQuery and jQuery-UI.
If I include my <script/> tags at the bottom of my <head/> element I get an error trying to call the .slider() extension to configure my sliders. But if I put the <script/> tags right before the closing of my <body/> element then everything works. To illustrate, the following will not work (obviously some pseudo code below):
<head>
<script jquery.js/>
<script jquery-ui.js/>
</head>
<body>
... html ...
<script type="text/javascript">
$(document).ready(function () {
$(".slider").slider( { .. options .. } );
} )
</script>
... more html *including* the .slider elements
</body>
However, if I move the two jQuery script tags to be right above the </body> closing element things work. When the script tags are in the head element and I debug my application, basically the page does appear to have completely loaded and Visual Studio highlights the line calling the .slider() function saying it doesn't know what slider() is. Looking at the call stack, it appears to be correctly calling it from the document ready function...the mark up all appears to be there as well, making me believe the document truly is ready.
Now I didn't include things that are required by asp.net 1.1/2.0 site in my pseudo code, namely a <form/> element with runat="server' and the use of a <asp:ScriptManager/> tag (we needed that for parsing monetary values from different cultures leveraging Microsoft Ajax). I can't believe they would be causing the problem, but maybe they are. Additionally, asp.net injects several of its own script sections (i.e. for validation, post back, etc.)
Regarding the form tag...all the html and document.ready markup would be inside the form tag, while the script tags are always outside of the form tag (either above it, in the head or below it at the bottom of the body).
Obviously I could leave the script tags at the bottom, and I very well may end up doing that, but I am trying to get a clean 'template site' of which to use when creating new client sites and it just feels wrong that I have a restriction forcing me to put those tags at the bottom of the html. I'm sure our framework code (or maybe asp.net's) is simply inserting something that is causing problems/conflicts with jQuery, but I don't really know how to go about debugging/diagnosing what that problem is. So if anyone has any suggestions I'd greatly appreciate it.
It looks like jQuery 1.3.2 is being loaded by ASP.NET (see your second WebResource.axd). The two library versions are overwriting each other. Thus the reason it works when you load 1.6.2 at the end of the page.
I have a simple html page
<a onclick="doSomething();">do something</a>
<script type="text/javascript">
function doSomething(){
alert("something");
}
</script>
I want to load this page using jquery ajax method , and append the result in a div.
Everything works great, but I want to be able to unload the html+javascript content.
For example if I empty the div where I loaded the html content, does this will unload the javascript functions as well. I know there is a Javascript garbage collector but since there is a refference of the function doSomething connected to the link, if I delete the link did I kill the reference automatically ??
The reason why I'm asking this is because I will have more complicated scripts connected to the loaded html, and I want to be sure that if I delete the html I will delete as well the memory allocated for javascript.
Also if you know a different implementation feel free to tell me.
Sorry for my bad english.
Thanks
if you use jQuery .load() method, the resulting scripts will tag along and be parsed.
to unload the dynamically loaded JS, you need to use your own namespace that you can then null out.
App = {} // master namespace
Then when you load a page
App.aboutPage = { ... } // your dynamically loaded namespace for the "About page"
When you're done
App.aboutPage = 0;