Synopsis:
The main idea behind this is to auto smooth scroll to the testimonials section of my html after a certain amount of time.
Achieved so far:
I'm able to scroll to the testimonials section of the page after X seconds without any problems using a simple script in my main index.html page. The script code is given below.
Auto scroll in the page after 5secs
<script>
setTimeout(function(){
window.location.hash = '#testimonials';
},5000);
</script>
Problem facing:
I've smooth scrolling in the entire page, but for the timer scrolling in my page, I'm unable to use smooth scroll. The uncertain transition is looking awkward, hence, I want to make it smooth scroll.
Also, I want this to happen only for the first time on page loading, i.e., if any operation is done in the page, this will not happen if visited index.html again.
TIA guys!
function goTo(selector, timeout, cb) {
var $el = $(selector);
if (!$el[0]) return;
var $par = $el.parent();
if ($par.is("body")) $par = $("html, body");
setTimeout(() => {
$par.stop().animate({scrollTop: $el.offset().top}, 1000, cb && cb.call($el[0]));
}, timeout || 0);
}
// USE LIKE:
goTo("#testimonials", 3000, function() {
// You can use `this` to reference #testimonials! yey
$(this).append("<br>Going to #contact in 3sec!");
goTo("#contact", 3000);
});
// Alternatively, without using callbacks you can do
// goTo("#testimonials", 3000);
// goTo("#contact", 6000);
// Reuse function for elements click!
$("[href^='#']").on("click", function(e) {
e.preventDefault();
goTo($(this).attr("href"));
});
/*QuickReset*/
*{margin:0;box-sizing:border-box;} html,body{height:100%;font:14px/1.4 sans-serif;}
article {
height: 150vh;
}
<article style="background:#0bf;" id="top">WELCOME (wait 3 sec)</article>
<article style="background:#f0b;" id="about">ABOUT</article>
<article style="background:#b0f;" id="work">OUR WORK</article>
<article style="background:#0fb;" id="testimonials">TESTIMONIALS</article>
<article style="background:#fb0;" id="contact">
CONTACT TO TOP
</article>
<script src="//code.jquery.com/jquery-3.1.0.js"></script>
Related
I am making a website with a splash screen that I want to make disappear after 3 seconds. I can successfully do it when I include jQuery, but this takes time to load (especially if it's not cached) and so the splash still displays for a small time.
I am also using cookies so that it will only show on the first load of the page (so it's not overly irritating).
Here's my HTML:
<div class="splash">
splash content
</div>
Here's the working jQuery (that I want to avoid):
if(document.cookie.indexOf("visited=true") === -1) {
$(".splash").delay(3000).queue(function(){
$(this).addClass("hidden").dequeue();
});
} else {
$(".splash").addClass("hidden");
}
Here's what I have come up with regarding javascript, but it doesn't work:
document.getElementsByClassName("splash").addEventListener("load",
function() {
if(document.cookie.indexOf("visited=true") === -1) {
setTimeout(function(){
this.classList.add("hidden");
}, 3000);
} else {
this.classList.add("hidden");
}
});
I don't think you want to add the function as the load event listener of the splash. You should add it to the load event of the page.
See comments inline for more details on reorganizing the code. Unfortunately, it won't work with cookies here in the Stack Overflow snippet environment.
Note that the splash is set to be hidden (via CSS) by default. This is a better practice than showing it by default and then hiding it. If, after reading the cookie, it is determined that the splash should not be shown, some users may wind up seeing the splash momentarily on their screens due to processing limitations, or worse if there is any kind of error in your code, the splash may wind up being shown and never taken away because the JS stops executing at the error.
// Get a reference to the splash dialog
var splash = document.querySelector(".splash");
// When the window is loaded....
window.addEventListener("load", function() {
// Check to see if the cookie indicates a first-time visit
if(document.cookie.indexOf("visited=true") === -1) {
// Reveal the splash (remember: splash is hidden by default by CSS)
splash.classList.remove("hidden");
// .5 seconds later, hide the splash
setTimeout(function(){
splash.classList.add("hidden");
// >> Set cookie to visited here <<
}, 500);
}
});
.splash {
height:200px;
width:200px;
background:yellow;
}
.hidden {
display:none;
}
<div class="splash hidden">S P L A S H !</div>
document.getElementsByClassName("splash").addEventListener("load", //not possible as ByClassName returns a collection not an element
function() {
if(document.cookie.indexOf("visited=true") === -1) {//why not simply !...
setTimeout(function(){
this.classList.add("hidden");//this is window as setTimeout is a window function...
}, 3000);
} else {
this.classList.add("hidden");//the only that work
}
});
The right way:
document.getElementsByClassName("splash").forEach(el=>{el.addEventListener("load",function() {
if(!document.cookie.indexOf("visited=true")) {
setTimeout(function(){
this.classList.add("hidden");
}.bind(this), 3000);//fix of context
} else {
this.classList.add("hidden");
}
})});
You can include this IIFE at the bottom of your page so that it will be executed when the splash DOM element is ready. This way you can avoid the event listener.
I also converted your splash to use the ID splash rather than a class. If you prefer the class, when you use document.getElementsByClassName("splash") it returns an array of elements. In that case you'll have to specify which elements of the returned array you want to use (i.e. document.getElementsByClassName("splash")[0] or iterate through them).
(function() {
var splash = document.getElementById("splash");
if (document.cookie.indexOf("visited=true") === -1) {
splash.classList.remove("hidden"); // Display the splash
setTimeout(function() {
splash.classList.add("hidden"); // Hide it after the timeout
}, 500);
}
})();
#splash { position: absolute; left: 0; right: 0; top: 0; bottom: 0; background: #ddd; }
.hidden { display: none; }
Not splashed!
<div id="splash" class="hidden">Splashed!</div>
I have a document with a bunch of sections that have information that I need to gather based on the URL anchor.
Example of what I'm trying to do:
URL
http://mywebsite.com/page.php#section-2
html
<div id='information'>Data should be here!</div>
<div id='section-1'>This is data from section 1!</div>
<div id='section-2'>This is data from section 2!</div>
<div id='section-3'>This is data from section 3!</div>
<div id='section-4'>This is data from section 4!</div>
CSS
div{
height: 500px;
}
jQuery
var hash = window.location.hash;
if(!hash == ""){
var data = $(hash).text();
$("#information").text(data);
}
But when I load the URL, The jQuery works fine, But the page jumps down to #section-2.
How do I stop this from happening?
Thanks in advance.
You condition is incorrect. It should be != instead.
if(hash != ""){
var data = $(hash).text();
$("#information").text(data);
}
And to prevent from jumping you can try using scrollTop().
$(document).ready(function(){
var hash = window.location.hash;
if(hash){
$('body').scrollTop(0);
}
});
div{
height: 500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id='information'>Data should be here!</div>
<div id='section-1'>This is data from section 1!</div>
<div id='section-2'>This is data from section 2!</div>
<div id='section-3'>This is data from section 3!</div>
<div id='section-4'>This is data from section 4!</div>
the browser will jump if there is a visible div with id = hash in the page. One way to prevent this is to set your divs display = none in the css so they are not visible during page load and then change them to visible immediately after
$(function() {
$('div').show();
});
Or perhaps you might only want to show one section at a time..
$(function() {
$('#section-2').show();
});
another way might be to leave the divs visible but immediately scroll back to top of page
$(function() {
self.scrollTo(0, 0);
});
I managed to find a way to fix it!
For some reason, The timing was messing it up and causing the $('body').scrollTop(0); not to work.
I was able to fix it by adding a 10 ms delay before scrolling to the top of the page.
$(document).ready(function(){
if(hash){
setTimeout( function(){
$('body').scrollTop(0);
}, 10 );
}
});
I managed to find a way to fix it!
For some reason, The timing was messing it up and causing the $('body').scrollTop(0); not to work.
I was able to fix it by adding a 10 ms delay before scrolling to the top of the page.
$(document).ready(function(){
if(hash){
setTimeout( function(){
$('body').scrollTop(0);
}, 10 );
}
});
I'm using jQuery to show / hide a div which happens to contain an iframe. It works great with just standard 'show' and 'hide' methods.
So now I want to get a little fancy and add some effects from jQuery UI (http://jqueryui.com/effect/) but suddenly my iframes are getting reloaded every time I show / hide them.
Here is a fiddle to demonstrate: http://jsfiddle.net/BnZzk/1/
And here is the code since SO is forcing me to add it:
<style>
div {
height: 200px
}
span {
display: block;
padding-bottom: 10px;
margin-bottom: 10px;
border-bottom: 1px solid black;
}
</style>
<div>
<iframe src="http://www.wikipedia.org/"></iframe>
</div>
<input type="button" value="Go"/>
<hr/>
<div id="msgs"></div>
<script>
$(function () {
var container = $('div'),
ifrm = $('iframe'),
msgs = $('#msgs')
delay = 10; //change me to adjust delay in seconds between actions
$('input').on('click', normal);
log('First let the iframe load and then clear your network console -- click the "Go" button to get started.');
function log (msg) {
msgs.append('<span>' + msg + '</span>');
}
function normal () {
ifrm.
hide(400, function () {
log('That was a standard hide with no effect -- is your network console still empty? OK we\'ll pause for ' + delay + ' seconds and then do a standard show.');
ifrm.
delay(delay * 1000).
show(400, function () {
log('That was a show with no effect -- is you network console *still* empty? Great! Let\'s try some effects.');
log('------------------------<br/>' +
'-- Begin Effects --<br/>' +
'------------------------<br/>');
withEffect();
});
}); //hide
} //normal
function withEffect () {
log('We\'ll pause for another ' + delay + ' seconds -- get ready to watch your network console.');
ifrm.
delay(delay * 1000).
hide('fold', {mode:'hide'}, 400, function () {
log('That was a hide with effect -- is your network console flooded? Mine too :-( We\'ll wait ' + delay + ' seconds while you clear your console again.');
ifrm.
delay(delay * 1000).
show('fold', {mode:'show'}, 400, function () {
log('That was a show with effect -- is your network console flooded again? Bummer ...');
});
}); //hide
} //withEffect
});
</<script>
Any idea how I can keep the fancy effects but not refresh the content of my iframes?
It's happening because this effect reorganizes the DOM, putting a DIV wrapper around the IFRAME, so when the IFRAME is "reappended" the reload happens! You can see this behavior using the Google Chrome elements inspector.
To solve I suggest you apply the effect in a parent DIV from your IFRAME but not using the effect plugin. Check out the http://api.jquery.com/animate/, manipulating the width and height style properties.
As #Jamillo Santos's answer, 'reappend' issues of iFrame.
if you are using dialog widget or its extension of jQueryUI and want to prevent this situation,
just redefine _moveToTop() function of your widget implementation as below.
_moveToTop: function() {
return null;
},
I want to only show the menu phrases "music, newsletter, contact" fixed at the bottom of the screen. On hover I want them to slide up and reveal hidden content. here's exactly what I mean:
http://sorendahljeppesen.dk/
See the bottom of the screen. Anyone know how this would be accomplished? Thank you.
P.S. also, would anyone know what type of MP3 player that is?
Put your hidden content into a div such as;
<div class="hiddenContent">...</div>
Then give your links at the bottom of the page a class such as;
Music
Then tell the Jquery to show the hidden content when you hover over the link;
$('.bottomLink').hover(
function () {
// Show hidden content IF it is not already showing
if($('.hiddenContent').css('display') == 'none') {
$('.hiddenContent').slideUp('slow');
}
},
function () {
// Do nothing when mouse leaves the link
$.noop(); // Do Nothing
}
);
// Close menu when mouse leaves Hidden Content
$('.hiddenContent').mouseleave(function () {
$('.hiddenContent').slideDown('slow');
});
Try this code:
ASPX section,
<div id="categories-menu" class="hover-menu">
<h2>Categories</h2>
<ul class="actions no-style" style="display: none">
<li>//Place your content here that should show up on mouse over</li>
</ul>
</div>
JQuery section,
<script type="text/javascript">
$(document).ready(function() {
function show() {
var menu = $(this);
menu.children(".actions").slideUp();
}
function hide() {
var menu = $(this);
menu.children(".actions").slideDown();
}
$(".hover-menu").hoverIntent({
sensitivity: 1, // number = sensitivity threshold (must be 1 or higher)
interval: 50, // number = milliseconds for onMouseOver polling interval
over: show, // function = onMouseOver callback (required)
timeout: 300, // number = milliseconds delay before onMouseOut
out: hide // function = onMouseOut callback (required)
});
});
</script>
Hope this helps...
I have found this great article with live demo and source code to download, the article show how to make a slide out menu from bottom.
THE SITUATION
I have a series of divs setup to contain various content:
<div id="main">
<div id="about"></div>
<div id="contact"></div>
<div id="flickr"></div>
<div id="twitter"></div>
</div>
I also have a nav which fades in and out specific divs from above (using either the animate or fade functions).
THE PROBLEM
I want to be able to check when all of the divs are hidden, when using the nav - so that i can trigger an event when all of the divs are hidden.
//Custom animation function.
jQuery.fn.fadeThenSlideToggle = function(speed, easing, callback) {
if (this.is(":hidden")) {
return this.slideDown({duration: 500, easing: "easeInOutCirc"}).animate({opacity: 1},700, "easeInOutCirc", callback);
} else {
return this.fadeTo(450, 0, "easeInOutCirc").slideUp({duration: 500, easing: "easeInOutCirc", complete: callback});
}
};
//example nav items.
$('#toggleContact').click(function() {
if (!$("#contact .tab").is(':animated')) {
$('#contact .tab').fadeThenSlideToggle(); //custom animation function
}
});
$('#toggleAbout').click(function() {
if (!$("#about .tab").is(':animated')) {
$('#about .tab').fadeThenSlideToggle();
}
});
//example check to see if all divs are hidden.
if((($(":hidden", '#main').length == 3) { //3 not 4 due to delay :S
}
However, this is proving to be difficult as the check is always one div out due to the delay on the fade function updating the div to hidden.
Is there any robust way to check if all divs are hidden? Initialising the check when clicking on an item in the nav and taking into account that each div takes a certain duration to actually set to hidden once the item has been clicked?
EDIT- I'd like a solution that includes the 'check for hidden divs', not just where i should put it.
You can attach an event to the completion of the fade:
$("#MyDiv").fade(100,function(){
DoSomething();
});
Add a callback function to your custom animation method, call this callback, if supplied, in the callback code for the animation to allow you to append some stuff to do after the animation is complete. I would depend on the state being what you expect once the animation is done.
$('#toggleContact').click(function() {
if (!$("#contact .tab").is(':animated')) {
$('#contact .tab').fadeThenSlideToggle( function() {
// since this is the callback, we assume that the animation
// has hidden all but one of the tabs
... more stuff to do after the animation is complete ...
});
}
});