I have a problem with jQuery.
I want to add the fixed-top class (Bootstrap 4) when scrolling the page, but this is not the case.
jQuery(document).ready(function($){
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$(".robig").addClass("fixed-top");
} else {
$(".robig").removeClass("fixed-top");
}
});
Can you see what I'm doing wrong?
Your scroll variable is never being updated. You need to add your code into a scroll event like so:
jQuery(document).ready(function($) {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 130) {
$(".robig").addClass("fixed-top");
} else {
$(".robig").removeClass("fixed-top");
}
});
});
body {
margin: 0;
}
.foo {
height: 140vh;
background: black;
}
.robig {
width: 100%;
height: 10vh;
background: lime;
}
.fixed-top {
position: fixed;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="foo"></div>
<div class="robig"></div>
<div class="foo"></div>
However, if you are trying to recreate a sticking effect, I suggest you use position: sticky as jquery isn't needed for this:
body {
margin: 0;
}
.foo {
height: 140vh;
background: black;
}
.robig {
width: 100%;
height: 10vh;
background: lime;
position: sticky;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="foo"></div>
<div class="robig">Stop at top</div>
<div class="foo"></div>
Your code run on page load only but you need to run your code in scroll event of window
$(window).scroll(function(){
var scroll = $(window).scrollTop();
if (scroll >= 500)
$(".robig").addClass("fixed-top");
else
$(".robig").removeClass("fixed-top");
});
Also you can simplify the code and use .toggleClass() instead
$(window).scroll(function(){
$(".robig").toggleClass("fixed-top", $(window).scrollTop() >= 500);
});
$(window).scroll(function(){
$(".robig").toggleClass("fixed-top", $(window).scrollTop() >= 500);
});
p {height: 500px}
.robig {
width: 100%;
background: red;
}
.fixed-top {
position: fixed;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>content</p>
<div class="robig">robig</div>
<p>content</p>
<p>content</p>
$(document).ready(function(){
var scroll = 0;
$(document).scroll(function() {
scroll = $(this).scrollTop();
if(scroll > 500) {
$(".robig").addClass("fixed-top");
} else {
$(".robig").removeClass("fixed-top");
}
});
});
You need to window scroll event. You can try below code
$(document).ready(function(){
$(window).scroll(function(){
if ($(this).scrollTop() >= 130)
{
$(".robig").addClass("fixed-top");
}
else
{
$(".robig").removeClass("fixed-top");
}
});
});
Related
I have the following script:
$(function() {
var header = $(".header-nav");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 50) {
header.addClass("scrolled");
}
if (scroll > 50 && scroll < 60) {
$(".header_logo img").clone().appendTo(".header-logo");
}
if (scroll <= 50) {
header.removeClass("scrolled");
}
});
});
It's supposed to make the navbar fixed on scroll and clone the website logo to the navbar on a .header-logo empty div
But it doesn't work as expected. The logo is mass duplicated or don't appear until a top scrolling.
Is there a way to make it work as: When I scroll, the logo is cloned one time on the navbar then disappear if you go back to top page?
Thanks
Clone img outside the condition, then append or remove based on your if condition. You need to set a class to detect cloned img for removing.
$(function() {
var header = $(".header-nav");
$el = $(".header-logo img").clone().addClass('cloned');
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 50) {
header.addClass("scrolled");
} else {
header.removeClass("scrolled");
}
if (scroll > 50) {
$el.appendTo(".header-logo");
} else {
$('.cloned').remove();
}
});
});
body {
height: 1000px;
/* fake height! */
}
header.header-nav.scrolled {
position: fixed;
}
.header-nav {
background: white;
width: 100%;
min-height: 150px;
border: 1px solid gray;
}
.scrolled {
background: red;
}
.header-logo img {
height: 150px;
display: block;
margin: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header class="header-nav">
<div class="header-logo">
<img src="https://i.graphicmama.com/blog/wp-content/uploads/2019/10/02145410/logo-design-trends-2020-colorful-gradient-logos-example-1.gif" />
</div>
</header>
After getting my last problems solved properly I've got a second problem.
I've got a div which is fixed. Inside of the fixed div is another div which is scrollable. I want to achieve that if I scroll anywhere on the page, even out of the scrollable div, that the scroll action only applies to the scrollable div, not the fixed div.
I made an example of the problem. I want to achieve that if I am scrolling anywhere, even in the red part, that the scroll action is in the red div.
Demo:
$(window).scroll(function () {
var s = $(this).scrollTop();
var row1 = $('#row1');
if(s>500){
row1.css({
'position': 'relative'
});
}
});
.timeline {
position: relative;
max-width: 1200px;
margin: 0 auto;
overflow: scroll;
height: 100vh;
}
#row1 {
width: 100vw;
height:100vh;
position: fixed;
background-color:red;
}
.col-sm-6{width:50%;float:left;height:100px;}
#test{background-color:green;overflow-x:scroll;}
body{height:1000px}
<div class="row" id="row1">
<div class="col-sm-6"></div>
<div class="col-sm-6" id="test">scrollable div<br>test1<br>test2<br>test3<br>test4<br>test5<br>test6<br>test7<br>test8<br>test9<br>test10<br>test11</div>
</div>
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
$(function () {
var myCounter = 0,
myOtherCounter = 0;
var scroll = 0;
$("#test").scroll(function () {
myCounter = myCounter + 1;
$("#log").html("<div>Handler for .scroll() called " + myCounter + " times.</div>");
});
//Firefox
$('#row1').bind('DOMMouseScroll', function (e) {
if (e.originalEvent.detail > 0) {
scrollDown();
} else {
scrollUp();
}
//prevent page fom scrolling
return false;
});
//IE, Opera, Safari
$('#row1').bind('mousewheel', function (e) {
if (e.originalEvent.wheelDelta < 0) {
scrollDown();
} else {
scrollUp();
}
//prevent page fom scrolling
return false;
});
function scrollDown() {
//scroll down
console.log('Down ' + scroll);
if (scroll < $('#test').find('div').height() - $('#test').height() + 20) {
scroll = $('#test').scrollTop() + 5;
$('#test').scrollTop(scroll);
}
};
function scrollUp() {
//scroll up
console.log('Up ' + scroll);
if (scroll > 0) {
scroll = $('#test').scrollTop() - 5;
$('#test').scrollTop(scroll);
}
};
});
.timeline {
position: relative;
max-width: 1200px;
margin: 0 auto;
overflow: scroll;
height: 100vh;
}
#row1 {
width: 100vw;
height:50vh;
position: fixed;
background-color:red;
}
.col-sm-6{width:50%;float:left;height:100px;}
#test{background-color:green;overflow-x:scroll;}
body{height:1000px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row" id="row1">
<div class="col-sm-6" id="test"><div>scrollable div<br>test1<br>test2<br>test3<br>test4<br>test5<br>test6<br>test7<br>test8<br>test9<br>test10<br>test11</div></div>
<div id="log"></div>
<div id="log2"></div>
</div>
Long story short: I'd like to scroll through full-screen divs. Looking at previous question I found this which is quite close to what I need but with some changes.
https://jsfiddle.net/naqk671s/
Instead of having the div #1 fixed and the #2 landing on the top of it, I'd like to have the #1 going up and revealing the #2.
My confidence with jQuery is not so big, so I tried to change some values but I just made it worst. do you think is possible to achieve the result with few changes or should I just start from scratch?
under = function(){
if ($window.scrollTop() < thisPos) {
$this.css({
position: 'absolute',
top: ""
});
setPosition = over;
}
};
over = function(){
if (!($window.scrollTop() < thisPos)){
$this.css({
position: 'fixed',
top: 0
});
setPosition = under;
}
};
To make my self more clear, what I'm trying to achieve is basically the opposite of the fiddle I've posted. If you scroll all the way down and than start to scroll up that will be the effect I'd like to achieve but upside down.
Thanks in advance
Update:
After comment, request became clearer, look these examples...
Pure CSS: https://jsfiddle.net/9k8nfetb/
Reference: https://www.w3schools.com/howto/howto_css_sticky_element.asp
jQuery: https://jsfiddle.net/kajwhnc1/
Reference: multiple divs with fixed position and scrolling
Another jQuery: https://jsfiddle.net/6da3e41f/
Reference: How to make div fixed after you scroll to that div?
Snippet
var one = $('#one').offset().top;
var two = $('#two').offset().top;
var three = $('#three').offset().top;
var four = $('#four').offset().top;
$(window).scroll(function() {
var currentScroll = $(window).scrollTop();
if (currentScroll >= 0) {
$('#one').css({
position: 'fixed',
top: '0',
});
} else {
$('#one').css({
position: 'static'
});
}
if (currentScroll >= two) {
$('#two').css({
position: 'fixed',
top: '26px',
});
} else {
$('#two').css({
position: 'static'
});
}
if (currentScroll >= three) {
$('#three').css({
position: 'fixed',
top: '52px',
});
} else {
$('#three').css({
position: 'static'
});
}
if (currentScroll >= four) {
$('#four').css({
position: 'fixed',
top: '78px',
});
} else {
$('#four').css({
position: 'static'
});
}
});
body,
html {
height: 200%;
}
#one,
#two,
#three,
#four {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
position: absolute;
}
#one {
top: 0;
background-color: aqua;
}
#two {
top: 100%;
background-color: red;
}
#three {
top: 200%;
background-color: #0a0;
}
#four {
top: 300%;
background-color: #a05;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<body>
<div id="one">ONE</div>
<div id="two">TWO TWO</div>
<div id="three">THREE THREE THREE</div>
<div id="four">FOUR FOUR FOUR FOUR</div>
</body>
I added a link into my page to scroll down:
<div class="scroll">
<a onclick="scroll_down()" href="#" id="'scroll_id">
click me
</a>
</div>
<script>
function scroll_down() {
var y = $(window).scrollTop(); //current position
$("html, body").animate({scrollTop: y + $(window).height()}, 600);
}
function scroll_top() {
window.scrollTo(0, 0);
}
</script>
I want to set onclick attribute when bottom is reached to scroll_top.
scroll down is working but when bottom is reached , the attribute of theonclick of <a> tag is not changed.
<script>
window.onscroll = function (ev) {
if ((window.innerHeight + window.scrollY) >= $(document).height()) {
console.log('bootom')
$('#scroll_id').attr('onClick', '');
$('#scroll_id').attr('onClick', 'scroll_top()');
}
}
</script>
do some body tell me where is the error ? why it's not working?
Using the on* event attributes is considered bad practice - and amending them at runtime is worse.
A much better solution is to use a single unobtrusive event handler which determines the current scroll position of the page and moves up/down as necessary, like this:
$(function() {
$('#scroll_id').click(function(e) {
e.preventDefault();
var $win = $(window);
var scrollTarget = $win.height() + $win.scrollTop() >= $(document).height() ? 0 : $win.scrollTop() + $win.height()
$("html, body").animate({
scrollTop: scrollTarget
}, 600);
});
});
.scroll {
position: fixed;
top: 0;
left: 0;
z-index: 10;
}
#content {
height: 1000px;
position: relative;
}
#content div {
position: absolute;
}
#content .top {
top: 20px;
}
#content .middle {
top: 500px;
}
#content .bottom {
bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="scroll">
click me
</div>
<div id="content">
<div class="top">top</div>
<div class="middle">middle</div>
<div class="bottom">bottom</div>
</div>
Syntax Error:
<a onclick="scroll_down()" href="#" id="'scroll_id">
it should be
id="scroll_id">
(removed extra ')
I have a function where I want to move the scroll down if it is at the top. But nothing happens, before and after the function value is still 0.
This is the code:
scrollDrawer = function () {
if (drawerIsUp) {
console.log($(window).scrollTop());
$(window).scroll(function() {
if ( $(window).scrollTop() < 92 ) {
$('html, body').animate({
scrollTop: $(".middle").offset().top
}, 2000);
}
});
console.log($(window).scrollTop());
function winScroll() {
drawerDiv.style.top = (drawerDiv.offset + window.pageYOffset) + "px";
}
}
}
Updated
console.log($(window).scrollTop());
$(window).scroll(function() {
if ( $("html,body").scrollTop() < 92 && $("html,body").scrollTop() > 0) {
$("html,body").scrollTop(800)
}
});
console.log($(window).scrollTop());
I have updated the code and modifed it by applying suggestions from the answers, but still the scroll doesn't get relocated. I wonder if that is maybe since when the page opens it is already at top 0, and I need to relocate it immediately without scrolling from the user in the first place.
Html:
<div id="app">
<div id="bg">
</div>
#section('topBar')
#include('customer.layouts.partials.top-bar')
#show
<div id="main-section">
#section('header')
#include('customer.layouts.partials.header')
#show
#section('carousel')
#include('customer.layouts.partials.carousel', ['function' => 'drawer', 'carouselPadding' => ''])
#show
</div>
<div id="drawer">
<div id="magazine-detail">
</div>
<div id="magazine-detail-carousel">
#section('magazine-detail-carousel')
#include('customer.layouts.partials.carousel', ['function' => 'magazineDetail', 'carouselPadding' => 'carouselPadding'])
#show
</div>
</div>
</div>
CSS:
#main-section {
height: calc(100vh - 92px);
overflow-y: scroll;
width: 100%;
position: fixed;
overflow-y: scroll;
top:77px;
}
#drawer {
z-index: 5;
position: fixed;
top: 100vh;
height: calc(100vh - 92px);
max-height: 100%;
overflow-y: scroll;
width: 100%;
background-color: $white;
padding-left: 15px;
padding-right: 15px;
}
.top-bar {
position: fixed;
top: 0;
}
On click div drawer that is first not visible since it is below the vh, goes over the top of the main-section all the way up to where the top-bar starts. This is the animation:
$('#drawer').animate({
top: 92
}, 500);
And then after that animation I want the scroll to start from the bottom so that I can when the user starts scrolling move the drawer back down again by the amount of pixels a user has scrolled up.
Try this
$(window).scroll(function() {
if ( $(window).scrollTop() < 92 ) {
// if want to animate scroll
$('html, body').animate({
scrollTop: $("body, html").offset(800)
}, 2000);
// otherwise
$("body, html").offset(800)
}
});
I think you make a mistake,you should addEventListener to window,and when the page init, window's scrollTop() eval 0,so your second example can't work.and the last,when the browser inited the page,all of console.log had excuted,so you would see two same result by console.log,you can try to move on into scroll function,so you can see the scrollTop of window when mouse scroll.
there are some example for you:
console.log($(window).scrollTop());
$(window).scroll(function() {
if ( $(window).scrollTop() < 92 && $(window).scrollTop() > -1) {
$(window).scrollTop(800);
}
console.log($(window).scrollTop());
});
the other one:
scrollDrawer = function () {
if (1) {
console.log($(window).scrollTop());
$(window).scroll(function() {
if ( $(window).scrollTop() < 92 ) {
$(window).scrollTop(800);
}
});
console.log($(window).scrollTop());
}
}
scrollDrawer();
This may not be exactly what you're looking for, but it is something that can work with a little css.
var wrap = $("#wrap");
wrap.on("scroll", function(e) {
if (this.scrollTop > 800) {
wrap.addClass("new");
} else {
wrap.removeClass("new");
}
});