Two conditions for scroll offset and element - javascript

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.

Related

How to center with javascript an element on y?

I am trying to make a sticky banner witn html and css and js. My html is this
window.addEventListener('scroll', function(ev) {
var distanceToTop = container.getBoundingClientRect().top;
if (container.getBoundingClientRect().top >= document.documentElement.scrollTop - screen.height + 400) {
sticky.style.top = "100px"
} else {
sticky.style.top = document.documentElement.scrollTop - screen.height + 400 + "px";
}
});
.container {
background: red;
width: 600px;
height: 100px;
position: relative;
}
.sticky {
background: blue;
width: 200px;
height: 200px;
position: absolute;
right: 0;
top: 100px;
}
<div class="container">
<div class="sticky"></div>
</div>
I would want when i scroll the window the stocky div to be center on y axis and when the distance between container and top of the page is less then 200px the two divs to be attached.
Can anyone to give me a clue?

Adding and removing class at div top?

I am trying to make a class fade in when 'register' class div top enters the window and otherwise have the class fade out
How can I make this work?
$(window).scroll(function() {
var tint = $('.register').offset().top;
if ($(this).scrollTop() > tint) {
$('.tint').fadeIn(1000);
} else {
$('.tint').fadeOut(1000);
}
});
section {
height: 100vh;
width: 100%;
}
.tint {
background-color: #000;
width: 100%;
height: 100vh;
opacity: 0.6;
position: absolute;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section></section>
<section class="register">
<div class="tint"></div>
<div>Content</div>
</section>
Class example code you posted seems to work correctly, I think you should check css also if there is any problem. But if want any other methods then here are some methods: you can use fadIn() - fadeOut(), or hide() - show() or css visibility or display block and none , or simply can jquery UI animate functionality. Here is animation example to hide div jquery animate
$(window).scroll(function() {
var top_of_element = $("#element").offset().top;
var bottom_of_element = $("#element").offset().top + $("#element").outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
var top_of_screen = $(window).scrollTop();
if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
// the element is visible, do something
} else {
// the element is not visible, do something else
}
});
$(window).scroll(function() {
var tint = $('.register').offset().top;
if ($(this).scrollTop() > tint) {
$('.register').fadeIn();
// OR
//$(".register").show();
// OR
//$(".register").css('visibility', 'visible');
} else {
$('.register').fadeOut();
// OR
//$(".register").hide();
// OR
//$(".register").css('visibility', 'hidden');
}
});
.tint {
background-color: #000;
width: 100%;
height: 100vh;
opacity: 0.6;
position: absolute;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="register">
<div class="tint"></div>
<div>Content</div>
</section>
The only problem, that you've passed a string to fadeOut, which expects a number.
So, remove the quotes around '1000', and you'll be right:
$(window).scroll(function() {
var tint = $('.register').offset().top;
if ($(this).scrollTop() > tint) {
$('.tint').fadeIn(1000);
} else {
$('.tint').fadeOut(1000);
}
});
section {
height: 100vh;
width: 100%;
}
.tint {
background-color: #000;
width: 100%;
height: 100vh;
opacity: 0.6;
position: absolute;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section></section>
<section class="register">
<div class="tint"></div>
<div>Content</div>
</section>

Customizing jQuery scrolling effect

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>

Built a scroll controller, need to reverse it

My code allows scrolling vertically in the bottom section to control scrolling horizontally in the top section.
My jsfiddle
You'll see the colors shift through a gradient. Works pretty well. Problem is that I can't quite seem to get the inverse to work. Scrolling horizontally in the top controls scrolling in the bottom.
Any ideas?
Here's the script that makes it work:
// Add event listener for scrolling
$("#bottom").on("scroll", function bottomScroll() {
var scrolledleft = parseInt($("#bottom").scrollTop()) * 1;
console.log(scrolledleft + scrolledright)
$("#top").scrollLeft(scrolledleft + scrolledright)
})
//Move right column to bottom initially
$("#top").scrollLeft($("#top").height())
//Get actual distance scrolled
var scrolledright = parseInt($("#top").scrollLeft())
Your event handlers need to temporarily cancel each other so that they don't both fire at once. You want to calculate your position percentage based on the current scrollLeft / (width of child div - width of container), then apply that percentage to the other element, and likewise for top/height. Also I changed the height of #top to 50% in CSS.
var handler = function (e) {
var src = e.target;
// the first element that triggers this function becomes the active one, until it's done
if (!activeScroller) activeScroller = src.id;
else if (activeScroller != src.id) return;
var $b = $("#bottom");
var $t = $("#top");
var scrollH = $("#bottom-content").height() - $b.height();
var scrollW = $("#top-content").width() - $t.width();
var scrollPct = 0;
if (src.id == "top") {
if (scrollW > 0) {
scrollPct = $t.scrollLeft() / scrollW;
}
$b.scrollTop(scrollH * scrollPct);
} else {
if (scrollH > 0) {
scrollPct = $b.scrollTop() / scrollH;
}
$t.scrollLeft(scrollW * scrollPct);
}
// give all animations a chance to finish
setTimeout(function () { activeScroller = ""; }, 100);
};
var activeScroller = "";
$("#top,#bottom").on("scroll", handler);
#top {
position: absolute;
margin: auto;
top: 0;
right: 0;
left: 0;
width: 100%;
height: 50%;
position: fixed;
overflow: auto;
background: red;
}
#top-content {
height: 100%;
width: 2000px;
background: linear-gradient(90deg, red, blue);
}
#bottom {
position: absolute;
margin: auto;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 50%;
position: fixed;
overflow: auto;
background: green;
z-index: 100;
}
#bottom-content {
height: 2000px;
width: 100%;
background: linear-gradient(0deg, orange, green);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="top">
<div id="top-content"></div>
</div>
<div id="bottom">
<div id="bottom-content"></div>
</div>
Check out this:
https://jsfiddle.net/1p7gp72h/1/
I'm not sure what your end goal is here.
$("#top").on("scroll", function topScroll() {
var scrolledleft = parseInt($("#top").scrollTop()) * 1;
$("#bottom").scrollLeft(scrolledleft + scrolledright)
});
#top {
top: 0;
right: 0;
left: 0;
width: 5000px;
height: 100%;
overflow: auto;
background: red;
overflow-x: scroll;
overflow-y: hidden;
white-space:nowrap;
}
Scroll to left ::
$('div').scrollLeft(1000);
Scroll back to normal/ scroll to right ::
$('div.slick-viewport').scrollLeft(-1000);

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>

Categories