Nav background color changes upon scroll - javascript

I want part of my navigation background to change color to match the content color as the user scrolls down.
An exact example of this is available at blobfolio.com.
My attempt:
window.onscroll = function () {
var background = document.body.scrollTop < 200 ? '#fff' : 'red',
elems = document.getElementsByTagName('nav');
for (var i=0; i<elems.length; i++) {
elems[i].style.background = background;
}
}
I think that it will include for loops. I have tried in this JSFiddle but the entire background changes, which isn't what I want.
I am really quite stuck, any help would be much appreciated!
Also I am trying to do this in pure JavaScript - no frameworks.

I think this does what you're asking for:
window.onscroll = function () {
var i = 0;
var elements = document.getElementsByClassName("container");
for(var j=elements.length-1; j>0; j--)
{
if (parseInt(elements[j].getBoundingClientRect().top) <= 0)
{
i = j;
break;
}
}
var nav = document.getElementsByClassName("nav");
for (var j=0; j<nav.length; j++)
nav[j].style.backgroundColor = "";
nav[i].style.backgroundColor = window.getComputedStyle(elements[i]).getPropertyValue("background-color");
}
window.onscroll();
Here's a demo on JSFiddle.
Doing it in pure JavaScript was quite fun :D

You can try something like this
window.onscroll = function () {
var top=0;
var top=document.body.scrollTop;
if(top < 200){
$("a[href='#home']").parent().css("background-color","Green");
$("a[href='#home']").parent().siblings().css("background-color","");
}
if((top >= 200) && (top < 800)){
$("a[href='#Services']").parent().css("background-color","red");
$("a[href='#Services']").parent().siblings().css("background-color","");
}
}
JS Fiddle Demo
Sorry If you don't want to use Jquery. Here I am just giving you an idea to how to achieve that.

Give this a try. Working Demo
window.onscroll = function () {
var offset = Math.max(document.documentElement.scrollTop, document.body.scrollTop),,
lis = document.getElementsByTagName('li');
var colorMap = [
{ value: 200, color : 'green'} ,
{ value: 800, color : 'red' },
{ value: 2800, color: 'purple'}
];
var isColorSet = false;
for (var i=0; i<colorMap.length; i++) {
lis[i].style.background='black';
if (!isColorSet && offset < colorMap[i].value) {
lis[i].style.background = colorMap[i].color;
isColorSet = true;
}
}
}
Let me know if it works for you.
Please find Updated Demo Link here

Related

Setting data type value to an element when it reaches the top of the viewport

I have a hex colour value stored on each section and when a section reaches the top of the screen (-180px for the header) I want to assign a css property to the header element in order to change the text colour as you scroll through the sections. I am not getting any errors and I am having trouble debugging this issue.
http://www.amypreston.co.uk/
$(window).load(function() {
var $header = $("header");
var numberOfSections = $("section").length;
var sectionOffsets = [];
var sectionColour = $("section").eq(i).data("colour");
for(var i = 0; i < numberOfSections; i++) {
sectionOffsets.push($("section").eq(i).offset().top);
}
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
for(var i = 0; i < numberOfSections; i++) {
if(scrollTop > sectionOffsets[i] - 180) {
$header.css('color', 'sectionColour');
}
}
});
});
I dont know if it happened by accident, but the line
var sectionColour = $("section").eq(i).data("colour");
is out of place. it uses a variable i which is only defined in the window scroll handler.
notice that you need to retrieve the section color each time the scroll handler runs, and not only on window load. you need to place this line from above in the loop inside the scroll handler.
Plus, as stated on the comments, you need to use the sectionColour as a variable, and not as a string like you do now. the single quote marks must be removed, so 'sectionColour' turns into sectionColour.
here is your fixed code:
$(window).load(function() {
var $header = $("header");
var numberOfSections = $("section").length;
var sectionOffsets = [];
for(var i = 0; i < numberOfSections; i++) {
sectionOffsets.push($("section").eq(i).offset().top);
}
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
for(var i = 0; i < numberOfSections; i++) {
if(scrollTop > sectionOffsets[i] - 180) {
var sectionColour = $("section").eq(i).data("colour");
$header.css('color', sectionColour);
}
}
});
});
On a side note, you could shorten your code into this:
$(window).scroll(function () {
$("section").each(function () {
if ($(window).scrollTop() > $(this).offset().top - 180) {
$("header").css('color', $(this).data("colour"));
}
});
}).scroll();

get interval ID from else statement when set in IF

