I am using Chris Ferdinandi's Smooth Scroll script and I am trying to have it scroll to an element, but land with that element centred. Similarly to what is done at http://www.spotify.com.
I attempted adding the following code to the start of the script:
$(document).ready(function(){
$('.downarrow a').click(elementhref = $('.downarrow a').attr('href'));
var elementheight = $(elementhref).height();
var windowheight = $(window).height();
if (elementheight < windowheight) {
topoffset = ((windowheight / 2) - (elementheight / 2) - 30);
} else {
topoffset = 0;
}
});
I then added the variable topoffset into the script so that it offsets the anchor's position by the correct amount.
var endLocation = _getEndLocation( document.querySelector(anchor), topoffset ); // Scroll to location
It works perfectly for the first section, but when I click on the next .downarrow a element, my code only ever uses the height of first section. But I have several of these links with the same class throughout my HTML.
This is a simplified version of what I have:
<section id="home">
<!--content-->
<div class="downarrow"><a data-scroll href="#about">Scroll Down</a></div>
</section>
<section id="about">
<!--content-->
<div class="downarrow"><a data-scroll href="#portfolio">Scroll Down</a></div>
</section>
<section id="portfolio">
<!--content-->
<div class="downarrow"><a data-scroll href="#contact">Scroll Down</a></div>
</section>
<section id="contact">
<!--content-->
</section>
I was trying to have it change the elementhref variable depending on which element was clicked, but this would obviously not work with my code. I tried giving each downarrow a unique ID but it became too complicated for me.
This is my first time using JavaScript and jQuery, so I'm hoping there's a simple solution I've overlooked.
Try
(function() {
function setStuff(elementhref) {
var elementheight = $(elementhref).height();
var windowheight = $(window).height();
if (elementheight < windowheight) {
topoffset = ((windowheight / 2) - (elementheight / 2) - 30);
} else {
topoffset = 0;
}
}
$('.downarrow a').click(function() {
setStuff( $(this).attr('href') );
});
})();
Only targeting the one you have 'clicked' - this - and making a jquery object of out it so you can access the jquery methods $(this)
Edit/Update - added in the parts to connect the click handler with a function to dostuff
Related
I have multiple html pages (Page A and Page B) and I need to detect if certain divs on each page are in view while the user is scrolling on either page. Both pages link to each other and share the same js script. The problem right now is that when I scroll and navigate to the other page, it only detects the divs for pageA but not for pageB. When I comment out the function for pageA (checkPageA()), then it works for pageB. I’m not sure what’s going on and why it’s not working for both pages.
I'm not sure how to show multiple html pages here, so here’s a simplified version of my code (doesn't run since the pages aren't connected here). I want to keep both pages separate HTML files and not combine them. Thanks!
$(document).ready(function() {
$(document).scroll(function() {
checkPageA();
checkPageB();
});
function checkPageA() {
if (percentInViewport(".pageA", 10)) {
alert("pageA");
}
}
function checkPageB() {
if (percentInViewport(".pageB", 10)) {
alert("pageB");
}
}
/**Checks if div is in the viewport by percentVisible**/
function percentInViewport(objectString, percentVisible) {
var el = document.querySelector(objectString);
rect = el.getBoundingClientRect();
windowHeight = (window.innerHeight || document.documentElement.clientHeight);
return !(
Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / + -(rect.height / 1)) * 100)) < percentVisible ||
Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible
)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- HTML for Page A-->
<html>
<body>
Go to Page B
<div class="pageA">This is page A</div>
</body>
</html>
<!-- HTML for Page B-->
<html>
<body>
Go to Page A
<div class="pageB">This is page B</div>
</body>
</html>
Ah, I just figured this out. There was something wrong with my percentInViewport function due to the null elements. As someone suggested, did some debugging from the console and the scroll works haha. Thanks!
The issue with you code because when you are on the second page the checkPageA function is called when you scroll and the class that is given in is not found and it will give error.
instead of creating different function, and different class for every page you can use one common function and one common class.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- HTML for Page A-->
<html>
<body>
Go to Page B
<div class="pageDiv">This is page A</div>
</body>
</html>
<!-- HTML for Page B-->
<html>
<body>
Go to Page A
<div class="pageDiv">This is page B</div>
</body>
</html>
<script>
$(document).ready(function() {
$(document).scroll(function() {
checkPage();
});
function checkPage() {
if (percentInViewport(".pageDiv", 10)) {
alert("pageDiv");
}
}
/**Checks if div is in the viewport by percentVisible**/
function percentInViewport(objectString, percentVisible) {
var el = document.querySelector(objectString);
rect = el.getBoundingClientRect();
windowHeight = (window.innerHeight || document.documentElement.clientHeight);
return !(
Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / + -(rect.height / 1)) * 100)) < percentVisible ||
Math.floor(100 - ((rect.bottom - windowHeight) / rect.height) * 100) < percentVisible
)
}
})
</script>
I currently have this working on each webpage, other than my 'about us' page.
Basically, I have used the variable:
<div class="spacer"></div>
<p id="startchange">
which links to the JQuery to initiate the change in colour / replacing the image with the other one. Currently neither of these attributes are changing, however on other pages they work just fine: as the sticky nav bar becomes smaller using waypoints. I am using these variables pretty early in my code (Just underneath header).
It seems no matter where I place these, they do not seem to execute, and I am not sure why.
jQuery:
<script>
$(document).ready(function(){
var scroll_start = 0;
var startchange = $('#startchange');
var offset = startchange.offset();
$(document).scroll(function() {
scroll_start = $(this).scrollTop();
if(scroll_start > offset.top) {
$('#navbar').css('background-color', '#f0f0f0');
$("#navbar img").attr("src", "images/logo-grey-real.jpg");
} else {
$('#navbar').css('background-color', '#fff');
$("#navbar img").attr("src", "images/logo.jpg");
}
});
});
</script>
I made a JSFiddle :)
HTML :
<div class="navbar"></div>
<p id="test">test</p>
Jquery :
var offset = $('#test').offset().top;
var navbar = $('.navbar');
$(document).scroll(function() {
position = $(this).scrollTop();
if (position < offset)
navbar.css('background-color', 'red');
else
navbar.css('background-color', 'blue');
});
I have taken a reference of the below site and i want to add text effects ie opacity gets fade on page scroll. The above code is working properly if i use the below reference as it is but if i add many div then it gets faded early not reaching the required div
http://jsfiddle.net/HsRpT/134/
Here is what i have done and the text fade effects goes early without reaching the actual div. Is there any other way of solving this problem?
<div>
fsdfdfsdfffffffffff<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>><br><br><br>
</div>
<div class="block">
<h2>Fade this in / out as scroll down</h2>
</div>
<div class="content">
<div class="headerbar">
</div>
</div>
Try
$(window).scroll(function() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (scrollTop > 200) {
$('.block').stop(true, true).fadeOut();
}
else {
$('.block').stop(true, true).fadeIn('fast');
}
});
Fiddle
current_div="div1";
$(window).scroll(function() {
current_div = scroll_content();
console.log(current_div);
if(current_div=="last"){
don't fade out
}
});
function scroll_content(){
var winTop = $(this).scrollTop();
var $divs = $('section');
var top = $.grep($divs, function(item) {
return $(item).position().top <= winTop;
});
var cur=top[top.length - 1];
return $(cur).attr('id');
}
You can get the the id of the div which is going out of screen while scrolling. So you can do what ever you want to do with the divs after getting the id .
It worked for me.
Let me know if you any other query.
I'm creating a Pure JS scroll to Top button. I'm writing a function to gather the window height and with, then write the appropriate margins to the scroll button, to keep it in a fixed position outside of the container(container is the 901 in marginx variable). However, when I load the page, the function isn't applying any of the margins to the "scroll" element, and I have no errors.
my code:
<head>
<script>
function displayScrollTop(){
var w=window,
d=document,
e=d.documentElement,
g=d.getElementsByTagName('body')[0],
x=w.innerWidth||e.clientWidth||g.clientWidth,
y=w.innerHeight||e.clientHeight||g.clientHeight;
var marginy = 60-y; //margin-top value
var marginx = "-" + (x-901)/2 - 60;
//image is floated right, this creates a negative margin left to pull to center.
The width of the window - 901 (width of the container)/2 to get the side
margins, - 60 (width of button)
document.getElementById('scroll').style.marginTop = marginy;
document.getElementById('scroll').style.marginLeft = marginx;
}
</script>
</head>
<body onload="displayScrollTop();">
<div id="scroll">
<a onclick="scrollToTop(500);"><img src="images/scrolltotopbutton.png" /></a>
</div>
<div id="container">
</div>
</body>
Any ideas?
You'll need to specify that the margin values are in px, by appending "px" to them.
I have a floating box and I'd like to know how I can stop it from overlapping the footer div by stopping it on the main div where it is only allowed to go.
window.onload = function ()
{
var scrolledElement = document.getElementById('scrolling_box');
var top = scrolledElement.offsetTop;
var listener = function ()
{
var y = scrolledElement.scrollTop || scrolledElement.scrollTop || window.pageYOffset;
if (y >= top-25)
{
scrolledElement.classList.add('fixed');
} else {
scrolledElement.classList.remove('fixed');
}
};
window.addEventListener('scroll', listener, false);
}
I'd like for it to stop at the main div, that is as followed:
<div class="outer">
<div class="main">
<div class="left">
</div>
<div class="right">
<div class="scrolling_box">
the box that is scrolled goes right here
</div>
</div>
</div>
<div id="footer">
Footer goes here
</div>
</div>
I'd like it to be stopped at the main class, I have looked a lot of other tutorials and none that I could port it to plain javascript. I tried including the .stop() but it wound up being only for jQuery sadly. I could not replicated the issue in jsfiddle, sadly.
I tried using float:both, left and right but neither seemed to have worked at all.
Almost Solved Check for Demo
$(window).scroll(function(){
var pos = $('#footer').offset();
var top = pos.top;
var pos1 = $('#scrolling_boxI').offset();
var top1 = pos1.top
//alert(top);
if( $(window).scrollTop()<top-150-top1)
{
$("#scrolling_boxI").stop().animate({"marginTop": ($(window).scrollTop()) + "px", "marginLeft":($(window).scrollLeft()) + "px"}, "slow" );
}
});