jQuery - element crossing another element - javascript

I have a fixed div on the page which contains a logo and as the user scrolls and this logo passes over other divs I wnat to the change the colour of the logo.
I have this working over a single div but need to it work across multiple so any help appreciated.
The WIP site can be seen here... dd.mintfresh.co.uk - if you scroll down you'll (hopefully) see the logo change from black to white as it crosses an illustrated egg. I need the same to happen when it crosses other divs further down the page.
The script so far...
jQuery(window).scroll(function(){
var fixed = jQuery("logo");
var fixed_position = jQuery("#logo").offset().top;
var fixed_height = jQuery("#logo").height();
var toCross_position = jQuery("#egg").offset().top;
var toCross_height = jQuery("#egg").height();
if (fixed_position + fixed_height < toCross_position) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else if (fixed_position > toCross_position + toCross_height) {
jQuery("#logo img").css({filter : "invert(100%)"});
} else {
jQuery("#logo img").css({filter : "invert(0%)"});
}
}
);
Any help appreciated. Thanks!

you need to fire a div scroll event. you can assign
$("div1").scroll(function(){
//change the color of the div1
}
});
$("div2").scroll(function(){
//change the color of the div2
}
});
or you can assign a class to divs which you want to change the color
$(".div").scroll(function(){
//change the color of the div which you are scrolling now
}
});

You can use like this :-
$(window).scroll(function() {
var that = $(this);
$('.section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('active')) {
$('.logo').addClass('invert');
} else {
$('.logo').removeClass('invert');
}
}
});
});
body {
padding: 0;
margin: 0;
}
div {
background: #f00;
height: 400px;
}
.logo {
position: fixed;
top: 0;
left: 0;
width: 100px;
}
.logo.invert {
filter: invert(100%);
}
div:nth-child(even) {
background: #ff0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://dd.mintfresh.co.uk/wp-content/uploads/2018/06/DD_logo.svg" class="logo" />
<div id="page1" class="section"></div>
<div id="page2" class="section active"></div>
<div id="page3" class="section"></div>
<div id="page4" class="section active"></div>
<div id="page5" class="section"></div>
As your site code you can do like this :
$(window).scroll(function() {
var that = $(this);
$('#content > section').each(function() {
var s = $(this);
if (that.scrollTop() >= s.position().top) {
if(s.hasClass('black')) {
$('#logo img').css({filter: 'invert(0%)'});
} else {
$('#logo img').css({filter: 'invert(100%)'});
}
}
});
});

Related

display sticky div if within viewport

I am basing my code off of this SO thread.
I have a parent div that is half way down the page. Within that parent div I want to display a sticky footer div, but only when viewport is showing the parent div. I have tried 4 different tutorials so far with no luck.
The page structure is this:
HEADER
HERO
CONTENT RIGHT-SIDE(id="wrap-vs")
CONTENT-FULL-WIDTH
FOOTER
When RIGHT-SIDE is within view, I want to display a sticky div within it. You can't see RIGHT-SIDE when page loads, you need to scroll down to it. Also, when we are below it I want the sticky div to go away.
var targetdiv = document.querySelector('.tabs');
console.log(targetdiv);
targetdiv.style.display = "none";
function CheckIfVisible(elem, targetdiv) {
var ElemPos = elem.getBoundingClientRect().top;
targetdiv.style.display = (ElemPos > 0 && ElemPos < document.body.parentNode.offsetHeight) ? "block" : "none";
}
window.addEventListener("onscroll", function() {
var elem = document.querySelector('#wrap-vs');
CheckIfVisible(elem, targetdiv);
});
#wrap-vs {
height: 100%;
background-color: yellow;
}
.tabs {
position: fixed;
bottom: 0;
}
<div id="wrap-vs">
<div class="tabs">
right-side content sticky div
</div>
</div>
This is how I fixed it:
// Create a new observer
var observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
// Log if the element and if it's in the viewport
console.log(entry.isIntersecting);
if(entry.isIntersecting == true){
document.querySelector('.tabs').style.display = 'block';
} else {
document.querySelector('.tabs').style.display = 'none';
}
});
});
// The element to observe
var app = document.querySelector('#wrap-vs');
// Attach it to the observer
observer.observe(app);
#wrap-vs {
height: 100%;
background-color: yellow;
}
.tabs {
position: fixed;
bottom: 0;
}
<div id="wrap-vs">
<div class="tabs">
right-side content sticky div
</div>
</div>