I am attempting to create a responsive slider, that will change to a simple set of dot points when in mobile mode (< 940).
The issue I am facing is in my else statement I am unable to clearintervals that were made in the if statement, because t comes up as undefined. I have resorted to using
for (var i = 1; i < 99999; i++) window.clearInterval(i); to clear the interval which works, but I don't like it because it's ugly and cumbersome, is there another way of accomplishing this?
$(document).ready(function() {
function rePosition() {
//get responsive width
var container_width = $('.container').width();
//Slider for desktops only
if(container_width >= 940) {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var n = 1;
var t = 0;
$('.slider_container').hover(function() {
clearInterval(t);
}, function() {
t = setInterval(sliderLoop,6000);
});
var marginSize = i = 1;
//Called in Doc Load
function sliderLoop(trans_speed) {
if (trans_speed) {
var trans_speed = trans_speed;
}
else
{
var trans_speed = 3000;
}
if (i < number_of_slides) {
marginSize = -(slide_width * i++);
}
else
{
marginSize = i = 1;
}
$('.slider').animate({ marginLeft: marginSize }, trans_speed);
}
t = setInterval(sliderLoop,6000);
$('.items li').hover(function() {
$('.slider').stop();
clearInterval(t);
var item_numb = $(this).index();
i = item_numb;
sliderLoop(500);
}, function() {
t = setInterval(sliderLoop,6000);
});
}
else
{
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
$('.slider').stop(true, true);
$('.slider').css('margin-left', '0px');
//rearrange content
if($('.slider .slide .slide_title').length < 1) {
$('.items ul li').each(function() {
var item_numb = $(this).index();
var content = $(this).text();
$('.slider .slide:eq(' + item_numb + ')').prepend('<div class="title slide_title">' + content + '</div>')
});
}
}
}
rePosition();
$(window).resize(function() {
rePosition();
});
});
Teemu's comment is correct. I'll expand on it. Make an array available to all of the relevant code (just remember that globals are bad).
$(document).ready(function() {
var myIntervalArray = [];
Now, whenever you create an interval you will need to reference later, do this:
var t = setInterval();//etc
myIntervalArray.push(t); //or just put the interval directly in.
Then to clear them, just loop the array and clear each interval.
for (var i=0; i<myIntervalArray.length; i++)
clearInterval(myIntervalArray[i]);
}
Umm, wouldn't t only be defined when the if part ran... as far as I can tell, this is going to run and be done... the scope will be destroyed. If you need to maintain the scope across calls, you'll need to move your var statements outside of reposition(), like so:
$(document).ready(function() {
var t = 0;
...
function rePosition() { ... }
});

Stop .animate() on last image

I'm trying to make a gallery of images to scroll using up/down buttons. So far I go the animation but now I need to make it stop on the first and last image.
This is what I got so far, jsfiddle.net/sJDMq/47 (don't mind the buttons, I still need to work on them but they are there, top and bottom red boxes)
Thanks!
$(document).ready(function() {
$(".down_button").click(function () {
$(".scroll-products").animate({marginTop: '-=700px'}, 300);
});
$(".up_button").click(function () {
$(".scroll-products").animate({ marginTop: '+=700px' }, 300);
});
});
I wouldn't have done it this way but just going with what you started with I would just let this JS do the trick:
$(document).ready(function(){
var curIndex = 0;
var height = 700;
var maxHeight = 0;
var allImages = document.getElementsByClassName("sidebar_images");
for(var i=0; i<allImages.length; i++) {
maxHeight += allImages[i].offsetHeight;
}
var maxIndex = Math.ceil(maxHeight/height);
$(".down_button").click(function () {
if(curIndex < maxIndex) {
$(".scroll-products").animate({marginTop: '-='+height+'px'}, 300);
curIndex++;
}
});
$(".up_button").click(function () {
if(curIndex > 0){
$(".scroll-products").animate({ marginTop: '+='+height+'px' }, 300);
curIndex--;
}
});
});
I just updated your fiddle here.

Changing background with sprite doesn't work

I've got this code for chaging a background image. I used setTimeout and everything but still it doesn't seem to work. Could anybody be kind enough and tell me what is possibly wrong?
var banner = document.getElementById("banner");
function changeBg () {
var i=0;
var images = ["0 235px", "0 0"];
while (true) {
setTimeout(function(){
banner.style.backgroundPosition = images[i]
},3000)
i++;
if (i>=images.length) {
i=0;
}
}
}
changeBg();
maybe that like this will work.
var banner = document.getElementById("banner");
function changeBg () {
var i=0;
var images = ["0 235px", "0 0"];
setInterval(3000,function(){banner.style.backgroundPosition = images[i];i++;if (i>=images.length) {
i=0;
} })
}
}changeBg();

jquery carousel evolution

I am trying to change an animation in jquery evolution carousel:
http://codecanyon.net/item/jquery-carousel-evolution/full_screen_preview/490018
As I have a lot of elements showing up in the slider I would like when clicking on the last one in the back to animate itself to the center without having all the other elements before it stepping and stopping through the center.
I am not good at jquery but I think it has something to do with these lines here:
for (var i = 0; i < n; i++){
animateImage(i);
}
};
var animateImage = function(i){
var o = settings,
item = slideItems.eq(i),
pos = slidePos(i);
item.show();
item.animate(setSlidePosition(pos), o.speed, 'linear', function(){
hideItem($(this));
if (i == numberSlides - 1){
isAnimationRunning = false ;
if (currentSlide != targetSlide){
animateSlide();
}
else {
self.current = currentSlide ;
showVideoOverlay(currentSlide);
o.after(self);
}
}
});
any help would be nice

Categories

Resources