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>
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'm trying to stick a section to the top when it hits the top of the browser on scroll down, but I'd like to unstick it when the user scrolls back up and the previous section is back in view.
I'm detecting distance from top to section I'd like to stick, but once its at the top how do we detect user scrolling back up and previous section comes back into view.
My Codepen: https://codepen.io/omarel/pen/LeEjax
Snippet
$(window).on('scroll', function() {
var scrollTop = $(window).scrollTop();
sectionone = $('section.one').offset().top;
sectiontwo = $('section.two').offset().top;
sectiontwodistance = (sectiontwo - scrollTop);
sectiononedistance = (sectionone - scrollTop);
console.log(sectiononedistance);
if (sectiontwodistance < 1) {
$('section.two').addClass('fix');
}
});
html,
body {
width: 100%;
height: 100%;
}
section {
height: 100%;
border: 5px solid red;
position: absolute;
width: 100%;
}
section.one {
z-index: 1;
top: 0%;
}
section.two {
border: 5px solid green;
z-index: 2;
top: 100%;
}
section.three {
z-index: 3;
top: 200%;
}
section.fix {
position: fixed;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="one">
1
</section>
<section class="two">
2
</section>
<section class="three">
3
</section>
I would update your jQuery to the snippet below. It checks the position of section one against the height of the window and if less than, or equal to it removes the .fix class.
$(window).on('scroll', function() {
var scrollTop = $(window).scrollTop();
sectionone = $('section.one').offset().top;
sectiontwo = $('section.two').offset().top;
sectiontwodistance = (sectiontwo - scrollTop);
sectiononedistance = (sectionone - scrollTop);
console.log(sectiononedistance);
if (sectiontwodistance < 1) {
$('section.two').addClass('fix');
}
if (Math.abs(sectiononedistance) <= $(window).height()) {
$('section.two').removeClass('fix');
}
});
Here is an example of what i want to achieve:
https://www.flambette.com/en/
I have tried to change the css properties of images but that effect does not satisfy my needs.
I have tried the following code:
mydocument.on('scroll',function() {
if (mydocument.scrollTop() > 10 && mydocument.scrollTop() < 200 ) {
$('#first').css('top', '320px');
$('#first').css('left', '215px');
$('#first').css('transition', '0.5s');
}
else {
$('#first').css('top', '300px');
$('#first').css('left', '200px');
$('#first').css('transition', '0.5s');
}
});
This is supposed to move an image when you scroll between 10 and 200 px.
var container = document.getElementById('container');
var windowHeight = window.innerHeight;
var windowWidth = window.innerWidth;
var scrollArea = 1000 - windowHeight;
var square1 = document.getElementsByClassName('square')[0];
var square2 = document.getElementsByClassName('square')[1];
// update position of square 1 and square 2 when scroll event fires.
window.addEventListener('scroll', function() {
var scrollTop = window.pageYOffset || window.scrollTop;
var scrollPercent = scrollTop/scrollArea || 0;
square1.style.left = scrollPercent*window.innerWidth + 'px';
square2.style.left = 800 - scrollPercent*window.innerWidth*0.6 + 'px';
});
body {
overflow-x: hidden;
}
.container {
width: 100%;
height: 1000px;
}
.square {
position: absolute;
}
.square-1 {
width: 100px;
height: 100px;
background: red;
top: 600px;
}
.square-2 {
width: 120px;
height: 120px;
background: black;
left: 800px;
top: 800px;
}
<div class="container" id="container">
<div class="square square-1"></div>
<div class="square square-2"></div>
</div>
Hope to help you.
Here you can see more examples about movable elements and scroll events.
i need some help about finding elements position.
im working on an e-book reader, also its all Html with css.
All html sectioned page by page, and i have to find an element like this
<span name="Note" style="background-color:rgb(255,255,204)">Example</span>
Everyone suggests code like this;
function position(elem) {
var left = 0,
top = 0;
do {
left += elem.offsetLeft;
top += elem.offsetTop;
} while ( elem = elem.offsetParent );
return [ left, top ];
}position(document.getElementsByName('Note')[0]);
but it does not work for me; I need element's real position in scroll with JavaScript.
var note = document.getElementsByName('Note')[0];
var screenPosition = note.getBoundingClientRect();
The ClientRect returned by getBoundingClientRect() has values for .top, .left, .right, .bottom, .width, and .height.
These are pixel positions on the visible window; as you scroll the page the .top and .bottom values will change, and may even become negative as the item scrolls off the top of the view.
Note that—unlike the solution accumulating offsetLeft/offsetTop—this solution properly accounts for borders and padding on the body and html elements in all browsers (Firefox).
See this test case: http://jsfiddle.net/QxYDe/4/ (scroll the page and watch the values change).
Also supported by Internet Explorer.
function position(elem) {
var left = 0,
top = 0;
do {
left += elem.offsetLeft-elem.scrollLeft;
top += elem.offsetTop-elem.scrollTop;
} while ( elem = elem.offsetParent );
return [ left, top ];
}
var elem = document.getElementById('id');
position(elem);
Subtract the scroll positions.
My guess is that you need the note to stay fixed to the top left corner at all times? Even when scrolled?
You can do this with CSS only! :)
HTML:
<div id="Note" name="Note">Example</div>
CSS:
div #Note {
background-color:rgb(255,255,204)
left: 0px;
position: absolute;
top: 0px;
z-index: 999;
}
#media screen {
body > div #Note {
position: fixed;
}
}
EDIT:
With several notes (not tested):
HTML:
<div id="Note1">Example</div>
<div id="Note2">Example</div>
<div id="Note3">Example</div>
<div id="Note4">Example</div>
CSS:
div #Note1 {
background-color:rgb(255,255,204)
left: 0px;
height: 20px;
position: absolute;
top: 0px;
z-index: 999;
}
div #Note2 {
background-color:rgb(255,255,204)
left: 0px;
height: 20px;
position: absolute;
top: 20px;
z-index: 999;
}
div #Note3 {
background-color:rgb(255,255,204)
left: 0px;
height: 20px;
position: absolute;
top: 40px;
z-index: 999;
}
div #Note4 {
background-color:rgb(255,255,204)
left: 0px;
height: 20px;
position: absolute;
top: 60px;
z-index: 999;
}
#media screen {
body > div #Note1 {
position: fixed;
}
body > div #Note2 {
position: fixed;
}
body > div #Note3 {
position: fixed;
}
body > div #Note4 {
position: fixed;
}
}
Solution to find an element position for scroll:
const target = document.querySelector('[name="Note"]')
window.scrollTo({
top: Math.round(target.getBoundingClientRect().top + document.documentElement.scrollTop),
behavior: 'smooth',
})
Or just use scrollIntoView:
document.querySelector('[name="Note"]').scrollIntoView({
behavior: 'smooth',
})
First you need to get the height of entire document. Height of the whole document, with the scrolled out part: link
let scrollHeight = Math.max(
document.body.scrollHeight, document.documentElement.scrollHeight,
document.body.offsetHeight, document.documentElement.offsetHeight,
document.body.clientHeight, document.documentElement.clientHeight
);
After you can use to get element's scrollTop position:
const element = document.getElementsByName('Note');
element.scrollTop
Or you can go to element on view (scrollIntoView)
I'm not sure what you want to do after get the scrollTop position.
Solution:
<script>function showDiv() {
var div = document.getElementById('comdiv');
var button = document.getElementById('button');
if (div.style.display !== "none") {
div.style.display = "none";
button.value = "Add Comments";
}
else {
button.value = "Hide Comments";
div.style.display = "block";
}
var note = document.getElementsByName("comment")[0];
var screenPosition = note.getBoundingClientRect();
window.scrollTo(screenPosition);
}</script>
<form name="form" id="form" action="" method="post">
<textarea name="comment" id="comment" placeholder="Write Comment, Max: 140 characters" rows="4" class="width-50" onblur="checkMe()" ></textarea>
<input type="text" class="input-small width-33" name="name" id="name" placeholder="Name" autofocus class="width-33" onblur="checkMe()" />
<button type="submit" name="submit" id="submitbutton" class="btn btn-green btn-outline" disabled="disabled">Post Comment</button>
</form>
In ANGULAR:
import { ViewChild, AfterViewInit } from '#angular/core';
...
export class NewTrendingComponent implements AfterViewInit {
#ViewChild('theElementInQuestion') public trendyElement!: ElementRef;
ngAfterViewInit(): void {
// log the top pixel value of the element in question
console.log(this.trendyElement.nativeElement.offsetTop)
}
}
...
<div #theElementInQuestion> this is the element you are looking for... </div>
...
Note: if you are using structural directives like ngIf, you want to look into when exactly the element will render (usually with / after after ViewInit if | async). Or look into using the {static: true} option.
#ViewChild('theElementInQuestion', {static: true}) public trendyElement!: ElementRef;