I have searched through StackOverflow posts and various forums, but cannot find an answer. I have found answers for similar questions, but nothing breaks it down quite enough for me to understand. I understand a good deal of PHP and HTML, but am having difficulty with scripts.
How can I click on a link, get the href (or what do I need?), have it fade out the current content, find the content I'm trying to load (href or whatever in the link) and load it, then fade it in?
My previous problems with random bits of code I've tried:
While going from page to page if another link was clicked while loading, it would only partially fade the second page in.
Each link had to have it's own script to direct it there. Could never figure out how to make it get the href of the link clicked.
Examples were so complicated I couldn't modify them to what I needed exactly. I need to understand the process of it.
Something like:
$('.link').on('click', function(){
$('.content').fadeOut().load('/path/to/script', function() {
$(this).fadeIn();
});
});
The key to this to use a HTML page or PHP script which can return the content you want. You might want to retrieve the URL from another element or hard-code it into your script - your call. For more information about how load() works, visit jQuery's documentation.
I actually developed something just like this some time ago.
The trick (or a trick) is to wrap your page an an iframe, and on the parent window, have a div element that fades into view when a page is requested, and fades out when the page loads.
The parent window looks like this:
<!DOCTYPE html>
<html>
<head>
<title>< Page1 ></title>
<style>
html, body{
font-family:helvetica;
}
#fade, iframe {
position:absolute;
left:0px;
top:0px;
width:100%;
height:100%;
border-width:0px;
z-index:-1;
opacity:0;
color:#AAA;
background-color:#FFF;
-webkit-transition: opacity 300ms;
-moz-transition: opacity 300ms;
-o-transition: opacity 300ms;
}
iframe {
opacity:1;
z-index:1;
background-color:#FFF;
}
</style>
</head>
<body>
<div id="fade">
<h1>Loadin..</h1>
</div>
<iframe src="p1.html"></iframe>
<script>
var fade = document.getElementById("fade");
var iframe = document.getElementsByTagName("iframe")[0];
var t = null;
addEventListener("message", function(e) {
if(t!=null)clearTimeout(t);
fade.style.zIndex = "2";
t=setTimeout(function(){
fade.style.opacity = "1";
},0);
}, true);
iframe.addEventListener("load", function() {
if(t!=null)clearTimeout(t);
t=setTimeout(function(){
fade.style.opacity = "0";
},0);
document.title = iframe.contentWindow.document.title;
t=setTimeout(function(){
fade.style.zIndex = "-1";
},300);
}, true);
</script>
</body>
</html>
And the subpages would each have the following code:
<script>
function go() {
window.parent.postMessage("showLoadScreen", "*");
}
</script>
somepage.html
This code is a little different in that the fader doesn't pop up unless the requested resource is taking awhile to load. But, you get the idea.
Since the iframe only exists for visual purposes, it shouldn't cause any major problems. However, note that this code uses HTML5's postMessage API, and you may want to tweak it a bit.
Related
I'm very new to JavaScript and I'm trying to figure out a way to trigger a keyframe animation if the page is accessed via a link on a menu page.
The code I have come up with so far using document.referrer does not work:
var ref = document.referrer;
if (ref.includes("menu")) {
document.getElementById('symbol').style.animation=' 2s ease-in-out 0s 1 slideLogo';
}
What am I doing wrong? The script is located at the end of <body> and runs nicely when ref is changed to a statement containing the search word.
I'm currently only testing locally, could that be why?
Hard to say what is going wrong without seeing the rest of the code, but the following should work.
Save as landing.html
<style type="text/css">
#symbol {
width: 100px;
height: 100px;
background-color: red;
}
#keyframes slideLogo { from { margin-left: -20%; } to { margin-left: 100%; } }
</style>
<h1>Landing page</h1>
<div id="symbol"></div>
<script>
var ref = document.referrer;
console.log('referrer is', ref);
if (ref.includes("menu")) {
console.log('set the style.animation property');
document.getElementById('symbol').style.animation=' 2s ease-in-out 0s 1 slideLogo';
}
else {
console.log('DO NOT set the style.animation property');
}
</script>
Put a link to landing.html in a file called menu.html. And make sure you're accessing it via something like http://localhost/menu.html
Similarly, put a link to landing.html in a file that will not have "menu" anywhere in the url, e.g.http://localhost/something-else.html. This will not trigger the animation.
So if these 3 files are accessed by their filenames, then the link from http://localhost/menu.html will trigger the animation on http://localhost/landing.html
It's worth noting that your referrer test will look anywhere in the referrer url, so even partial matches like http://localhost/not-a-menu.html will trigger the animation. So you may want to make your test a little more specific if you're worried about this.
Also, for browser compatibility, I think at this point it is still a little safer to use indexOf instead of includes.
if(document.referrer.indexOf('menu') !== -1) { ... }
On ie if i do something like this:
var aOverlay = $('<div>');
aOverlay.addClass("modal_overlay");
aOverlay.prependTo(aAppendTo);
window.location.reload(false);
then the overlay is not show at all. but if i replace
window.location.reload(false);`
with
setTimeout(function(){window.location.reload(false);},300)
then it works. Why ?
It is a browser-specific quirk if changes before the reload get displayed or not. IE is trying to optimize page rendering by delaying page updates until all page updating has stopped.
Q: If the page is about to be discarded, should recent page updates be rendered?
A1: No! A new page is coming, so simply display that. (IE)
A2: Yes! The updates are what the user is going to be staring at while the new page is fetched from the server. (Chrome, Firefox, Opera, Safari)
The solution, as you found with setTimeout(...,300), is to delay for a short interval before reloading the page. This forces page updates to be rendered, so that they can be visible during the delay interval.
The delay can be shorter than 300ms. In fact, it can be 0 or omitted entirely. According to W3C standards, the interval is actually a minimum of 4ms.
This sample renders the overlay as a translucent gray layer over the entire page:
<?php sleep(1); /* simulate typical server delay */ ?>
<!DOCTYPE html><html><head>
<style>
.gray_overlay { position:fixed; top:0; left:0; height:100%; width:100%;
padding:0; margin: 0; z-index:999; background-color:#202020; opacity:0.4 }
button { display:block; margin:20px }
</style></head><body>
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
This is some text. Server takes 1s to respond.
<button onclick="v1()">Version 1: Show overlay then reload instantly.</button>
<button onclick="v2()">Version 2: Show overlay then reload in 0ms.</button>
<script>
var aAppendTo = $('body');
var aOverlay = $('<div>');
aOverlay.addClass("gray_overlay");
function v1() {
aOverlay.prependTo(aAppendTo);
window.location.reload();
}
function v2() {
aOverlay.prependTo(aAppendTo);
setTimeout(function(){window.location.reload();});
}
</script>
</body></html>
My site structure is more or less this:
HOME - PAGE1 - PAGE2 - PAGE3.
What I would realize is a site with transition like "a mobile app" between pages, where you click on a button then the new page slide in. Now I'm looking on how to realize that, if using AJAX (that load the page and slide it but I don't know AJAX) or use a plugin (but I can't find anything).
Another alternative is create a single page and then moving into that (would be great find a plugin to do that) but the pages are big so my site will became heavy.
Does anyone have an idea how help me?
Thanks guys!
ps: the site is developed ONLY for tablet and smartphones
there are many ways to implement what you wanted, below i will show you one of them. (example at the bottom of the answer)
you hide the content outside of the screen, and slide it when page loads:
HTML:
<div class="content_div">
<p class="title">HOME</p>
page 1
</div>
CSS:
body{
overflow:hidden;
}
.content_div {
box-shadow:0 0 10px;
border:10px solid black;
height:800px;
left:-1000px;
width:100%;
-webkit-animation:slide_in 800ms ease-out forwards;
position:absolute;
box-sizing:border-box;
}
.title{
font-size:50px;
text-align:center;
}
.nav{
margin-left:20px;
}
#-webkit-keyframes slide_in{
0% {
left:-1000px;
}
100% {
left:0px;
}
}
now when you click a link, you intercept the click using a custom handler, prevent the default redirection, execute a "slide out" animation and once the animation is done, you redirect manually:
the function inside .promise().done() will be executed as soon as all animations on the object are done:
$(function(){
$(".nav").on("click",function(ev){
ev.preventDefault();
$(".content_div").animate({
"margin-left":$(".content_div").width() +100
}).promise().done(function(){
window.location="http://jsfiddle.net/TheBanana/27o989vy/embedded/result/";
});
});
});
here is a Live Example
implement this on every page in your website, and you should have sliding transitions.
change the transitions if you would like a different animation.
NOTE: in jsfiddle it will be a bit messed up because it will open itself inside itself, but on your website it will work as needed.
UPDATE FOR AJAX:
if you would like to avoid the disappearing of pages while window relocates to a new page, you need to load the content from the new page dynamically instead of changing location.
you can do that using plain ajax, or you can use jQuery's ajax extension .load(), it does the same ajax behind the scenes:
$(".nav_waitforajax").on("click", function (ev) {
ev.preventDefault();
$(".content_div").animate({
"margin-left": $(".content_div").width() + 100
}).promise().done(function () {
$(".content_div").load("/three", function () {
$(".content_div").animate({
"margin-left": 0
});
});
});
});
Ajax Example
UPDATE 2: delegated handlers for dynamic content:
//monitors a `mouseover` event on every element inside `.content_div`
//which fits the selector of "*" (everything)
$(".content_div").on("mouseover","*",function(){
$(this).css({
"background":"red"
});
});
Delegates Example
I have a page where I want all my images to fade in once they have loaded, but separately, and I have it working fine using the following...
<style>
img.imgfade {display:none;}
</style>
<script>
$(document).ready(function() {
$('img.imgfade').load(function() {
$(this).fadeIn('slow');
});
});
</script>
The problem I have here, is after navigating away from the page, and then coming back again, the images are no longer there. This is probably because they are already stored in the browser cache, and so are already loaded before my javascript runs.
I've been researching this all afternoon, but can't find an alternative where the images load and fade in seperately. One method I found says to include an .each() function to the .load(). This each can check if an image is already complete and if so just manually call .load() but when I add it, the images don't even load the first time round.
<script>
$(document).ready(function() {
$('img.imgfade').load(function() {
$(this).fadeIn('slow');
});.each(function() {
if(this.complete) {
jQuery(this).load();
}
});
</script>
SOLVED: The question was solved below, so I am sharing my full code incase it helps anyone else. This will fade in your images one at a time as they load, and also will not be affected by the browser caching images when you return to the page.
<style>
img.imgfade {display:none;}
</style>
<script>
(function ($) {
$(document).ready(function() {
$('img.imgfade').load(function() {
$(this).fadeIn('slow');
})
.each(function() {
if(this.complete) {
jQuery(this).load();
}
});
})(jQuery);
</script>
});.each(function() {
try to remove the semicolon ; otherwise your code will raise a syntax error.
Remember to also add a }); for your each(function()... )
So the code becomes
...
})
.each(function() {
if(this.complete) {
jQuery(this).load();
}
});
You can make this happen with modern CSS3 transitions and a onload attribute like so:
<img src="http://www.hdwallpapersfan.com/wp-content/uploads/2013/10/mountain-4.jpg" onload="this.classList.add('show')">
img {
opacity: 0;
-webkit-transition: 1000ms opacity;
-moz-transition: 1000ms opacity;
-ms-transition: 1000ms opacity;
-0-transition: 1000ms opacity;
transition: 1000ms opacity;
}
img.show {
opacity: 1
}
Example
Granted, I used vanilla JS with this.classList which may not be suitable for you if you need older browser support
But you can always swap out for jQuery: $(this).addClass('show')
And here's an example using jQuery to perform the fade in:
<img src="http://www.hdwallpapersfan.com/wp-content/uploads/2013/10/mountain-4.jpg" onload="$(this).fadeIn(1000)">
img {
display: none;
}
Example
I'm using queryloader on my website (link). For some reason the main page appears during one second before queryloader does its job (progress bar to load images before showing the website).
I assume that this is due to the fact that the page is loaded before the queryloader script is loaded but don’t know how to fix this. For the moment the code is in the
$(document).ready as suggested on the queryloader2 website and I’m calling the script (located in js/scripts.js) in my head tags.
$(document).ready(function () {
$("body").queryLoader2();
$('.activity-title a').click(function() {
var region = $(this).attr('data-region');
$('.textzone:visible').fadeOut(2000, function () {
$('#' + region).fadeIn(2000);
});
return false;
});
});
Sorry to bring up an old thread, but just for anyone facing this problem, here's my fix..
i added an overlay div right after the Body tag opening
<div id="preloader"></div>
And added this CSS
#preloader {
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
background-color:#fff; /* change if the mask should have another color then white */
z-index:99; /* makes sure it stays on top */
}
and added the onLoadComplete: hidePreLoader to the QueryLoader options
Then on that function just hide the overlay once done.
function hidePreLoader() {
$("#preloader").hide();
}
That would be pretty much it, hope it helps someone out there :)