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;
Related
In our team it is practice to keep all Javascript in their own .js files -> no Javascript in Views.
Certain events cause new divs to be loaded on the page (but the page itself does not get reloaded, nor do we go to a new URL). I want the Javascript code only to be executed when a certain div is loaded.
My current solution is to simply call within the view:
<script>
someJavascriptFunction(...);
</script>
What I want is something like
$(document).ready(function(){
$("#my-div").....
}
However, $(document).ready, only loads once. Same for
jQuery(window).on('load', function () {
//some function
});
which only seems to work when the URL actually changes.
Does somebody have an good idea on how to execute Javascript only when a certain div is currently loaded on the page/in the current view?
I haven't found a working solution yet...
Hopefully my question is clear - I'm new to Javascript!
If you are using default turoblinks:
$(document).on('turbolinks:load', function() {
$("#my-div").....
});
RoR turbolinks
I'm trying to create an html page that uses jquery to populate a table when the page loads. I have the function that gets the data, but currently for testing I just attached it to a button that I'm clicking to get the table to appear.
How do I get a jquery function to run when the page is loaded? In case it isn't obvious I'm a complete beginner when it comes to Jquery, so this may be something really obvious, but I've been trying to google it and I can't find a solution.
This should do the trick
jQuery(document).ready(myFunction);
function myFunction(){
// logic goes here
}
jQuery(document).ready(function(){
//some logic
newFunc();
//logic
});
function newFunc(){
//logic
}
However you can write code anywhere inside <script> tags and it will execute directly after including the jQuery file. But, the may not be as effective as above because at that time dom may or may not be created. So, better go the above way .. as it will only execute when page is loaded and DOM is created.
Are you looking for something like this. You can do this in regular JS.
document.addEventListener('DOMContentLoaded', function() {
console.log('document loaded');
});
But be aware this doesn't cover you from other dependent file loading like the js and png and others . They get loaded asynchronously . this just cover you for the dom content load
As the title says, if I remove a script tag from the DOM using:
$('#scriptid').remove();
Does the javascript itself remain in memory or is it cleaned?
Or... am I completely misunderstanding the way in which browsers treat javascript? Which is quite possible.
For those interested in my reason for asking see below:
I am moving some common javascript interactions from static script files into dynamically generated ones in PHP. Which are loaded on demand when a user requires them.
The reason for doing this is in order to move the logic serverside and and run a small script, returned from the server, clientside. Rather than have a large script which contains a huge amount of logic, clientside.
This is a similar approach to what facebook does...
Facebook talks frontend javascript
If we take a simple dialog for instance. Rather than generating the html in javascript, appending it to the dom, then using jqueryUI's dialog widget to load it, I am now doing the following.
Ajax request is made to dialog.php
Server generates html and javascript that is specific to this dialog then encodes them as JSON
JSON is returned to client.
HTML is appended to the <body> then once this is rendered, the javascript is also appended into the DOM.
The javascript is executed automatically upon insertion and the dynamic dialog opens up.
Doing this has reduced the amount of javasript on my page dramatically however I am concerned about clean up of the inserted javascript.
Obviously once the dialog has been closed it is removed from the DOM using jQuery:
$('#dialog').remove();
The javascript is appended with an ID and I also remove this from the DOM via the same method.
However, as stated above, does using jQuery's .remove() actually clean out the javascript from memory or does it simple remove the <script> element from the DOM?
If so, is there any way to clean this up?
No. Once a script is loaded, the objects and functions it defines are kept in memory. Removing a script element does not remove the objects it defines. This is in contrast to CSS files, where removing the element does remove the styles it defines. That's because the new styles can easily be reflowed. Can you imagine how hard it would be to work out what a script tag created and how to remove it?
EDIT: However, if you have a file that defines myFunction, then you add another script that redefines myFunction to something else, the new value will be kept. You can remove the old script tag if you want to keep the DOM clean, but that's all removing it does.
EDIT2: The only real way to "clean up" functions that I can think of is to have a JS file that basically calls delete window.myFunction for every possible object and function your other script files may define. For obvious reasons, this is a really bad idea.
If your scripts have already executed removing the DOM elements are not going to get rid of them. Go to any page with JavaScript, open up your preferred javascript console and type $("script").remove(). Everything keeps running.
And this demonstrates #Kolink answer:
http://jsfiddle.net/X2mk8/2/
HTML:
<div id="output"></div>
<script id="yourDynamicGeneratedScript">
function test(n) {
$output = $("#output")
$output.append("test " + n + "<br/>")
}
test(1);
</script>
Javascript:
$("script").remove();
// or $("#yourDynamicGeneratedScript").remove();
test(2);
test(3);
test(4);
function test(n) {
$output = $("#output")
$output.append("REDEFINED! " + n + "<br/>")
}
test(5);
test(6);
test(7);
I'm having a jQuery mobile page with JavaScript inside. The problem is the JavaScript doesn't work unless the page is refreshed. Here is my code:
jQuery(function($) {
var url = window.location.search.substring(1);
$('#mydiv').load('real_news.asp?' + url);
});
To understand this problem you need to understand how jQuery Mobile works.
Your first problem is point where you are trying to initialize JavaScript. From your previous answers I can see you are using several HTML/ASP pages and all of your javascript is initialized form the page <head>. This is the main problem. Only the first HTML file should have JavaScript placed into the <head> content. When jQuery Mobile loads other pages into the DOM it loads only the <div> with a data-role="page" attribute. Everything else, including <head>, will be discarded.
This is because currently loaded page has a <head> already. No point in loading another pages <head> content. This goes even further. If you have several pages in a second HTML file, only the first one is going to be loaded.
I will not try to invent warm water here so here are links to my other 2 answers discussing this problem. Several solutions can be found there:
Why I have to put all the script to index.html in jquery mobile (or in this blog article)
Link fails to work unless refreshing
There's more then enough information there to give you an idea what to do.
The basic solutions to this problem are:
Put all of your JavaScript into a first HTML/ASP file
Move your JavaScript into <body>; to be more precise, move it into a <div> with data-role="page". As I already pointed out, this is the only part of a page that is going to be loaded.
Use rel="external" when switching between pages because it will trigger a full page refresh. Basically, you jQuery mobile that the page will act as a normal web application.
As Archer pointed out, you should use page events to initialize your code. But let me tell you more about this problem. Unlike classic normal web pages, when working with jQuery Mobile, document ready will usually trigger before page is fully loaded/enhanced inside the DOM.
That is why page events were created. There are several of them, but if you want your code to execute only once (like in case of document ready) you should use the pageinit event. In any other case use pagebeforeshow or pageshow.
If you want to find out more about page events and why they should be used instead of document ready take a look at this article on my personal blog. Or find it here.
Your question isn't exactly overflowing with pointers and tips, so I'm going with the thing that immediately sprung to mind when I saw it.
Document ready does not fire on page change with jQuery Mobile, due to "hijax", their method of "ajaxifying" all the links. Try this instead...
$(document).on("pageshow", function() {
var url = window.location.search.substring(1);
$('#mydiv').load('real_news.asp?' + url);
});
Try pageinit like this
$(document).delegate("body", "pageinit", function() { // Use body or page wrapper id / class
var url = window.location.search.substring(1);
$('#mydiv').load('real_news.asp?' + url);
});
seems like nothing ever worked for me. Tried many different fixes, but i made the site too messy, that even position of certain javascript files wouldn't make the site work. Enough talk, here is what i came up with.
// write it in head at top of all javascripts
<script type="text/javascript">
$(document).ready(function() {
// stops ajax load thereby refreshing page
$("a,button,form").attr('data-ajax', 'false');
// encourages ajax load, hinders refresh page (in case if you want popup or dialogs to work.)
$("a[data-rel],a[data-dialog],a[data-transition]").attr('data-ajax', 'true');
});
</script>
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.