In a simple plugin for my wordpress site, I wrote code that sets up click events as follows:
$(document).ready(function() {
$("#myButton").click(function() {
//do stuff
});
});
This code works as expected when I load the relevant page directly. However, the way users are expected to access the page is through a link in the theme header. I am not really sure how page transitions in the theme work, but the end effect is that whenever a link is clicked, some animation happens, the page fades out, and the new page fades in. The problem is that $(document).ready() does not fire when the new page fades in, so the click handlers do not function.
How can I change the code so that the click handlers are registered at the time the new page fades in?
If it's necessary to see how the theme works, I am using the Bridge Theme. A demo version of the theme is available here.
UPDATE:
After playing with the theme page transitions a bit, I am suspecting that the theme is using ajax to get the new page content, fading out old page content, fading in new page content, then "artificially" modifying the url to show the new pages url.
If you bind your click event to the document it will apply to elements which are loaded or created after the document has loaded.
This can be done like so:
$(document).on('click', '#myButton', function() { /* ... */ });
you can use one of these methods:
The DOM way
window.onload = function() { // do stuff with the DOM }
The direct jQuery translation
$(document).ready(function() { // do stuff with the DOM });
The jQuery way
$(function() { // do stuff with the DOM });
Related
I have a very simple jQuery function
$('#bnAddDegree').click(function () {
alert("bnAddDegree Loaded");
});
I have broken my site into different pieces based upon what the user clicks. If they click on a tab in the menu to load a section I call a partial_html page and load the section into the center div. If I put the code above into the main page load it will not fire. If I add an external js file and load it when the page loads it will not fire, I think because the elements are not initialized yet. If I put it into an external js page that is loaded after the partial_html is loaded it will not fire. If I put it ON the partial_html page with a tag it DOES fire. If I put a simple javascript function
function testFile() {
alert("File Loaded");
}
In the places that the jQuery code will not fire it works fine.
Is there something special that I'm missing with jQuery?
When I load the javascrip file I use
$.getScript("js/biosketch.js")
And test it with the simple javascript file and it works fine but not the jQuery call.
You need to use delegated event handlers since you are modifying the DOM dynamically.
$(document).on('click', '#bnAddDegree', function () {
alert("bnAddDegree Loaded");
});
I am doing a phonegap app.
I have an index.html page with a sign-in button that redirects to the website app.
When sign-in button was clicked, I wanted to have a loading gif to show while the page
is being cached/pre-loaded and redirect to the page when its done.
I would appreciate a sample script code.
I'm not even sure you need to use any jQuery or Javascript unless you want to dynamically take care of many cases like this. You can look into HTML5 prefetch to preload and cache the next page after login. So in the head of your document add:
<link rel="prefetch" href="http://example-site/next_page_after_login.html" />
You can read more about this on David Walsh blog here, or read more on MDN prefetch MDN
I accomplished a similar task using <iframe> elements. My phonegap app needed to load (local) pages, possibly modifying them via jQuery. Using plain redirects (via window.location) caused loading artifacts for two reasons:
images appeared as they were being loaded
the page state before jQuery modifications momentarily flashed.
I solved this problem by loading the page in a non-visible <iframe>, and making the <iframe> visible only after it had loaded and modifications had been made via jQuery. I supposed there are various ways to do this, but I did it by "juggling" <iframe> elements via their z-index.
I have created an annotated fiddle that is slightly simpler and adds a loading spinner:
http://jsfiddle.net/Leftium/L2HdV/ (Hat tip to Umidbek for the spinner!):
jQuery(document).ready(function ($) {
$app = $('.app');
// Attach behavior to Login button.
$('.login').on('click', function () {
$app.addClass('loading');
// Create an <iframe>.
$iframe = $('<iframe>');
// Set url of <iframe> to desired redirect URL.
// Note: the URL must be in the same domain,
// or set special HTTP headers to allow rendering inside an <iframe>.
$iframe.attr({src: 'http://doc.jsfiddle.net/'});
// Add <iframe> we just created to DOM.
$iframe.appendTo($('body'));
// When <iframe> has been loaded, remove <div> containing login button
// and loading spinner to reveal <iframe>.
$iframe.load(function() {
$('.app').remove()
});
});
});
This is very simple example:
http://jsfiddle.net/umidbek_karimov/DQ2wn/
Use css classes to manipulate visibility of the loader div and switch between pages.
jQuery(document).ready(function ($) {
$app = $('.app'),
$pages = $('.page');
$('.login').on('click', function () {
$app.addClass('loading');
$pages.removeClass('active').filter('.page-2').addClass('active');
setTimeout(function () {
$app.removeClass('loading');
}, 500);
});
$('.logout').on('click', function () {
$app.addClass('loading');
$pages.removeClass('active').filter('.page-1').addClass('active');
setTimeout(function () {
$app.removeClass('loading');
}, 500);
});
$app.removeClass('loading');
});
But if you need more complicated solution it's better to use some js frameworks, Knockout.js + some js router, or more powerful Angular.JS
I am working on PJAX powered website.
Problem is that I want to create animated website, when we animate content out of the view and then animate new content into the view.
You can see example here: http://ventguru.infoaleja.lt/
As you can see there's initial animation and after you select anything from top menu everything just disappears and new content is animated in.
What I want to do is that after you click menu item new content is not shown until we animate out old content.
What kind of way to archieve this you could offer?
You can use PJAX callback events, more info at https://github.com/defunkt/jquery-pjax#events!
Example:
$("body").on("click", ".menu li a", function() {
$(document).on('pjax:end', function() {
// Here comes the fade out animation
$('#container').fade( function(){
//Callback after animation has finished
});
});
});
I found this nice jQuery preloader/progress bar, but I cannot get it to work as it is supposed to. The problem is that it first loads my page and after my whole page is loaded the 0%-100% bar displays quickly, after that it reloads my page again. So it does not show the progress bar BEFORE the page loads and it loads the page a second time as well.
Here is my implementation code:
<head>
<script src="js/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="js/jquery.queryloader2.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("body").queryLoader2();
});
</script>
</head>
<body>
My content...No other reference in here for the Jquery preloader
</body>
Thanks for any help in advance.
I could be very, very wrong here, but in my opinion:
The plugin is flawed.
You have some issue in your page that causes a redirect.
I have created a test fiddle and found out the following:
If there are no images on the page, then the plugin's private function completeImageLoading(); is never called because it is only bound to the image elements. When there are no images -> there's no binding -> no triggering -> nothing completes -> you stay with overlay 0% as demonstrated by the fiddle that is NOT RUN (jsfiddle doesn't see relative images when the page is not run).
The plugin doesn't take into consideration remote images. So if you declare them like so <img src="http://example.com/image.jpg"> - then it won't work because the plugin doesn't recognize them. In fact it is using $.ajax to load images which, obviously, generates a error when trying to access another domain.
The plugin doesn't reload the page (at least in Google Chrome)... check your console output while in the fiddle. It displays the message once per click on Run.
Suggestions:
Make sure you provide at least one relative or background image (though I haven't tested backgrounds...) for the plugin to work.
Show us more code. The fiddle demonstrates that the plugin does NOT cause page reload (at least in Chrome... are you using another browser?). It must be something you made that interferes here.
Specify some options for the plugin (behaves weird when there are none).
Edit regarding preloader
Regarding preloader... if displaying progress is not mandatory for you, then you can just use a window.onload trick. On DOM ready $(...) you create an opaque page overlay with a "Please wait..." message and some animation if you fancy it. Then you wait for window.onload event which "fires at the end of the document loading process... when all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading." When window.onload triggers, you just remove your overlay and voila - the page is ready!
Edit 2 regarding preloader
Actually, you don't even need $(...)... what the hell was I thinking? Just create your overlay (a simple div with a unique id) in your html, style it so that it fills the screen and give it a z-index:1337 CSS attribute so that it covers the entire page. Then, on window.onload:
window.onload = function () {
// Grab a reference to your overlay element:
var overlay = document.getElementById('myOverlay');
// Check if the overlay really exists
// and if it is really appended to the DOM,
// because if not - removeChild throws an error
if (overlay && overlay.parentNode && overlay.parentNode.nodeType === 1) {
// Remove overlay from DOM:
overlay.parentNode.removeChild(overlay);
// Now trash it to free some resources:
overlay = null;
}
};
Of course, it's not really a preloader, but simply an imitation.
Here's a working fiddle you can play with.
P.S. I personally don't appreciate preloaders, but that's just me...
Try out this(Remove the document.ready event and simply call this):-
<script type="text/javascript">
$("body").queryLoader2();
</script>
I currently have a page that is being resized through the use of javascript whenever the end-user resizes the window, so that scrolling is reduced or eliminated when not necessary. I have a loader.js jquery file which picks out .html documents to throw in to the content section of the page when the user selects an option from the left menu:
$("#response").load("home.html");
$("#home").click(function(){
// load home page on click
$("#response").load("home.html");
setTimeout("resizefunc()",500);
});
$("#about").click(function(){
// load about page on click
$("#response").load("about.html");
setTimeout("resizefunc()",500);
});
//etc
While these timeout functions work most of the time, they have the potential to fail if the page loads abnormally slow for any reason. I am using document.ElementId.scrollHeight to determine the height of each new page, but it seems to only detect the height after the changes have been correctly applied. If the javascript loads before the page content then the resize fails.
It seems that if I were using complete html documents for each page then the problem would be irrelevant. I could put an onLoad event in to the body of each one and have it resize there... But since the tag is only loaded once I'm somewhat at a loss. My current implementation "works", but I feel that there should be something more efficient.
Don't use onLoad, instead wrap your code in
$(window).load(function() {
// your code here
});
Also, instead of load() with just the filename as a parameter, use:
$('#response').load('file.html', function() {
resizefunc();
});
Along with "load" you could also use "resize" as one of the events. This would allow dynamic resizing.
$(window).resize(function() {
resizefunc()
});
function resizefunc()
{
// code to resize.
}
See: http://api.jquery.com/resize/