i m new to JS and i m trying to create sticky video player like http://www.standard.co.uk/stayingin/tvfilm/jamestown-everything-you-need-to-know-about-the-sky1-drama-a3531796.html. When user scrolls up or down sticky class get added to video player. I have done some work https://jsfiddle.net/oLythd3f/ . but i want to also add function which check the bottom and once i scroll down i want sticky class to be added.
not sure how to do that. any help will be great. Be easy on me
var vid = document.querySelector('#main');
var topOfVid = vid.offsetTop;
function fixVid() {
if (window.scrollY >= topOfVid) {
document.body.style.paddingTop = vid.offsetHeight + 'px';
document.body.classList.add('fixed-vid');
} else {
document.body.classList.remove('fixed-vid');
document.body.style.paddingTop = 0;
}
}
window.addEventListener('scroll', fixVid);
Related
Im creating a navbar. The add javascript to it for two functions. One, the navbar will go invisible when the user scrolls down. Second, the invisible navbar will be visible again if the user reaches the end of the webpage or if they scroll up midway.I can't find the problem in my code, will be helpful if anyone can point it out for me
/ select the navbar element
var navbar = document.getElementById("navbar");
// set a variable to track the previous scroll position
var prevScrollpos = window.pageYOffset;
// listen for scroll events on the window
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
// check if the user has scrolled down
if (prevScrollpos > currentScrollPos) {
navbar.style.top = "0";
} else if (currentScrollPos + window.innerHeight >= document.body.offsetHeight) {
// check if the user has reached the bottom of the page
navbar.style.top = "0";
} else {
navbar.style.top = "-50px";
}
prevScrollpos = currentScrollPos;
};
The code you provided seems to be on the right track for creating a navbar with the functionality you described. The navbar element is selected, and the onscroll event is being used to track the user's scroll position and make the navbar visible or invisible based on that position.
The main issue I see is that you're using the navbar.style.top property to change the visibility of the navbar. It's better to use a class to change the visibility of the navbar, so you can add CSS styles to control the transition.
You can create a class like "navbar-invisible" and then add and remove the class to the navbar element to change its visibility.
// select the navbar element
var navbar = document.getElementById("navbar");
// set a variable to track the previous scroll position
var prevScrollpos = window.pageYOffset;
// listen for scroll events on the window
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
// check if the user has scrolled down
if (prevScrollpos > currentScrollPos) {
navbar.classList.remove("navbar-invisible");
} else if (currentScrollPos + window.innerHeight >= document.body.offsetHeight) {
// check if the user has reached the bottom of the page
navbar.classList.remove("navbar-invisible");
} else {
navbar.classList.add("navbar-invisible");
}
prevScrollpos = currentScrollPos;
};
.navbar-invisible {
top: -50px;
transition: top 0.3s ease-in-out;
}
It is important to test this code in different browsers, since browser compatibility can sometimes be an issue when working with JavaScript.
I want to add a class to an element as soon as the users' scroll-position has "hit" a special - other - element.
I try to use that code therefore
var hands = $(".sw_3--breit");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
// The next line is the one I am asking for help
if (scroll >= window.innerHeight)
{
hands.addClass("fixed");
} else {
hands.removeClass("fixed");
}
});
Which works nice by adding the class after the scroll is bigger then the users display-height I guess. But I want to add - and afterwards also remove - a class when then user has "hit" another element.
What I am asking for is something - very roughly and stupid I know - like:
var other_elements_position = $(".other_element"().position;
if (scroll >= other_elements_position)
How can I achieve that? And I already do use jquery for other things, so using jquery there would make sense I guess.
Thanks!
For people that got the same problem as I do have, this worked for me:
var hands = $(".sw_3--breit");
var hands_original = $(".sw_8").position();
var hands_off = $("#target_agentur").position();
var hands_corrected = (hands_original.top + 680) // here I add a small delay to the trigger of the "animation"
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll >= hands_corrected && scroll <= hands_off.top) // I doublecheck against 2 heights
{
hands.addClass("fixed");
} else {
hands.removeClass("fixed");
}
});
Context
I am working on a one-page website where the fixed navigation's class changes as it scrolls through the different sections in order to match the section's background color. To achieve this effect, I used and modified the 2nd solution listed here.
Issue
While it works great most of the time, the navigation code breaks when I resize the browser (or leave the page and click back). More specifically, the navigation's background color changes too early or too late and no longer matches the section's background.
I'm guessing that this happens because the section's height are calculated on page load. Ideally, they would be recalculated on every scroll - but I am a novice and that's just a guess. Any help to solve this issue would be appreciated.
JavaScript
FYI: there are four sections in the websites (Hero, Work, About, Contact). Navigation's bg color should be transparent in Hero, white in Work and Contact, and teal in About.
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
$(window).on('scroll', function() {
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Just try adding all your size variables into your scroll event handler:
$(window).on('scroll', function() {
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Now afterhero, afterwork and afterabout should all be recalculated on a page scroll.
The general idea to the site i am designing is to scroll through a set of menu items horizontally and incrementally underneath a static div that will magnify(increase dimensions and pt size) the contents of a menu items. I don't really need help with the magnify portion because i think it's as simple as adding a mag class to any of the menuItem divs that go underneath the static div. I have been messing with this for a few weeks and the code I have for incrementally scrolling, so far, is this:
$(document).ready(function () {
currentScrollPos = $('#scrollableDiv').scrollTop(120); //sets default scroll pos
/*The incrementScroll function is passed arguments currentScrollPos and UserScroll which are variables that i have initiated earlier in the program, and then initiates a for loop.
-The first statement sets up the variables: nextScrollPos as equal to the currentScrollPos(which by default is 120px) plus 240px(the distance to next menuItem), prevScrollPos as equal to the currentScrollPos(which by default is 120px) minus 240px(the distance to next menuItem).
-The second Statement checks to see if the user has scrolled using var userScroll
-The third statement sets: var CurrentScroll equal to the new scroll position and var userScroll to false*/
function incrementScroll(currentScrollPos, userScroll) {
for (var nextScrollPos = parseInt(currentScrollPos + 240, 10),
prevScrollPos = parseInt(currentScrollPos - 240, 10); //end first statement
userScroll == 'true'; console.log('dude'), //end second statement and begining of third
currentScrollPos = scrollTop(), userScroll = 'false') {
if (scrollTop() < currentScrollPos) {
$('#scrollableDiv').animate({
scrollTop: (parseInt(prevScrollPos, 10))
}, 200);
console.log('scrolln up')
} else if (scrollTop() > currentScrollPos) {
$('#scrollableDiv').animate({
scrollTop: (parseInt(nextScrollPos, 10))
}, 200);
console.log('scrolln down')//fire when
}
}
}
$('#scrollableDiv').scroll(function () {
userScroll = 'true';
_.debounce(incrementScroll, 200); //controls the amount of times the incrementScroll function is called
console.log('straight scrolln')
});
});
I have found a variety of solutions that are nigh close: such as a plugin that snaps to the next or previous div horizontally demo, another solution that also snaps and is based on setTimeout demo, but nothing that nails incrementally scrolling through divs. I also found a way to control the rate at which a user may scroll through the menuItems using debounce which is included in the above code.
The console.logs inside the loop do not fire when I demo the code in jsfiddle which leads me to believe the problem lies within the loop. I'm a noob though so it could be in syntax or anywhere else in the code for that matter. Also in the second demo, i have provided the css for the horizontal static div, but the moment I put it in my html it keeps the js from working.
I would like to write the code instead of using a plugin and any help would be appreciated! Also, thank you ahead of time!
Try this fiddle. Menu container height is 960px to show 4 menu items. "Zoom" div is positioned absolutely at top. When you scroll mouse over this div, menu items shifts to top/bottom. I had to add additional div to bottom to be able to scroll to last 3 menu items. JS code:
jQuery(document).ready(function($){
var current = 0;
var menu = $('.menu-container').scrollTop(0);
var items = menu.find('.menu-item');
var zoom = $('.zoom');
function isVerticalScroll(event){
var e = event.originalEvent;
if (e.axis && e.axis === e.HORIZONTAL_AXIS)
return false;
if (e.wheelDeltaX)
return false;
return true;
}
function handleMouseScroll(event){
if(isVerticalScroll(event)){
var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail;
current += (delta > 0 ? 1 : -1);
if(current < 0)
current = 0;
if(current >= items.length){
current = items.length - 1;
}
menu.stop().animate({
"scrollTop": current * 240
}, 300);
items.removeClass('current').eq(current).addClass('current');
event && event.preventDefault();
return false;
}
}
zoom.on({
"MozMousePixelScroll": handleMouseScroll,
"mousewheel": handleMouseScroll
});
});
Hope it will help.
I have a div section on my .ASPX form. The section just contains a load of links (standard
document.getElementById('Side1').style.display = 'none';
This worked great but was a bit abrupt for what I wanted, so I wrote the little routine below (with a little help from the internet) but although the DIV dection shrinks, and the content below scrolls up .. the links in the div section don't move, until the div section is made invisible .... is there a way round this, or am i going about this all wrong (ps my javascript is rubbish)
var originalSize =0;
var i = 0;
var ts;
function shrink() {
if (i != 28) {
document.getElementById('Side1').style.height = parseInt(document.getElementById('Side1').style.height) - 5 + 'px';
i++;
ts = setTimeout("shrink()", 10);
}
else {
document.getElementById('Side1').style.display = 'none';
i = 0;
clearTimeout(ts);
}
}
You probably just need to add this to your CSS:
#Side1 { overflow: hidden; }