I'm trying to hide the .site-header on scroll and have it re-appear after inactivity for a couple of seconds.
I found the most of the answer here: How to hide a Div when the scroll bar is moving with jQuery?
var $header = $(".site-header");
var opacity = $header.css("opacity");
var scrollStopped;
var fadeInCallback = function () {
if (typeof scrollStopped != 'undefined') {
clearInterval(scrollStopped);
}
scrollStopped = setTimeout(function () {
$header.animate({ opacity: 1 }, "slow");
}, 500);
}
$(window).scroll(function () {
if (!$header.is(":animated") && opacity == 1) {
$header.animate({ opacity: 0 }, "slow", fadeInCallback);
} else {
fadeInCallback.call(this);
}
});
$('.menu-toggle').on('click', function(){
$('.menu-toggle').addClass('activated');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<section style="height:5000px;">
<div class="site-header" style="position:fixed; top:5px; left:5px; width:200px; height:100px; display:block; background:#000; opacity:1;">
<button class="menu-toggle">Menu</button>
<nav class="nav-primary">
<ul>
<li>Menu item 1</li>
<li>Menu item 2</li>
<li>Menu item 3</li>
</ul>
</nav>
</div>
</section>
The nav is activated by clicking button
However, the nav is nested inside the .site-header which means when the menu is activated it still fades out on scroll...
I'm wondering how to alter this javascript so that when the .activated class is applied to the button the nav remains visible even while scrolling.
Here is the fiddle https://jsfiddle.net/fwa16eok/
Thanks so much!
HTML:
<div>
<div class="a">A</div>
</div>
Javascript:
$(window).scroll(function() {
if ($(this).scrollTop() > 0) {
$('.a').fadeOut(); }
else {
$('.a').fadeIn();
}
});
Add !$menu.is(":active") before the fade out animation call
var $menu = $("#menu");
var opacity = $menu.css("opacity");
var scrollStopped;
var fadeInCallback = function () {
if (typeof scrollStopped != 'undefined') {
clearInterval(scrollStopped);
}
scrollStopped = setTimeout(function () {
$menu.animate({ opacity: 1 }, "slow");
}, 2000);
}
$(window).scroll(function () {
if (!$menu.is(":active") &&!$menu.is(":animated") && opacity == 1) {
$menu.animate({ opacity: 0 }, "slow", fadeInCallback);
} else {
fadeInCallback.call(this);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<section style="height:5000px;">
<div id="menu" style="position:fixed; top:5px; left:5px; width:200px; height:100px; display:block; background:#000; opacity:1;"></div>
</section>
Related
when i scroll the page, i want to add class active menu item.
i can get the current div id like this var currSection = $(this).attr('id'). im stuck with id and data-id matching.
here is the codes. ty for helping guys.
$(document).scroll(function() {
var cutoff = $(window).scrollTop();
$('div').each(function(){
if($(this).offset().top + $(this).height() > cutoff){
$('div').removeClass('current');
$(this).addClass('current');
var currSection = $(this).attr('id');
console.log(currSection);
if ($('.circle li').data('id') == currSection) {
};
return false;
}
});
});
ul{
position:fixed;
z-index:9;
top:0;
}
.active{
color:red;
}
div{
height:500px;
}
div:nth-child(odd){
background:green;
}
div:nth-child(even){
background:blue;
}
<div id="home"></div>
<div id="who"></div>
<div id="team"></div>
<div id="why"></div>
<div id="contact"></div>
<ul class="circle">
<li data-id="home" class="active">a</li>
<li data-id="who">b</li>
<li data-id="team">c</li>
<li data-id="why">d</li>
<li data-id="contact">f</li>
</ul>
Change scroll event listener to this
$(document).scroll(function () {
var cutoff = $(window).scrollTop();
$('div').each(function () {
if ($(this).offset().top + $(this).height() > cutoff) {
$('div').removeClass('current');
$(this).addClass('current');
var currSection = $(this).attr('id');
console.log(currSection);
$('li').removeClass('active');
$('li[data-id=' + currSection + ']').addClass('active');
return false;
}
});
});
I have a fixed div on the page which contains a logo and as the user scrolls and this logo passes over other divs I wnat to the change the colour of the logo.
I have this working over a single div but need to it work across multiple so any help appreciated.
The WIP site can be seen here... dd.mintfresh.co.uk - if you scroll down you'll (hopefully) see the logo change from black to white as it crosses an illustrated egg. I need the same to happen when it crosses other divs further down the page.
The script so far...
jQuery(window).scroll(function(){
var fixed = jQuery("logo");
var fixed_position = jQuery("#logo").offset().top;
var fixed_height = jQuery("#logo").height();
var toCross_position = jQuery("#egg").offset().top;
var toCross_height = jQuery("#egg").height();
if (fixed_position + fixed_height < toCross_position) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else if (fixed_position > toCross_position + toCross_height) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else {
jQuery("#logo img").css({filter : "invert(0%)"});
}
}
);
Any help appreciated. Thanks!
you need to fire a div scroll event. you can assign
$("div1").scroll(function(){
//change the color of the div1
}
});
$("div2").scroll(function(){
//change the color of the div2
}
});
or you can assign a class to divs which you want to change the color
$(".div").scroll(function(){
//change the color of the div which you are scrolling now
}
});
You can use like this :-
$(window).scroll(function() {
var that = $(this);
$('.section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('active')) {
$('.logo').addClass('invert');
} else {
$('.logo').removeClass('invert');
}
}
});
});
body {
padding: 0;
margin: 0;
}
div {
background: #f00;
height: 400px;
}
.logo {
position: fixed;
top: 0;
left: 0;
width: 100px;
}
.logo.invert {
filter: invert(100%);
}
div:nth-child(even) {
background: #ff0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://dd.mintfresh.co.uk/wp-content/uploads/2018/06/DD_logo.svg" class="logo" />
<div id="page1" class="section"></div>
<div id="page2" class="section active"></div>
<div id="page3" class="section"></div>
<div id="page4" class="section active"></div>
<div id="page5" class="section"></div>
As your site code you can do like this :
$(window).scroll(function() {
var that = $(this);
$('#content > section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('black')) {
$('#logo img').css({filter: 'invert(0%)'});
} else {
$('#logo img').css({filter: 'invert(100%)'});
}
}
});
});
I've just finished a creating a bare bones JavaScript tabs functionality for website. Right now I'm having a bit of problem trying to add directional functions in order to switch between tabs. Here is what I've created so far. I'm not sue on how I can increment or decrement the index in order to use the directional arrows to switch tabs and also the content
$(document).ready(function() {
$('.tabs-list li:first-child').addClass('active'),
$('.tab-content .show-content:first-child').addClass('active');
$('.tabs-list li').click(function(e) {
event.preventDefault();
if (!$(this).hasClass('active')) {
var tabIndex = $(this).index();
var nthChild = tabIndex + 1;
// select the right elements
var $tabsList = $(this).parent();
var $tabContent = $tabsList.next('.tab-content');
$tabsList.find('li.active').removeClass('active');
$(this).addClass('active');
$tabContent.find('.show-content').removeClass('active');
$tabContent.find('.show-content:nth-child(' + nthChild + ')').addClass('active');
}
})
$('.prev').on('click', function() {});
$('next').on('click', function() {});
})
.tabs-list li {
display: inline-block;
}
.tab-content .show-content {
display: none
}
.tab-content .show-content.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul class="tabs-list">
<li>Tab 1</li>
<li>Tab 2</li>
<li>Tab 3</li>
</ul>
<div class="tab-content">
<div class="show-content">
Content 1
</div>
<div class="show-content">
Content 2
</div>
<di>
Content 3
</di>
</div>
</div>
<ul>
<li class="prev">Prev</li>
<li class="next">Next</li>
</ul>
You can do it using jQuery .prev() and .next() methods. You just need to get the current .active tab and change it accordingly.
Here's the code you need:
$('.prev').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.prev('.tab-content .show-content')[0]) {
current.removeClass('active');
current.prev('.tab-content .show-content').addClass('active');
}
});
$('.next').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.next('.tab-content .show-content')[0]) {
current.removeClass('active');
current.next('.tab-content .show-content').addClass('active');
}
});
Demo:
This is a working Fiddle and a working Demo snippet:
$(document).ready(function() {
$('.tabs-list li:first-child').addClass('active'),
$('.tab-content .show-content:first-child').addClass('active');
$('.tabs-list li').click(function(e) {
event.preventDefault();
if (!$(this).hasClass('active')) {
var tabIndex = $(this).index();
var nthChild = tabIndex + 1;
// select the right elements
var $tabsList = $(this).parent();
var $tabContent = $tabsList.next('.tab-content');
$tabsList.find('li.active').removeClass('active');
$(this).addClass('active');
$tabContent.find('.show-content').removeClass('active');
$tabContent.find('.show-content:nth-child(' + nthChild + ')').addClass('active');
}
})
$('.prev').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.prev('.tab-content .show-content')[0]) {
current.removeClass('active');
current.prev('.tab-content .show-content').addClass('active');
}
});
$('.next').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.next('.tab-content .show-content')[0]) {
current.removeClass('active');
current.next('.tab-content .show-content').addClass('active');
}
});
})
.tabs-list li {
display: inline-block;
cursor: pointer;
}
.tab-content .show-content {
display: none
}
.tab-content .show-content.active {
display: block;
}
.as-console-row-code {
display: none;
}
.prev,
.next {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul class="tabs-list">
<li>Tab 1</li>
<li>Tab 2</li>
<li>Tab 3</li>
</ul>
<div class="tab-content">
<div class="show-content">
Content 1
</div>
<div class="show-content">
Content 2
</div>
<div class="show-content">
Content 3
</div>
</div>
</div>
<ul>
<li class="prev">Prev</li>
<li class="next">Next</li>
</ul>
Edit:
To make it loop in a cyclic way and doesn't stop in first or last elements, we should just implement that in the else block of our if statement, so it won't stop.
Here's how will be your code:
$('.prev').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.prev('.tab-content .show-content')[0]) {
current.removeClass('active');
current.prev('.tab-content .show-content').addClass('active');
} else {
current.removeClass('active');
$(".tab-content .show-content:last").addClass('active');
}
});
$('.next').on('click', function() {
var current = $('.tab-content .show-content.active');
if (current.next('.tab-content .show-content')[0]) {
current.removeClass('active');
current.next('.tab-content .show-content').addClass('active');
} else {
current.removeClass('active');
$(".tab-content .show-content:first").addClass('active');
}
});
And this is an updated Fiddle taking in consideration these changes.
My code looks like this:
<div id="arrow">
<a class="next"></a>
<a class="previous"></a>
</div>
<section id="first">
...
</section>
<section id="second">
...
</section>
<section id="third">
...
</section>
The element #arrow has position: fixed, and I'm trying to make the window scroll to the next section when a.next is clicked.
Ex: The first time a.next is clicked, the window scrolls to section#first, the second time, the window scrolls to section#second, etc. The same thing happens to a.previous.
Does someone know how to solve this problem?
Thanks a lot!
EDIT
My JS code:
$('#arrows a.previous').click(function() {
$.scrollTo($(this).closest('section').prev(),800);
});
$('#arrows a.next').click(function() {
$.scrollTo($(this).closest('section').next(),800);
});
You will need to handle to 3 events in this case:
Current page position - updated each time.
User scrolls manualy the page.
User clicks the prev or next button.
2, 3 need to use the current page position and update him according to the direction that the page is scrolling.
My quick demos : Vertical Version jsFiddle --- Horizontal Version jsFiddle
Vertical Version snippet :
$(function(){
var pagePositon = 0,
sectionsSeclector = 'section',
$scrollItems = $(sectionsSeclector),
offsetTolorence = 30,
pageMaxPosition = $scrollItems.length - 1;
//Map the sections:
$scrollItems.each(function(index,ele) { $(ele).attr("debog",index).data("pos",index); });
// Bind to scroll
$(window).bind('scroll',upPos);
//Move on click:
$('#arrow a').click(function(e){
if ($(this).hasClass('next') && pagePositon+1 <= pageMaxPosition) {
pagePositon++;
$('html, body').stop().animate({
scrollTop: $scrollItems.eq(pagePositon).offset().top
}, 300);
}
if ($(this).hasClass('previous') && pagePositon-1 >= 0) {
pagePositon--;
$('html, body').stop().animate({
scrollTop: $scrollItems.eq(pagePositon).offset().top
}, 300);
return false;
}
});
//Update position func:
function upPos(){
var fromTop = $(this).scrollTop();
var $cur = null;
$scrollItems.each(function(index,ele){
if ($(ele).offset().top < fromTop + offsetTolorence) $cur = $(ele);
});
if ($cur != null && pagePositon != $cur.data('pos')) {
pagePositon = $cur.data('pos');
}
}
});
section { min-height:800px; }
#arrow {
position:fixed;
right:0;
top:0;
background-color:black;
color:white;
}
#arrow a{
display:inline-block;
padding:10px 20px;
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="arrow">
<a class="next">next</a>
<a class="previous">prev</a>
</div>
<section style="background-color:green">...</section>
<section style="background-color:blue">...</section>
<section style="background-color:red">...</section>
All you need, to allow the user to use both arrows and scrollbar:
var $sec = $("section");
$(".prev, .next").click(function(){
var y = $sec.filter(function(i, el) {
return el.getBoundingClientRect().bottom > 0;
})[$(this).hasClass("next")?"next":"prev"]("section").offset().top;
$("html, body").stop().animate({scrollTop: y});
});
*{margin:0;padding:0;}
#arrow{
position:fixed;
width:100%;
text-align:center;
}
#arrow a{
display:inline-block;
background: tomato;
padding:6px 15px;
border-radius:3px;
cursor:pointer;
}
section{
height:1200px;
border:3px solid #444;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="arrow"><a class="prev">↑</a><a class="next">↓</a></div>
<section>1</section>
<section style="height:500px;">2</section>
<section>3</section>
<section style="height:600px;">4</section>
<section>5</section>
To explain the jQuery a bit:
// Cache your selectors
var $sec = $("section");
// On any of both arrows click
$(".prev, .next").click(function(){
// We need to get current element
// before defining the `.next()` or `.prev()` element to target
// and get it's `offset().top` into an `y` variable we'll animate to.
// A current element is always the one which bottom position
// (relative to the browser top) is higher than 0.
var y = $sec.filter(function(i, el) {
return el.getBoundingClientRect().bottom > 0;
})[$(this).hasClass("next")?"next":"prev"]("section").offset().top;
// (Line above:) if the clicked button className was `"next"`,
// target the the `.next("section")`, else target the `.prev("section")`
// and retrieve it's `.offset().top`
$("html, body").stop().animate({scrollTop: y});
});
i have tried to do with .closest("section") but it only works when the section is a parent of the element you clicked so this is the best way i got
sections=$("section");
s=0;
$(".next").click(function() {
if(s<sections.length-1){
s++;
$('html, body').animate({
scrollTop: sections.eq(s).offset().top
}, 500);
}});
$(".previous").click(function() {
if(s>0){
s--;
$('html, body').animate({
scrollTop: sections.eq(s).offset().top
}, 500);
}});
section{
background-color:#bbb;
width:100%;
height:700px;
border-bottom:2px solid #eee;
}
#arrow{
position:fixed;
}
#first{
background-color: red;
}
#second{
background-color:green;
}
#third{
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="arrow">
<a class="next">next</a>
<a class="previous">prev</a>
</div>
<section id="first">
...
</section>
<section id="second">
...
</section>
<section id="third">
...
</section>
I am working on an image slideshow, and the fadeOut() functionality working with every image change, but the next image appears abruptly. I want it to fade in. I can't seem to get it working.
Here is the code without any fadeIn():
HTML:
<div id="backgroundChanger">
<img class="active" src="background1.jpg"/>
<img src="background2.jpg"/>
<img src="background3.jpg"/>
CSS:
#backgroundChanger{
position:relative;
}
#backgroundChanger img{
position:absolute;
z-index:-3
}
#backgroundChanger img.active{
z-index:-1;
}
Javascript:
function cycleImages(){
var $active = $('#backgroundChanger .active');
var $next = ($active.next().length > 0) ? $active.next() : $('#backgroundChanger img:first');
$next.css('z-index',-2);
$active.fadeOut(1500,function(){
$active.css('z-index',-3).show().removeClass('active');
$next.css('z-index',-1).addClass('active');
});
}
$(document).ready(function(){
setInterval('cycleImages()', 7000);
})
I'd recommend something like this for your interval function:
window.setInterval(function (){
var images = $('#backgroundChanger img');
var active, next;
images.each(function(index, img) {
if($(img).hasClass('active')) {
active = index;
next = (index === images.length - 1) ? 0 : index + 1;
}
});
$(images[active]).fadeOut(1000, function() {
$(images[next]).fadeIn(1000);
});
$(images[next]).addClass('active');
$(images[active]).removeClass('active');
}, 3000);
And this is all you'd need for your css:
#backgroundChanger img:first-child {
display: block;
}
#backgroundChanger img {
display: none;
}
And keep the same HTML and you should be good to go!
You can fadeIn() the next image in the callback of fadeOut() as shown below:
$(window).load(function() {
var $slider = $("#backgroundChanger"),
$slides = $slider.find("img"),
$firstSlide = $slides.first();
function cycleImages() {
var $active = $('#backgroundChanger .active'),
$next = ($active.next().length > 0) ? $active.next() : $firstSlide;
$active.fadeOut(1000, function() {
$active.removeClass('active');
$next.fadeIn(1000).addClass('active');
});
}
setInterval(cycleImages, 3000);
})
#backgroundChanger img {
position: absolute;
width: 150px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="backgroundChanger">
<img class="active" src="http://i46.tinypic.com/2epim8j.jpg" />
<img src="http://i49.tinypic.com/28vepvr.jpg" />
<img src="http://i50.tinypic.com/f0ud01.jpg" />
</div>
Notes:
Since we're dealing with images, It's better to use load() handler than ready() to make sure the slide show starts after the images are loaded
You can slightly improve the performance by caching the elements accessed frequently
You don't have to play with z-index property at all since both fadeIn() and fadeOut() changes the elements `display property itself