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>
Related
Hi, trying to have the text inside a sticky header change in relation to how far away it is from the top of the page. Supposing I have a single page site, with several distinct did sections each measuring 100vh. The nav links to them via href="#sectionA", "#sectionB", etc.
So if I start on the landing page and scroll down to "sectionA" the header should change to that sections title. Couldn't figure out how to do this using the .href but if that is a preferable way I'm amendable.
Currently have:
function scrollChange(id) {
var winHeight = window.innerHeight;
if (window.scrollBy(winHeight)) {
document.getElementById(title).innerHTML = 'SomethingB';
}
else if (window.scrollBy(winHeight * 2)) {
document.getElementById(title).innerHTML = 'SomethingC';
}
else {
document.getElementById(title).innerHTML = 'somethingA';
}
}
document.addEventListener('scroll', function() {scrollChange();});
The DOM manipulation doesn't matter for right now; just trying to get the correct reference by scroll. No JQuery answers please. Thank you!!
Complete re-write based on feedback and testing :]
function scrollChange(id) {
console.log('scroll w.height:['+ window.innerHeight +'] scroll:['+ window.scrollY +']');
// start with the biggest value first
if (window.scrollY > (window.innerHeight / 2)) {
document.getElementById(id).innerHTML = 'Something big';
} else if (window.scrollY > (window.innerHeight / 3)) {
document.getElementById(id).innerHTML = 'Something middle';
} else {
document.getElementById(id).innerHTML = 'Something small';
}
}
window.addEventListener('scroll',function(){
scrollChange('sticky');
});
<div id="sticky" style="position:fixed;top:0px;line-height:2em;background:#fff">
Sticky title (0)
</div>
<div style="margin-top:3em;line-height:3em">
<p>This</p><p>is</p><p>just</p><p>padding</p><p>to</p>
<p>test</p><p>scrolling</p><p>down</p><p>the</p>
<p>page</p><p>and</p><p>this</p><p>is</p><p>more</p>
<p>padding</p><p>to</p><p>test</p><p>scrolling</p>
<p>down</p><p>the</p><p>page</p>.</div>
I am making a website but I don't know much about javascript or jquery. I have a down arrow on my homepage showing that there is more information but I want it to go away when the user scrolls to the bottom of the page because it is then not needed because they can't scroll down anymore. I know I will need javascript or jquery to do this but I don't even know where to start with it. Help!
Try something like this :
document.onscroll = function() {
if (window.innerHeight + window.scrollY > document.body.clientHeight) {
document.getElementById('arrow').style.display='none';
}
}
Where 'arrow' is the id of the image.
Using jquery:
$(window).scroll(function(){
var numPix = 200; // number of pixels before bottom of page that you want to start fading
var op = (($(document).height() - $(window).height()) - $(window).scrollTop()) / numPix;
if( op <= 0 ){
$("#thing-to-hide").hide();
} else {
$("#thing-to-hide").show();
}
$("#thing-to-hide").css("opacity", op );
});
I'm making a header with a responsive img in the middle. I want to calculate 2 divs.
1 on top of img;
1 at bottom of img;
The calc is ok, except in small devices.
On the first load of the page, this is how it is: http://i.imgur.com/hdJnIId.png
If i reload the page, this is what happens: http://i.imgur.com/pY6GkpN.png
It's happening only in screen smaller than 440px
This is the Jquery i'm using:
$(document).ready(function() {
$(window).resize(function() {
getWidthAndHeight();
});
$(window).load(function() {
getWidthAndHeight();
});
});
function getWidthAndHeight (){
var full = $('.header-main').outerHeight (),
hImg = $('.hd-m-m').height (),
x = hImg,
y = full - x,
c1 = y * 0.3,
c2 = (y * 0.7) + 5,
ct = c1 + c2 + x; //used only to confirm the result - console.log
$('.hd-m-t').css({'height': c1});
$('.hd-m-b').css({'height': c2});
}
Ps.: I have the ' +5 ' because i'm using a margin-top: -5px to cover a small blank area after the img.
And this is my HTML
<header id="home" class="full"><!-- home -->
<div class="header-bg"></div><!-- background images -->
<div class="header-main">
<div class="hd-s"></div> <!-- div on left side -->
<div class="hd-m">
<div class="hd-m-t"></div> <!-- top div - needs calc -->
<div class="hd-m-m"> <!-- middle div -->
<img src="img/home/home-logo.png" />
</div>
<div class="hd-m-b"> <!-- bottom div - needs calc -->
<h2>main text</h2>
<h2>sub text</h2>
</div>
</div>
<div class="hd-s"></div> <!-- div on right side -->
</div><!-- transparent logo -->
</header>
This is the final result i'm looking for: http://i.imgur.com/vnS3BGb.png
I want to this way, because the background img will have a parallax effect and i want it to appear only trought the logo transparency.
Can anyone help me?
Ok, so, after some time, i didn't found anything to solve this problem but this 'fix'.
I don't know if it's the best way or not, but here we go:
I changed the $(document).ready part, so now it execute the function after everything is loaded (including img's). This solved the extra margin at the bottom.
$(document).ready(function() {
$(window).load(function() {
getWidthAndHeight();
});
$(window).resize(function() {
getWidthAndHeight();
});
});
Since the missing background at the bottom only happens in screen smaller than 440px, i added a if condition to the function with an extra calc. The missin background was always the same height. But i also moved the function inside the $(document).ready this is the final code:
$(document).ready(function() {
$(window).load(function() {
getWidthAndHeight();
});
$(window).resize(function() {
getWidthAndHeight();
});
function getWidthAndHeight (){
var full = $('.header-main').outerHeight (),
hImg = $('.hd-m-m').height (),
x = hImg,
y = full - x,
c1 = y * 0.3,
c2 = (y * 0.7) + 5,
c3 = c2 + 17,
ct = c1 + c2 + x;
$('.hd-m-t').css({'height': c1});
if ($(window).width() < 440) {
$('.hd-m-b').css({'height': c3});
} else {
$('.hd-m-b').css({'height': c2});
};
}
});
If anyone knows a better answer, i'll appreciate that. =D
Thanks #SableFost you gave me some good tips (even to learn extra things).
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
I have an Html page with an scroll ,and I'd like when the page starts (onload) to put the focus in the 60% parox (y axis) of the page. that means to scroll automatically the 60% of the page.
is this possible? thankyou
Try this website:
link text
Thats should work!
function pageScroll() {
var height = document.documentElement.clientHeight;
window.scrollBy(0, Math.floor(0.6 * height)); // horizontal and vertical scroll increments
}
window.onload = pageScroll;
You can use window.scrollBy() method:
http://www.mediacollege.com/internet/javascript/page/scroll.html
Or use scrollTo jQuery plugin, which gives you more flexibility.
http://plugins.jquery.com/project/ScrollTo
With jQuery and it's scrollTop method:
function loadedScroll() {
$(window).scrollTop(0.6*$(document).height());
}
window.onload = loadedScroll;
Then it scrolls to 0.6 times the document's height when the page has finished loading. :)
<html>
<head>
<script>
scroller = function() {
bodyHeight = Math.max(
Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
Math.max(document.body.clientHeight, document.documentElement.clientHeight)
);
scrollToPosition = Math.floor(bodyHeight / 100 * 60);
window.scrollTo(0, scrollToPosition);
}
</script>
</head>
<body onload="scroller()">
</body>
</html>
Depending on what you want to display, you can add id selectors to you content and then have the page skip to them using a url eg.
<div id="content">
<!--Content Goes Here -->
</div>
And open the page using:
http://www.mysite.com/mysite.html#content
Another example would be this:
start html page scrolled