Customizing jQuery scrolling effect - javascript

I'm working on a website where I have made a simple scrolling effect using jQuery. Basically, I just have the page scroll to a specified section when the user clicks on one of the navigation links. I would like to customize this so that the header (which I'm using as my scrolling target) is not at the very top of the page. I want it more in the middle. Does anybody know how I can easily customize this? Below is my jQuery code.
jQuery Scroll effect
$('a[href*="#"]').on('click', function(e) {
e.preventDefault()
$('html, body').animate(
{
scrollTop: $($(this).attr('href')).offset().top,
},
500,
'linear'
)
});
Thank you!

The key is to calculate the offset, Try this:
$('a[href*="#"]').on('click', function(e) {
e.preventDefault()
var id = $(this).attr('href');
var $element = $(id);
var elementHeight = $element.height();
var winHeight = $(window).height();
var offset;
if(elementHeight >= winHeight) //if element height > window height, just put the element to top place.
{
offset = 0;
}
else // else make it to the middle place of window.
{
offset = Math.round((elementHeight - winHeight) / 2);
}
$('html, body').animate(
{
scrollTop: $element.offset().top + offset,
},
500,
'linear'
)
});
body, html {
padding: 0;
margin: 0;
}
.nav-wrap {
width: 100vw;
position: fixed;
background: rgba(0,0,0,0.5);
padding: 10px;
}
.nav-wrap > a {
color: #ffffff !important;
padding: 10px;
}
section {
display: block;
width: 100vw;
}
#id1 {
background: #ff0000;
height: 50vh;
}
#id2 {
background: #00ff00;
height: 80vh;
}
#id3 {
background: #ffff00;
height: 120vh;
}
#id4 {
background: #0000ff;
height: 30vh;
}
#id5 {
background: #000000;
height: 60vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="nav-wrap">
ID1
ID2
ID3
ID4
ID5
</div>
<div class="section-wrap">
<section id="id1"></section>
<section id="id2"></section>
<section id="id3"></section>
<section id="id4"></section>
<section id="id5"></section>
</div>

Related

Two conditions for scroll offset and element