How to detect correct div data attribute when each hitting the top of the page

I am working on the below code. Why am I not able to detect which div is reaching at the top of page in both down or up scroll?
$(window).scroll(function() {
$(".container").each(function() {
var $that = $(this);
var po = $(this).offset().top;
if (po >= 0 && po <= 300) {
console.log($that.data('map'));
}
});
});
.container {
height: 690px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container" data-map="One">One</div>
<div class="container" data-map="Two">Tow</div>
<div class="container" data-map="Three">Three</div>
<div class="container" data-map="Four">Four</div>
<div class="container" data-map="Five">Five</div>
You'll need to use $(window).scrollTop(); as well as $that.outerHeight()
$(window).scroll(function() {
var windowScrollTop = $(this).scrollTop(); // window scroll top
$(".container").each(function() {
var $that = $(this);
var po = $that.offset().top;
var poHeight = $that.outerHeight(true); // the height of the element
var distanceTop = 100; // the distance from top to run the action .. it can be 0 if you want to run the action when the element hit the 0 top
if (windowScrollTop + distanceTop >= po && windowScrollTop + distanceTop <= po + poHeight) {
if(!$that.hasClass('red')){ // if element dosen't has class red
console.log($that.data('map'));
$(".container").not($that).removeClass('red'); // remove red class from all
$that.addClass('red'); // add red class to $that
}
}
});
}).scroll(); // run the scroll onload
.container {
height: 690px;
}
.container.red{
background : red;
color : #fff;
font-size: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container" data-map="One">One</div>
<div class="container" data-map="Two">Two</div>
<div class="container" data-map="Three">Three</div>
<div class="container" data-map="Four">Four</div>
<div class="container" data-map="Five">Five</div>

How to scroll from waypoint to waypoint in jQuery?

In my webpage I have 4 "waypoints" that have their respective links in a menu. What I need is to also bind the scroll of the page to these waypoints. So when the page loads, the pointer is at the top and based on the scrolling direction, the page moves to the next/previous waypoint. Until now I have come up with this simplistic approach, which goes into a scroll loop due to the scrollTo() function triggering the whole method again.
$(function () {
var top = $(window).scrollTop();
var currentWaypoint = 0;
var previousWaypoint = 0;
$(window).scroll(function () {
console.log("Scroll triggered");
console.log("Current Waypoint: " + currentWaypoint);
var curTop = $(window).scrollTop();
if (top < curTop) {
if (currentWaypoint < 4) {
previousWaypoint = currentWaypoint;
currentWaypoint=currentWaypoint+1;
}
}
else {
if (currentWaypoint > 0) {
previousWaypoint = currentWaypoint;
currentWaypoint=currentWaypoint-1;
}
}
top = curTop;
if (previousWaypoint != currentWaypoint) {
switch (currentWaypoint) {
case 1:
$.scrollTo(document.getElementById("waypoint-collection"));
case 2:
$.scrollTo(document.getElementById("waypoint-report"));
case 3:
$.scrollTo(document.getElementById("waypoint-video"));
case 4:
$.scrollTo(document.getElementById("waypoint-mail"));
default:
}
}
console.log("New Waypoint: " + currentWaypoint);
});
});
I've seen this sort of behaviour implemented in some websites but cannot seem to find anything relevant with google. Any ideas?
EDIT:
The relevant HTML code:
<html>
<head>
<style>
body {
background-color: #FFFFFF;
}
.features-container-wh {
min-height: 12.5rem;
text-align: center;
height: 100%;
}
.features-container-bl {
background-color: #43bfcb;
text-align: center;
color: #FFFFFF;
height: 100%;
}
.features-container-bottom {
height: 100%;
}
</style>
</head>
<body>
<div class="features-container-wh">
Collection
Report
Video
Mail
</div>
<div class="features-container-bl" id="waypoint-collection">
<p>Stuff...</p>
</div>
<div class="features-container-wh" id="waypoint-report">
<p>Stuff...</p>
</div>
<div class="features-container-bl" id="waypoint-video">
<p>Stuff...</p>
</div>
<div class="features-container-bottom" id="waypoint-mail">
<p>Stuff...</p>
</div>
</body>
$('html, body').animate({scrollTop: $("#.wayPoint1").offset().top}, 2000);

swap div's position from top div's

I am trying to swap a div's position from top on and when I click another div then top div can be swap.
HTML
<div class="wrap top">
<input type="text" value="div1" class="textbox " />
</div>
<div class="wrap">
<input type="text" value="div2" class="textbox " />
</div>
<div class="wrap">
<input type="text" value="div3" class="textbox " />
</div>
jQuery
(function ($) {
$(".wrap").on("click", function () {
if ($(this).index() == 0) {
} else {
$(this).insertBefore($(this).prev());
}
});
}(jQuery));
The fact is I don't want to remove the div which I click instead want to swap the positions around.
How Can I do this using jQuery itself?
I would suggest using css to position the top div and just swap the class as follows:
(function ($) {
$(".wrap").on("click", function () {
if ($(this).index() == 0) {
} else {
$(".wrap").removeClass("top");
$(this).addClass("top");
}
});
}(jQuery));
this will swap whatever you click with the first element.
$(".wrap").on("click", function () {
var $this = $(this);
if ($this.index() == 0) {
} else {
var first = $this.siblings('.wrap').first();
first.insertBefore($this);
$this.prependTo($this.parent());
}
});
if you just want to move the clicked element to the top, you can simply do
$this.prependTo($this.parent());
To swap the two DOM elements using jQuery, you could use something like this: -
(function($) {
$(".wrap").on("click", function(event) {
var index = $(event.target).index();
var first = $(".wrap").first();
if (index > 0) {
$(first).swapWith(this);
}
});
}(jQuery));
jQuery.fn.swapWith = function(to) {
return this.each(function() {
var copy_to = $(to).clone(true);
var copy_from = $(this).clone(true);
$(to).replaceWith(copy_from);
$(this).replaceWith(copy_to);
});
};
.wrap {
height: 100px;
width: 200px;
margin: 10px 10px 10px 10px;
background-color: #2d8cd0;
}
h2 {
color: white;
text-align: center;
padding-top: 20px;
pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="wrap">
<h2>1</h2>
</div>
<div class="wrap">
<h2>2</h2>
</div>
<div class="wrap">
<h2>3</h2>
</div>
<div class="wrap">
<h2>4</h2>
</div>

How can I change the x position of a div via javascript when I click on another div this way?

<body>
<div id = "SiteContainer">
<div id = "NavigationButtons"></div>
<div id = "ShowReelContainer">
<div id= "NavigationBackward" name = "back" onclick="setPosition();">x</div>
<div id= "NavigationForward" name = "forward" onclick="setPosition();">y</div>
<div id = "VideoWrapper">
<div id = "SlideShowItem">
<img src="Images/A.png" alt="A"></img>
</div>
<div id = "SlideShowItem">
<img src="Images/B.png" alt="B"></img>
</div>
<div id = "SlideShowItem">
<img src="Images/C.png" alt="C" ></img>
</div>
</div>
</div>
</div>
<script>
var wrapper = document.querySelector("#VideoWrapper");
function setPosition(e)
{
if(e.target.name = "forward")
{
if!(wrapper.style.left = "-200%")
{
wrapper.style.left = wrapper.style.left - 100%;
}
}
else
{
if(e.target.name = "back")
{
if!(wrapper.style.left = "0%")
{
wrapper.style.left = wrapper.style.left + 100%;
}
}
}
}
</script>
</body>
Hi, I am very new to javascript. What I am trying to do, is change the x-position of a div when another div (NavigationForward or NavigationBackward) is clicked. However it does not appear to do anything at all. Basically if the div with name forward is clicked, I want to translate the VideoWrapper -100% from it's current position and +100% when "back". The css div itself VideoWrapper has a width of 300%. Inside this div as you can see is a SlideShowItem which is what will change. Perhaps I am adding and subtracting 100% the wrong way?
EDIT:
Thanks everyone for helping me out with this...I had just one more query, I am trying to hide the arrows based on whether the wrapper is at the first slide or the last slide. If its on the first slide, then I'd hide the left arrow div and if it's on the last, I'd hide the right arrow, otherwise display both of em. Ive tried several ways to achieve this, but none of em work, so Ive resorted to using copies of variables from the function that works. Even then it does not work. It appears that my if and else if statements always evaluate to false, so perhaps I am not retrieving the position properly?
function HideArrows()
{
var wrapper2 = document.getElementById("VideoWrapper");
var offset_x2 = wrapper2.style.left;
if(parseInt(offset_x2,10) == max_x)
{
document.getElementById("NavigationForward").display = 'none';
}
else if(parseInt(offset_x2,10) == min_x)
{
document.getElementById("NavigationBackward").display = 'none';
}
else
{
document.getElementById("NavigationForward").display = 'inline-block';
document.getElementById("NavigationBackward").display = 'inline-block';
}
}
//html is the same except that I added a mouseover = "HideArrows();"
<div id = "ShowReelContainer" onmouseover="HideArrows();">
To achieve this type o slider functionality your div VideoWrapper must have overflow:hidden style, and your SlideShowItemdivs must have a position:relative style.
Then to move the slides forward or backward you can use the style left which allows you to move the divs SlideShowItem relative to it's parent VideoWrapper.
I've tested this here on JSFiddle.
It seems to work as you described in your question, although you may need to do some adjustments, like defining the width of your slides, how many they are and so on.
For the sake of simplicity, I defined them as "constants" on the top of the code, but I think you can work from that point on.
CSS
#VideoWrapper{
position:relative; height:100px; white-space:nowrap;width:500px;
margin-left:0px; border:1px solid #000; overflow:hidden; }
.SlideShowItem{
width:500px; height:100px;display:inline-block;position:relative; }
#NavigationForward, #NavigationBackward{
cursor:pointer;float:left; background-color:silver;margin-right:5px;
margin-bottom:10px; text-align:center; padding:10px; }
HTML
<div id = "SiteContainer">
<div id = "NavigationButtons">
</div>
<div id = "ShowReelContainer">
<div id= "NavigationBackward" name = "back" onclick="setPosition('back');">prev</div>
<div id= "NavigationForward" name = "forward" onclick="setPosition('forward');">next</div>
<div style="clear:both;"></div>
<div id = "VideoWrapper">
<div class= "SlideShowItem" style="background-color:blue;">
Slide 1
</div>
<div class = "SlideShowItem" style="background-color:yellow;">
Slide 2
</div>
<div class = "SlideShowItem" style="background-color:pink;">
Slide 3
</div>
</div>
</div>
</div>
JavaScript
var unit = 'px'; var margin = 4; var itemSize = 500 + margin; var itemCount = 3; var min_x = 0; var max_x = -(itemCount-1) * itemSize;
function setPosition(e) {
var wrapper = document.getElementById("VideoWrapper");
var slides = wrapper.getElementsByTagName('div');
var offset_x = slides[0].style.left.replace(unit, '');
var curr_x = parseInt(offset_x.length == 0 ? 0 : offset_x);
if(e == "forward")
{
if(curr_x <= max_x)
return;
for(var i=0; i<slides.length; i++)
slides[i].style.left= (curr_x + -itemSize) + unit;
}
else if(e == "back")
{
if(curr_x >= min_x)
return;
for(var i=0; i<slides.length; i++)
slides[i].style.left= (curr_x + itemSize) + unit;
} }
After you analyze and test the code, I don't really know what's your purpose with this, I mean, you maybe just playing around or trying to develop something for a personal project, but if you are looking for something more professional avoid to create things like sliders on your own, as there are tons of plugins like this available and well tested out there on the web.
Consider using jQuery with NivoSlider, it works like a charm and is cross browser.
I would recommend using jQuery, this will reduce your coding by quite a bit. Can read more here: http://api.jquery.com/animate/
I've created a simple fiddle for you to take a look at. This example uses the .animate() method to reposition two div elements based on the CSS 'left' property.
CSS:
#container {
position: absolute;
left: 1em;
top: 1em;
right: 1em;
bottom: 1em;
overflow: hidden;
}
#one, #two {
position: absolute;
color: white;
}
#one {
background: pink;
width: 100%;
top:0;
bottom:0;
}
#two {
background: blue;
width: 100%;
left: 100%;
top:0;
bottom:0;
}
HTML:
<div id="container">
<div id="one">Div One</div>
<div id="two">Div Two</div>
</div>
JavaScript/jQuery:
var one, two, container;
function animateSlides(){
one.animate({
left : '-100%'
}, 1000, function(){
one.animate({
left : 0
}, 1000);
});
two.animate({
left : 0
}, 1000, function(){
two.animate({
left:'100%'
}, 1000);
});
};
$(function(){
one = $('#one');
two = $('#two');
container = $('#container');
setInterval(animateSlides, 2000);
});
JSFiddle Example: http://jsfiddle.net/adamfullen/vSSK8/3/

Categories

Resources