I'm having a hard time finding a Javascript piece of code to dynamically show the Back to Top button when the user has scrolled, lets say, more than 1000 pixels. All examples use jQuery, and I can't use jQuery. Any help will be very appreciated.
Set the CSS when pageOffset is a certain point (in a window.onscroll event):
window.onscroll = function()
{
if(pageOffset >= 1000)
{
document.getElementById('backToTopID').style.visibility="visible"
}
};
something more full would be:
window.onscroll = function()
{
if(pageOffset >= 1000)
{
document.getElementById('backToTopID').style.visibility="visible"
}else
{
document.getElementById('backToTop').style.visibility="hidden";
}
};
DEMO
JavaScript using Window.onscroll
var appended = false, bookmark = document.createElement("div");
bookmark.id = "arrowUp";
bookmark.innerHTML = "<a href=\"#\" title=\"Top of the page.\">↑<\/a>";
onscroll = function() {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop > 500) {
if (!appended) {
document.body.appendChild(bookmark);
appended = true;
}
} else {
if (appended) {
document.body.removeChild(bookmark);
appended = false;
}
}
};
source
https://developer.mozilla.org/en-US/docs/Web/API/window.onscroll
demo link
http://jsfiddle.net/MA4dC/
This is how I do it. To show back to top button when user scrolls more than 150 pixels down from top of document.
//how to show back to top button when user scrolls more than 150 pixels down from top of document.
var toTopButton = document.querySelector("a");
toTopButton.style.display = "none";//by default should be hidden
document.querySelector('body').onscroll = function(){//whenever they scroll
if (window.scrollY > 150)//if scroll is 150px from top
toTopButton.style.display = "block";//if they scroll down, show
else
toTopButton.style.display = "none";//if they scroll up, hide
};
html {scroll-behavior: smooth;}
a {
background-color: #f00;
position: fixed;
bottom: 10px;
right: 10px;
}
<html>
back to top
<body id="top">
text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>
</body>
<html>
OR to show back to top button when user scrolls more than 150 pixels up from bottom of document.
//how to show back to top button when user scrolls more than 150 pixels up from bottom of document.
var toTopButton = document.querySelector("a");
toTopButton.style.display = "none";
document.querySelector('body').onscroll = function(){
if (window.innerHeight + 150 < document.body.offsetHeight)//if document long enough
if (window.scrollY + window.innerHeight > document.body.offsetHeight - 150)//if scroll is 150px from bottom (if 'bottom of what we are looking at' is > than 'bottom of document - 150px earlier)
toTopButton.style.display = "block";
else
toTopButton.style.display = "none";
};
html {scroll-behavior: smooth;}
a {
background-color: #f00;
position: fixed;
bottom: 10px;
right: 10px;
}
<html>
back to top
<body id="top">
text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>text<br>
</body>
<html>
Simple but working.
CSS:
#scrollToTop { visibility: hidden; }
JavaScript:
// Show/Hide the button
window.onscroll = function() {
var pageOffset = document.documentElement.scrollTop || document.body.scrollTop,
btn = document.getElementById('scrollToTop');
if (btn) btn.style.visibility = pageOffset > 450 ? 'visible' : 'hidden';
};
Related
I am building this site as a fun little side project but I am stuck. My sticky nav bar jumps once the user scrolls far enough down. I have read other threads and can't quite connect the dots.
I have been thinking it must be a padding issue, however, my JS isn't all that great so there is potential for problems there as well.
Here is my Javascript:
var header = document.getElementById("header");
var navbar = document.getElementById("navbar");
var navbarHeight = navbar.offsetHeight;
var headerHeight = header.offsetHeight;
header.style.height = screen.height - navbarHeight;
function initJake() {
if (window.pageYOffset > headerHeight) {
navbar.style.position = "fixed";
navbar.style.top = "0";
} else {
navbar.style.position = "relative";
}
}
window.onscroll = function() {
initJake()
};
Here is my jsFiddle (the links are cut off since this is the full-screen HTML setup): https://jsfiddle.net/jihlenfeldt/435ugdyf/2/
I am hoping to find a way in which the transition from absolute to fixed is smooth and doesn't end up covering a bunch of lines of text.
Thank you to anyone willing to offer a bit of advice, this little issue has become quite a headache.
Is this what you mean?:
var header = document.getElementById("header");
var navbar = document.getElementById("navbar");
var content = document.querySelector('#navbar + .content');
var navbarHeight = navbar.offsetHeight;
var headerHeight = header.offsetHeight;
header.style.height = screen.height-navbarHeight;
function initJake(){
if(window.pageYOffset > headerHeight){
navbar.style.position = "fixed";
navbar.style.top = "0";
content.style.padding = '60px 0 0 0';
}
else{
navbar.style.position = "relative";
content.style.padding = '0 0 0 0';
}
}
function hamburgerMenu() {
var x = document.getElementById("submenu");
if (x.style.display == "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
window.onscroll = function() {initJake()};
The issue here is that your navbar gets position "fixed" and its height is not considered by the DOM anymore since it'll be positioned "on top" of everything. Best way to fix this is to give the element after it (the content in this case) a padding-top of the same height that navbar has. (Unlike me, use a variable that gets the height of the navbar since its height can vary, not a fixed number like I did (the 60px))
Well here's your mistake.
if (window.pageYOffset > headerHeight) {
navbar.style.position = "fixed";
navbar.style.top = "0";
} else {
navbar.style.position = "relative"; // here
}
Your navbar has position absolute and when window.pageYOffset > headerHeight is false, you are making it relative
#navbar {
position: absolute;
bottom: 0;
width: 100%;
background-color: #111;
z-index: 3;
overflow: hidden;
height: 20%;
padding-bottom: 3%;
display: flex;
flex-direction: column;
transition-property: width;
}
That's why the bump. Also, the navbar is fixed now, so It doesn't disturbs other elements. That's why the this div is covered by the navbar (or is going upwards)
<div class="content">
<h1>text here</h1>
<p>text here text here text here text here text here text here text here text here text here text here text here text here </p>
</div>
Possible fix is we stick to one position. Let's make it relative. Then we add margin top to the content div when the position is fixed. Which makes it some distance from above. So javascript becomes becomes
var content = document.getElementsByClassName("content")[0];
if (window.pageYOffset > headerHeight) {
navbar.style.position = "fixed";
navbar.style.top = "0";
content.style.marginTop = " 115px";
} else {
navbar.style.position = "relative";
content.style.marginTop = "0px";
}
And stick to relative in css
#navbar {
position: relative;
...
}
So your fiddle becomes something like this
Why do you guys use always JS to interact with the appearance of a HTML object.
Use JS to check if the header is outside of the viewport and if yes, set a class on the body. Via CSS you can modify the sticky header.
Something like this:
$(window).scroll(function(){
if($(this).scrollTop() > $('#header').outerHeight()){
$('body').addClass('scrolled');
} else {
$('body').removeClass('scrolled');
}
});
And via CSS
#header { position:relative; }
body.scrolled #header { position:fixed; top:0; left:0; width:100%; }
body.scrolled { padding-top:<Enter here Height of Header to prevent jumping> }
My page have a div called #product. I need to fill progress bar when user scroll in #product div. How can I do it using jquery. Thanks.
if (/* page scroll to #product div */){
var scrolled = ??? //percentage of scroll on div
}
You can get current scroll position with this:
currentScroll = $(this).scrollTop() + $(this).innerHeight()
where 100% scroll is:
maxScroll = this.scrollHeight
Then your current progress percentage will be:
(currentScroll / maxScroll) * 100
Use this code:
$('#product').bind('scroll', function() {
var currentScroll = $(this).scrollTop() + $(this).innerHeight(),
maxScroll = this.scrollHeight;
var scrolled = (currentScroll / maxScroll) * 100;
});
See example here.
EDIT:
To let the div come to top on browser scroll add:
$(document).bind('scroll', function() {
$('#product').css({ position: absolute; top: 0; });
});
I'm trying to use jQuery to set the height of a div so that it takes up the entire window + the height of a header (so that you can scroll the header off the page) but no more than that. I would think the height of the div would be the height of the window + the height of the header I'm trying to hide.
When I set the div to window height, however, it creates overflow. Here's the rough code:
var $body = $("#body"),
$container = $("#container"),
$window = $(window),
$content = $("#mainContent"),
$header = $("#header"),
bodyHeight = window.innerHeight + $header.height();
$body.css("height", window.innerHeight);
$container.css("height", bodyHeight);
div {
display: block;
width: 100%;
margin: 0;
}
#body {
overflow-y: scroll;
}
#container {
overflow-y: hidden;
}
#header {
overflow: hidden;
}
#navbar {
height: 10px;
background-color: brown;
}
#mainContent {
height: 200px;
overflow-y: scroll;
}
#contentP {
height: 400px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="body">
<div id="container">
<div id="header">
<h1>Header</h1>
</div>
<div id="navbar">
</div>
<div id="mainContent">
<p id="contentP">This is content</p>
</div>
</div>
</div>
Why is there overflow if the div is sized to fit in the window?
EDIT: So far, answers haven't helped. This is the site I'm working on. It's joomla. I want the nav bar to lock at the top of the screen.
$(document).ready(function() {
//Declare some variables
var $window = $(window),
$body = $(".body"),
$mainContent = $("#maincontent"),
headerGap = parseFloat($("#headerimg").css("margin-top")),
headerHeight = headerGap + $("#header").height() + parseFloat($("#navbar").css("margin-top")),
navbarHeight = $("#navbar").height(),
footerHeight = $("#footer").height();
//set the height of the body and the maincontent
resizePage();
//Set the listeners for resizing and scrolling
$window.resize(resizePage);
$window.scroll(scrollHandler);
//When you scroll, see if the navbar is at the top. Set maincontent overflow
//to scroll when the navbar is at the top of the window. Set it to hidden otherwise
function scrollHandler() {
if ($window.scrollTop() < headerHeight - 1) {
$mainContent.css("overflow", "hidden");
} else {
$mainContent.css("overflow", "auto");
}
}
//Set the body and the mainContent to be the correct sizes when the window size is changed. In theory, the body should be:
// windowHeight + headerHeight
// maincontent should be:
// windowHeight - (headerHeight + navbarHeight + footerHeight)
// But that doesn't quite work out.
function resizePage() {
//Deal with the changing CSS due to media queries
if ($(window).width() > 768) {
headerGap = parseFloat($("#headerimg").css("margin-top"));
headerHeight = headerGap + $("#header").height() + parseFloat($("#navbar").css("margin-top")) - 1;
$(".nav.menu.nav-pills").css("width", "92.5%");
}
else {
headerHeight = $("#header").height();
$(".nav.menu.nav-pills").css("width", $window.width());
}
//The header and navbar height change at certain sizes, so grab them again to be safe.
navbarHeight = $("#navbar").height();
footerHeight = $("#footer").height();
var windowHeight = $window.height(),
contentHeight = windowHeight - (footerHeight + navbarHeight);
//if we account for headerHeight too, maincontent is too big
resizeContent(contentHeight);
resizeBody(windowHeight);
}
//The body should take up the whole height of the window, plus the header
//and margin heights at the top. This way, you scroll to the navbar.
// But it doesn't work this way.
// -7 and -27 are from eyeballing it.
function resizeBody(windowHeight) {
if($window.width() > 728) {
$body.css("height", windowHeight - 7);
}
else {
$body.css("height", windowHeight - 27);
}
}
// The content should go from the bottom of the navbar to the bottom of the footer.
//
function resizeContent(contentHeight) {
$mainContent.css("top", (headerHeight + navbarHeight));
$mainContent.css("bottom", (0 - headerHeight));
//For the background slideshow on the Furniture page
// Again, + 5 was eyeballed
$("div.moduletable").css("height", contentHeight + 5);
if ( (contentHeight + 5) < ($(window).width()) /2 ) {
$(".wk-slideshow img").css("width", "100%");
$(".wk-slideshow img").css("height", "auto");
}
else {
$(".wk-slideshow img").css("height", contentHeight + 5);
$(".wk-slideshow img").css("width", "auto");
}
}
});
It works for a lot of sizes, but one you get to small resolutions it falls apart.
EDIT 2: I was able to get the effect I was going for by adding another div. I set the body to be the height of the window and the new div to be the size of the body + the height of the header. The body has "overflow-y: scroll". The container would have "overflow-y: hidden" (See updated snippet). This doesn't totally answer my question, but at least it helps?
I've taken a look at your code and altered it. Try this and see if this is what you're looking for.
In my example i'm looking for the element by getElementById and then I set it's style.height to window.innerHeight - 10px without taking the 10px it wouldn't show the border fully on the page. So you just remove 10px's. The example has been tested on different screen sizes.
Javascript example:
function autoResizeDiv() {
document.getElementById('body').style.height = window.innerHeight - 10 + 'px';
console.log(window.innerHeight - 10 + 'px');
}
window.onresize = autoResizeDiv;
autoResizeDiv();
#body {
display: block;
border: 5px solid black;
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="body">
</div>
The following worked for me:
$(".body").height($(window).height());
I figured out the biggest problem. I was using some absolutely positioned elements without giving a parent any other position. This made things show up wonky when I was trying to size other things. I also needed to have an extra div as a container for all the content on the page that would be the height of the window + the height of the header.
Thanks to everyone who answered, it helped!
I have it right now so that when you scroll down a fixed text will appear. However, the script running it is currently initiating when the viewport is scrolled to the <span>. How can I make it so that the script starts when you're, say 100px, above the <span>
I've tried using a <div> and positioning it where I want so that the script picks that up instead of the <span> however, that just adds unwanted blank space.
<div class="invis"></div>
.invis { height: 100px; visibility: hidden; }
Code: http://jsfiddle.net/suLLL/1/
$(window).scroll(checkY);
function checkY() {
//save this value so we dont have to call the function everytime
var top = $(window).scrollTop();
$(".title").each(function () {
var target = $(this).closest(".content");
var tTop = target.offset().top;
var tBottom = target.offset().top + target.outerHeight();
if (top >= tTop && top <= tBottom) {
console.log("Show");
$(this).show();
} else {
console.log("Hide");
$(this).hide();
}
});
}
checkY();
You could remove the height from the 'tTop' variable:
var someVal = 100;
var tTop = target.offset().top - someVal;
So I basically want the script to start at the top of "mini" div but can't get it to work right.
#mini {
width: 100%;
padding-top: 300px;}
var tTop = $("#mini").outerHeight(true);
Full script:
$(window).scroll(checkY);
function checkY() {
//save this value so we dont have to call the function everytime
var top = $(window).scrollTop();
$(".title").each(function () {
var target = $(this).closest(".content");
var tTop = $("#mini").outerHeight(true);
var tBottom = target.offset().top + target.outerHeight();
if (top >= tTop && top <= tBottom) {
console.log("Show");
$(this).show();
} else {
console.log("Hide");
$(this).hide();
}
});
}
checkY();
Why not setting the mini style to
position:relative;
and the inner div to
position: absolute;
top:0