What I trying to do is, show .box-tocart when scroll top bigger than .product-info-main offset top and also if reached to .page-footer should hide but I couldn't mix these conditions together, each condition work separately but not working together with || or &&
var target = $('.product-info-main').offset().top;
$(window).scroll(function() {
var footer = $('.page-footer').offset().top;
var element = $('.box-tocart').offset().top;
if (($(window).scrollTop() >= target) || (element >= footer)) {
$('.box-tocart').show();
} else {
$('.box-tocart').hide();
}
});
body {
height: 2000px;
}
#nothing {
height: 100px;
background: red;
}
.product-info-main {
height: 1000px;
}
.box-tocart {
height: 30px;
background: green;
display: none;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
}
.page-footer {
background: blue;
height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="nothing"></div>
<div class="product-info-main">
<div class="box-tocart"></div>
</div>
<div class="page-footer"></div>
Goal: show .box-tocart if scroll top bigger than .product-info-main offset top, else hide. Also if reached to .page-footer hide, else show, but I want these two conditions together, but couldn't make it work.
The problem with current snippet is, it not hide .box-tocart after reach .page-footer
Simple explanation: green div should show after red div, else hide and should hide after
reach to blue div else hide.
You need to change the condition to:
var scrollTop = $(window).scrollTop();
var windowHeight = $(window).height();
if ((scrollTop >= target) && (scrollTop + windowHeight <= footer)) {
// ...
}
Updated example:
var target = $('.product-info-main').offset().top;
$(window).scroll(function() {
var footer = $('.page-footer').offset().top;
var element = $('.box-tocart').offset().top;
var scrollTop = $(window).scrollTop();
var windowHeight = $(window).height();
if ((scrollTop >= target) && (scrollTop + windowHeight <= footer)) {
$('.box-tocart').show();
} else {
$('.box-tocart').hide();
}
});
body {
height: 2000px;
}
#nothing {
height: 100px;
background: red;
}
.product-info-main {
height: 1000px;
}
.box-tocart {
height: 30px;
background: green;
display: none;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
}
.page-footer {
background: blue;
height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="nothing"></div>
<div class="product-info-main">
<div class="box-tocart"></div>
</div>
<div class="page-footer"></div>
You should use $(window).scrollTop() instead of element so your OR condition should be like if (... || $(window).scrollTop() >= footer, that’s because the scroll position is all relative to the window view and not to the cart box
I hope it can help you.

Multiple Window Events - Jquery

I'm trying to write a function that watches the window for a few things:
If the window is greater-than 900px and the window is scrolled passed 100 add a BG color to the nav
If the nav is scrolled passed 100 and the window is resized to less-than 900px change the BG color nav.
I've written two functions that should be doing the trick. My problem is my functions work right up until you scroll passed 100 and resize the screen: they won't apply the second class with the second bg color.
Snippet below. Can anyone provide assistance?
$(document).ready(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var nav = $('nav');
if( scroll > 100 ) {
nav.addClass('scrolled');
} else {
nav.removeClass('scrolled');
}
});
$(window).resize(function() {
var mq = window.matchMedia('(min-width: 100px) and (max-width: 900px)');
if( mq.matches && $('nav').hasClass('scrolled')) {
$('nav').removeClass('scrolled');
console.log("Working");
$('nav').addClass('scrolledTwo');
} else {
console.log("Not working");
$('nav').removeClass('scrolledTwo');
}
});
});
* {
padding: 0;
margin: 0;
}
nav {
height: 70px;
width: 100%;
border: 1px solid;
transition: all .2s ease;
background-color: transparent;
position: fixed;
top: 0;
left: 0;
z-index: 1000;
}
.nav-fixedWidth {
height: inherit;
width: 1000px;
margin: 0 auto;
border: 1px solid #ccc;
}
main {
width: 100%;
height: 2000px;
border: 1px solid;
background-color: #f1f1f1;
}
.scrolled {
background-color: red;
}
.scrolledTwo {
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<div class="nav-fixedWidth"></div>
</nav>
<main></main>
Your code is working fine it is even applying the second class with the second bg color if you will resize slowly your window. The only issue is this if( mq.matches && $('nav').hasClass('scrolled')) condition. As you have mentioned $('nav').hasClass('scrolled') so first time when you will resize it will be true and then
$('nav').removeClass('scrolled');
console.log("Working");
$('nav').addClass('scrolledTwo');
this will apply scrolledTwo class to nav. After that when you will further resize it will never pass this if( mq.matches && $('nav').hasClass('scrolled')) condition, until you don't resize the screen width to less than 100px or greater than 900px and scroll, and will always goto else and you will always see the red color. Try removing it
$(document).ready(function() {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var nav = $('nav');
if( scroll > 100 ) {
nav.addClass('scrolled');
} else {
nav.removeClass('scrolled');
}
});
$(window).resize(function() {
var mq = window.matchMedia('(min-width: 100px) and (max-width: 900px)');
if( mq.matches ) {
$('nav').removeClass('scrolled');
console.log("Working");
$('nav').addClass('scrolledTwo');
} else {
console.log("Not working");
$('nav').removeClass('scrolledTwo');
}
});
});
* {
padding: 0;
margin: 0;
}
nav {
height: 70px;
width: 100%;
border: 1px solid;
transition: all .2s ease;
background-color: transparent;
position: fixed;
top: 0;
left: 0;
z-index: 1000;
}
.nav-fixedWidth {
height: inherit;
width: 1000px;
margin: 0 auto;
border: 1px solid #ccc;
}
main {
width: 100%;
height: 2000px;
border: 1px solid;
background-color: #f1f1f1;
}
.scrolled {
background-color: red;
}
.scrolledTwo {
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<div class="nav-fixedWidth"></div>
</nav>
<main></main>
Another issue in your code is if I scroll and resize the screen width between 100 to 900 and then again resize it to out of this window then there is no class assigned to your div and that is due to no class added in else of resize function. Changing that to this will do that trick also :)
else {
console.log("Not working");
$('nav').removeClass('scrolledTwo');
var scroll = $(window).scrollTop();
if( scroll > 100 ) {
$('nav').addClass('scrolled');
}
}

Rest of divs are shown when resizing browser in single page website

I am developing a single page website, the page is composed by a header and a footer, both fixed at top and bottom respectively and the content in the middle.
The content is a div with 100% of width and height.
At the header there is a menu to access the sections with smooth scrolling, everything works fine at this point, but when I choose the third section and resize the browser I can see the divs above and below, which should be hidden.
I tried to position the current div absolute with addClass/removeClass and modify the height when resize but did not work either.
This is the code:
CSS:
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
}
body {
background-color: red;
overflow: hidden;
}
#cabecera, #footer {
width: 100%;
height: 50px;
background-color: #D1D1D1;
position: fixed;
left: 0;
z-index: 1000;
}
#cabecera {
top: 0;
}
#footer {
bottom: 0;
}
#menu li {
list-style: none;
float: left;
margin-right: 10px;
}
#menu li span {
cursor: pointer;
}
.centrar {
width: 960px;
margin: 0 auto;
}
#section1 {
background-color: #fbfbfb;
}
#section2 {
background-color: #017EFF;
}
#section3 {
background-color: #9F25F6;
}
#section4 {
background-color: #FB8114;
}
#section5 {
background-color: #373737;
}
.layout {
width: 100%;
height: 100%;
}
.active {
position: absolute;
top: 0;
left: 0;
}
</style>
JAVASCRIPT:
<script type="text/javascript">
$(document).ready(function(){
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash;
var $target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing');
/*$("#section1").removeClass("active");
$("#section2").removeClass("active");
$("#section3").removeClass("active");
$("#section4").removeClass("active");
$("#section5").removeClass("active");*/
/*$target.addClass("active");*/
});
/*$(window).resize(function () {
var doc = $(document).height() || $(window).height();
var cabecera = $("#cabecera").height();
var footer = $("#footer").height();
var margin = doc - cabecera - footer;
$('#section3').css({ 'min-height': + margin + 'px' });
});
$(window).resize();*/
});
</script>
HTML:
<body>
<div id="cabecera">
<div class="centrar">
<ul id="menu">
<li>section1</li>
<li>section2</li>
<li>section3</li>
<li>section4</li>
<li>section5</li>
</ul>
</div>
</div>
<div id="section1" class="layout"></div>
<div id="section2" class="layout"></div>
<div id="section3" class="layout"></div>
<div id="section4" class="layout"></div>
<div id="section5" class="layout"></div>
<div id="footer">
<div class="centrar"></div>
</div>
</body>
EDIT:
Screenshot normal browser //
Screenshot resized browser
Steps to reproduce:
1) Open the browser resized to a small window
2) Open the page
3) Go to "section3"
4) Change the height of the browser, increasing or decrementing
5) Take a look at the divs above and below :S
You have to scroll to the top of the selected element(initialized on first) on the resize event of the window without any animation so that it gets executed transparently for the visitor.
The $target variable needs to be declared "globally" so that the resize function will know which was the last accessed section.
<script type="text/javascript">
$(document).ready(function(){
var $target = $(".layout:first");
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash;
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing');
});
$(window).resize(function(){
$(window).scrollTop($target.offset().top);
});
});
</script>

How to set a div as background?

I've found something interesting on this link. But I can't figure out how to make it and I want to know if anyone has any idea how. So what I realised on this is that even if you resize de browser window the elements keep floating but somehow the only focused element here is the webpage not the floating divs from left and right. This is what I've tried https://jsfiddle.net/eoopvgmc/9/ but the only thing that is working is those floating elements.
Here is what I want to know how to do it http://demo.inskinmedia.com/cds/show.php?live=uxtxbpwvx&ismState=1
(function($) {
var element = $('.left-zone'),
originalY = element.offset().top;
var topMargin = 0;
element.css('position', 'relative');
$(window).on('scroll', function(event) {
var scrollTop = $(window).scrollTop();
element.stop(false, false).animate({
top: scrollTop < originalY ? 0 : scrollTop - originalY + topMargin
});
});
})(jQuery);
(function($) {
var element = $('.right-zone'),
originalY = element.offset().top;
var topMargin = 0;
element.css('position', 'relative');
$(window).on('scroll', function(event) {
var scrollTop = $(window).scrollTop();
element.stop(false, false).animate({
top: scrollTop < -250 ? -250 : scrollTop - originalY + topMargin
});
});
})(jQuery);
Just add a div with a fixed width to wrap them
Edit: Changed the code to fit the request ->
$(document).ready(function() {
$(document).on('scroll', function() {
$('.ads').css({
'top': $(window).scrollTop() + 'px'
});
})
});
body {
margin: 0;
}
.wrapper {
position: relative;
width: 500px;
margin: 0 auto;
}
.main_content {
background: blue;
float: left;
height: 1500px;
width: 500px;
}
.top_banner {
background: orange;
float: left;
height: 250px;
width: 500px;
}
.left-zone,
.right-zone {
position: absolute;
top: 0;
width: 224px;
height: 284px;
transition: top 0.8s;
}
.left-zone {
background: yellow;
left: -224px;
}
.right-zone {
background: red;
right: -224px;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="left-zone ads"></div>
<div class="top_banner"></div>
<div class="main_content"></div>
<div class="right-zone ads"></div>
</div>

In Javascript, Hiding a div when scrolling and showing it on mouseover

I am searching for a solution like LinkedIn header functionality after login.
header is fixed on top.
one div(.topBlocks) after header, after scrolling it should be hide and show- its done by using following code
$(window).scroll(function(){
if ($(this).scrollTop() > 0) {
$('.topBlocks').fadeOut("slow", 0);
} else {
$('.topBlocks').fadeIn();
}
});
after content scrolls down... and on moseover of header (.topBlocks) div should be hide and show without moving back content.. and reset css
I have done it like this...
HTML :
<header>some content goes here, height is fixed 33px </header>
<section>
<div class="topBlocks"> some content goes here, height is fixed 123px, width 635</div>
<div class="wrapper">
<div class="fixedLeftSection"></div>
<div class="stickyListWrap"> blog type content, so it scrollable </div>
</div>
</section>
CSS :
header {
width: 100%;
background: #474747;
min-height: 33px;
padding: 11px 0;
position: fixed;
top: 0;
z-index: 1000;
}
.wrapper {
width: 940px;
margin: auto;
padding: 0 10px;
}
.topBlocks {
width: 635px;
margin: auto;
background: #e7e7e7;
height:123px;
}
.fixedLeftSection {
position: fixed;
top: 85px;
}
.stickyListWrap {
margin-top: 30px;
}
Javascript as follows for on header hover hide and show
var hoverMenu = $('.topBlocks'),
hoverSpace = $('header'),
secWrap = $('#mainSectionWrap');
$(window).scroll(function () {
if ($(this).scrollTop() > 0 && !$('header').hasClass('open')) {
$('.topBlocks').fadeOut("slow", 0);
} else {
$('.topBlocks').fadeIn();
}
});
$('header').mouseover(function (e) {
if ($(window).scrollTop() > 0) {
e.stopPropagation();
$('.topBlocks').addClass('testThing');
$('.topBlocks').css("display", "block");
}
});
$('.topBlocks').mouseleave(function (e) {
if ($(window).scrollTop() >= 0) {
e.stopPropagation();
$('.topBlocks').css("display", "none");
$('.topBlocks').removeClass('testThing');
}
});
I try to rebuild the effect of the Linkedin header, I don't know if this can help you.
$(window).scroll(function() {
if($(this).scrollTop() == "0") {
$('#hiddenHeader').show();
} else {
$('#hiddenHeader').hide();
}
});
$('#header').mouseenter(function() {
$('#hiddenHeader').css("top", "50px").show();
}).mouseleave(function() {
if($(window).scrollTop() != "0") {
$('#hiddenHeader').hide();
}
});
http://jsfiddle.net/sing0920/wM7w2/
Try this out
<div class="fixedhead">header tag with</div>
<div class="item">red div1 red div1 red div1 red div1
<br/>
</br/>red div1 red div1 red div1 red div1</div>
css
.fixedhead {
position: fixed;
top: 0;
width: 100%;
height:60px;
background-color:green;
z-index: 999;
}
.item {
background-color:red;
margin: 60px auto 0;
width: 100%;
height:510px;
}
Fiddle reference

Categories