I have a one page, scrolling site with 5 main sections that have title bars that span across the top of each respective section. I want each title bar to stick at the top (well, relative top-underneath the top sticky header) as you scroll down the section. I can get one to stick, but I am having trouble making it so that one sticks and then it goes away once the next section's title bar gets to the sticky point.
I can't figure out another way to bind the HTML or CSS with the jQuery if else statement to make this work. I was thinking I could try to make it work within each sections' id but I don't think there's like a "withinId" jQuery selector.
I'm posting the latest jQuery I attempted (with just 2 out of the 5 variables I will need to make work here). I know it's wrong but I'm seriously stuck. Any ideas here? Thanks a million.
(abbreviated) HTML:
<div id="welcome">
<div class="title-bar">
<p>WELCOME</p>
</div>
</div>
<div id="global">
<div class="title-bar">
<p>GLOBAL ENGAGEMENT</p>
</div>
</div>
<div id="community">
<div class="title-bar">
<p>COMMUNITY</p>
</div>
</div>
<div id="resources">
<div class="title-bar">
<p>RESOURCES</p>
</div>
</div>
<div id="horizon">
<div class="title-bar">
<p>ON THE HORIZON</p>
</div>
</div>
CSS:
.title-bar {
padding: 5px;
position: relative;
}
.title-bar.sticky {
position: fixed;
top: 111px;
width: 100%;
z-index: 1040;
}
jQuery:
$(document).ready(function() {
var welcomeTitle = $('#welcome .title-bar');
var globalTitle = $('#global .title-bar');
var communityTitle = $('#community .title-bar');
var resourcesTitle = $('#resources .title-bar');
var horizonTitle = $('#horizon .title-bar');
var stickyOffset = $('#header').offset().top;
if ($w.scrollTop() > stickyOffset + 225) {
welcomeTitle.addClass('sticky');
globalTitle.addClass('sticky');
} else {
welcomeTitle.removeClass('sticky');
globalTitle.addClass('sticky');
}
if (welcomeTitle.hasClass('sticky') && globalTitle.hasClass('sticky')) {
welcomeTitle.removeClass('sticky');
} else {
//
}
});
jsBin demo
Give your "pages" a class="page" and listen for their positions using JS's Element.getBoundingClientRect on: DOM Ready, window Load, window Scroll
$(function() { // DOM ready
var $win = $(window),
$page = $(".page").each(function(){
// Memorize their titles elements (performance boost)
this._bar = $(this).find(".title-bar");
});
function fixpos() {
$page.each(function(){
var br = this.getBoundingClientRect();
$(this._bar).toggleClass("sticky", br.top<0 && br.bottom>0);
});
}
fixpos(); // on DOM ready
$win.on("load scroll", fixpos); // and load + scroll
});
*{box-sizing: border-box;}
html, body{height:100%;}
body{margin:0;font:16px/1 sans-serif; color:#777;}
.page{
position:relative;
min-height:100vh;
}
.title-bar {
position: absolute;
top:0;
width: 100%;
background:#fff;
box-shadow: 0 3px 4px rgba(0,0,0,0.3);
}
.title-bar.sticky {
position: fixed;
}
#welcome {background:#5fc;}
#global {background:#f5c;}
#community{background:#cf5;}
#resources{background:#fc5;}
#horizon {background:#5cf;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="welcome" class="page">
<div class="title-bar">
<h2>WELCOME</h2>
</div>
</div>
<div id="global" class="page">
<div class="title-bar">
<h2>GLOBAL ENGAGEMENT</h2>
</div>
</div>
<div id="community" class="page">
<div class="title-bar">
<h2>COMMUNITY</h2>
</div>
</div>
<div id="resources" class="page">
<div class="title-bar">
<h2>RESOURCES</h2>
</div>
</div>
<div id="horizon" class="page">
<div class="title-bar">
<h2>ON THE HORIZON</h2>
</div>
</div>
Design-wise > add a padding-top to the first container element (inside your .page) to prevent content going underneath the title element (since it toggles from absolute/fixed positions).
Have a look at the Waypoints plugin.
You can probably make it a little easier on yourself by assigning each section a class and then add and remove the class from each section with jquery each function.
Try something like the following:
$(window).on( "scroll", function() {
$( ".section" ).each(function() {
if ( $(window).scrollTop() >= $(this).offset().top - 50 ) {
$( this ).addClass("sticky");
}else{
$( this ).removeClass("sticky");
}
});
});
Then your css
.section{
height: 200px;
background: #333;
border:1px solid #222;
position:relative;
}
.section .title-bar{
position:absolute;
top:0;
left:0;
width:100%;
height:50px;
}
.section.sticky .title-bar {
position:fixed;
}
And html
<div class="section">
<div class="title-bar"></div>
</div>
<div class="section">
<div class="title-bar"></div>
</div>
<div class="section">
<div class="title-bar"></div>
</div>
Related
I have three columns, in each column I have a number of blocks. On scroll the first block in each column should be fixed to the top. When you scroll down to the bottom of each column the first block should dissappear, when you scroll back up and hit the bottom of the column the first block should be fixed again.
Can anyone help me out. I'm using Vanilla JS
{
var stick = document.querySelectorAll(".stick");
window.onscroll = function() {
stickIt();
};
}
function stickIt() {
for (var i = 0; i < stick.length; i++) {
var sticky = stick[i].offsetTop;
if (window.pageYOffset >= sticky) {
stick[i].classList.add("sticky");
} else {
stick[i].classList.remove("sticky");
}
}
}
header{
height:300px;
background:#ccc;
}
.block.stick {
background: #333;
}
.block {
height: 200px;
background:#ccc;
}
section{
height:1000px;
background:#999;
}
.sticky {
position: fixed;
top: 0;
z-index:1;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/foundation/4.1.2/css/foundation.css">
<header></header>
<div class="row">
<div class="small-4 columns">
<div class="stick block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="small-4 columns">
<div class="stick block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
<div class="small-4 columns">
<div class="stick block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
</div>
<section></section>
I would advise you to take a look at CSS Flexbox. You can accomplish 99% of your goal using only CSS. Once you get your layout, then it's as simple as toggle a class on the parent based on scroll position.
Check out this great write up.
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
First of all I'm as newbie in this area. I tried to search about this but nothing fits on what I want.
So I have this html:
<aside>
<div align="center">
<img src="images/teste.jpg" style="width:200px;height:200px;">
</div>
...
<div id="disciplinas">
<h3>Disciplinas:</h3>
<li>x</span></li>
<li>y</span></li>
<li>z</span></li>
<li>w</span></li>
<br/>
</div>
</aside>
<div id="main">
<section id="x">
<div>
<img src="images/teste.jpg">
</div>
</section>
<section id="y">
<div>
<img src="images/teste.jpg">
</div>
</section>
...
I tried this code but didn't work:
<script type="text/javascript">
$(document).ready(function(){
var scroll_pos = 0;
$(document).scroll(function() {
scroll_pos = $(this).scrollTop();
if(scroll_pos > 210) {
$("li").css('background-color', 'blue');
} else {
$("li").css('background-color', 'red');
}
});
});
</script>
I would like to know how can i change the color of the <li> on scroll, when they get to the correct section (or maybe i need to use a div instead).
Thanks
If it helps, the css of div disciplinas and li:
#disciplinas {
border: 1px solid;
margin-top: 5%;
margin-bottom: 5%;
text-align: center;
box-shadow: 10px 10px 5px #DCDCDC;
background-color: white;
}
li {
text-align: center;
list-style-type: none;
}
Try using this code,
$(window).scroll(function () {
var scroll_pos= $(window).scrollTop();
if(scroll_pos > 210) {
$("li").css('background-color', 'blue');
} else {
$("li").css('background-color', 'red');
}
});
hope it helps.
Add jquery library js file
Remove unnecessary html tag
<aside>
<div align="center">
<img src="images/teste.jpg" style="width:200px;height:200px;">
</div>
...
<div id="disciplinas">
<h3>Disciplinas:</h3>
<li>x</li>
<li>y</li>
<li>z</li>
<li>w</li>
<br/>
</div>
</aside>
<div id="main">
<section id="x">
<div>
<img src="images/teste.jpg">
</div>
</section>
<section id="y">
<div>
<img src="images/teste.jpg">
</div>
</section>
https://jsfiddle.net/rq6rgrcj/
Check this codepen:
http://codepen.io/yuki-san/pen/eJqLNO
You can see the idea and how the sections are tied to the scrolling event.
Now use that and just change the li background color instead of underline
Create a css class lets say - scrollColor and add it using jQuery
.addClass(".scrollColor")
when the window scrolled to the right place and remove it when scrolled away
I am new to stackoverflow and can't seem to find an answer to my issue - please put link to similar question if I missed it, but I have gave it a strong gander already.
I am making a portfolio site and when a user clicks a project, the clicked div slides out and the bottom div is revealed with the project case study.
The problem: When user scrolls down to project thumbs on sliding div, the lower div scrolls with it - therefore when the user clicks the project, the case study is already scrolled down. I need it to reveal with the case study at scrolltop(0)
Here is a simplified version of what I have so you can get an idea:
// View Project Details (user clicks thumbnail from LP) CTA function
$(".projThumb").click(function()
{
$("#nav-icon3").toggleClass('open');
$(".projDetails").fadeIn( 500 );
// $('.lowerContainer').css('position','absolute');
$('.mainContentWrap').openSlide();
var id = $(this).attr('id');
if(id == 'Proj1')
{
$("#Proj1_Details").fadeIn( 500 );
//get persona image height so background shape is proportional
var personaImgHeight = parseInt($("#personaImg1").height());
$(".containImg").css("height", personaImgHeight + "px");
$(".personaImgWrap").css("height", personaImgHeight + "px");
} else if (id == 'Proj2') {
$("#Proj2_Details").fadeIn( 500 );
//get persona image height so background shape is proportional
var personaImgHeight = parseInt($("#personaImg2").height());
$(".containImg").css("height", personaImgHeight + "px");
$(".personaImgWrap").css("height", personaImgHeight + "px");
} else if (id == 'Proj3') {
$("#Proj3_Details").fadeIn( 500 );
//get persona image height so background shape is proportional
var personaImgHeight = parseInt($("#personaImg3").height());
$(".containImg").css("height", personaImgHeight + "px");
$(".personaImgWrap").css("height", personaImgHeight + "px");
} else if (id == 'Proj4') {
$("#Proj4_Details").fadeIn( 500 );
};
});
.lowerContainer
{
width:80%;
max-width: 2050px;
height: auto;
min-height:100vh;
margin:0 auto;
background:#f9f9f9;
position: relative;
/*left:10%;*/
}
.revealPanel
{
width: 100%;
min-height:100vh;
float: left;
margin-top:0;
overflow-y:scroll;
padding:0;
/*position: fixed;*/
}
.mainContent
{
width:80%;
max-width: 2050px;
height:auto;
top:0px;
left: 0px;
right: 0;
margin-top: 0;
margin-right:auto;
margin-bottom:0;
margin-left:auto;
position: absolute;
z-index: 1000;
overflow-x: hidden;
overflow-y: scroll;
opacity: 1;
}
.mainContentWrap
{
width:100%;
overflow:auto;
}
<div class="lowerContainer group">
<section class="revealPanel group">
<!-- ******************************
PROJECT CASE STUDY GOES HERE
******************************** -->
</section> <!-- /revealPanel -->
</div> <!-- /lowerContainer -->
<div class="mainContent">
<div class="mainContentWrap">
<!-- ******************************
MY WORK SECTION
******************************** -->
<div class="myWork group">
<!-- Project container (Contains project thumbnails ) -->
<div class="projContainer">
<h3 class="secTitle">Recent Work</h3>
<div class="projectsWrap">
<div class="row">
<!-- Project 1 -->
<div class="projects col-lg-6 col-md-12">
<div class="projThumb" id="Proj1">
<img src="assets/proj1.png" width="100%" alt="">
</div>
</div>
<!-- Project 2 -->
<div class="projects col-lg-6 col-md-12">
<div class="projThumb" id="Proj2">
<img src="assets/proj2.png" width="100%" alt="">
</div>
</div>
<!-- Project 3 -->
<div class="projects col-lg-6 col-md-12">
<div class="projThumb" id="Proj3">
<img src="assets/proj3.png" width="100%" alt="">
</div>
</div>
<!-- Project 4 -->
<div class="projects col-lg-6 col-md-12">
<div class="projThumb" id="Proj4">
<img src="assets/proj4.png" width="100%" alt="">
</div>
</div>
</div> <!-- /row -->
</div> <!-- /projectWrap -->
</div> <!-- projectsWrap -->
<!-- <div class="triBg" id="triBg-myWork"></div> -->
</div> <!-- /myWork -->
</div>
</div> <!-- /mainContent -->
Based on what you said you want to happen, without really looking at your massive amount of code, I think you are over complicating this.
You can make use of jQuery's .slideToggle() http://api.jquery.com/slidetoggle/
You can also utilize the fact that you can have multiple elements with the same class to help minimize the amount of repeated code.
$(document).on('click', '.projectButton', function(){
$(this).siblings('.projectInfo').slideToggle();
});
.projectInfo {
display: none;
}
.projectButton {
height: 25px;
background: gray;
cursor: pointer;
border: 1px solid white;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="projectsContainer">
<div class="project" id="project1">
<div class="projectButton">Project 1</div>
<div class="projectInfo">Project 1 information goes here</div>
</div>
<div class="project" id="project2">
<div class="projectButton">Project 2</div>
<div class="projectInfo">Project 2 information goes here</div>
</div>
<div class="project" id="project3">
<div class="projectButton">Project 3</div>
<div class="projectInfo">Project 3 information goes here</div>
</div>
<div class="project" id="project4">
<div class="projectButton">Project 4</div>
<div class="projectInfo">Project 4 information goes here</div>
</div>
</div>
Right now I have divs that show when you scroll past a certain mark but realized that this gets broken when the browser is resized. Is there any way I can make this responsive? I'm not sure if adding $(window).resize(checkY); would work either.
EDIT:
The end goal is to show the title when the associated content comes into view
HTML
<div class="title" data-position="400,1150">Yama</div>
<div class="title" data-position="1150,1800">Modurra</div>
<div class="title" data-position="1800,2600">Computer</div>
<div class="title" data-position="2600,3300">Maru</div>
<div class="title" data-position="3300,3900">Sushi</div>
<div class="title" data-position="3900,4700">Summit</div>
<div class="title" data-position="4700,10000">Lights Out</div>
JS
<script>
//Note you do not need to make an anonymous
//function just to do the call for checkY
//just pass the function
$(window).scroll(checkY);
function checkY() {
//save this value so we dont have to call the function everytime
var top = $(window).scrollTop();
console.log(top);
$(".title").each(function () {
var positionData = $(this).data("position").split(",");
if (top > positionData[0] && top <= positionData[1]) {
console.log("Show");
$(this).show();
} else {
console.log("Hide");
$(this).hide();
}
});
}
checkY();
</script>
EDIT
.title {
position:fixed;
top:0px;
left:45%;
display:none;
padding:10px;
background:rgba(255,255,255,0);
color:#000;}
#Yama {
position:absolute;
display:block;
height:900px;
font-family: Arial, Helvetica, sans-serif;
font-size:70pt;
letter-spacing:0px;
font-weight:100;
-webkit-font-smoothing: antialiased;
text-align:center;}
This is the wrapper holding everything.
#mini {width:100%; height:100%;
padding-top:140px;}
What you want to do is find the target content and determine if the element is within the viewport. If it is then you show the title.
With this you won't need to use data-* attributes. You can just put the title in the main content's element, and then use jQuery's .closest method to get the closest parent (the content element). And from there do the tests.
HTML
<div id="Yama" class="content">
<div class="title">Yama</div>
</div>
<div id="Modurra" class="content">
<div class="title">Modurra</div>
</div>
<div id="Computer" class="content">
<div class="title">Computer</div>
</div>
<div id="Maru" class="content">
<div class="title">Maru</div>
</div>
<div id="Sushi" class="content">
<div class="title">Sushi</div>
</div>
<div id="Summit" class="content">
<div class="title">Sushi</div>
</div>
<div id="LightsOut" class="content">
<div class="title">Lights Out</div>
</div>
JS
$(window).scroll(checkY);
function checkY(){
var top = $(window).scrollTop();
$(".title").each(function(){
var target = $(this).closest(".content");
//The start range value is just offset().top
var tTop = target.offset().top;
//The end range value is the start range value plus
//the content elements height
var tBottom = tTop+target.outerHeight();
if(top >= tTop && top <= tBottom){
console.log("Show");
$(this).show();
} else {
console.log("Hide");
$(this).hide();
}
});
}
checkY();
JSFiddle Demo
I am creating a single page website with a fixed navigation. Within the navigation there are two containers, the one on the left contains a series of headers that change as you click the links on the right. I am setting the display on each of the classes containing the headers to 'none' and attempting to display them with Jquery when you click the links on the right. But nothing I am trying is working. Is it possible to get a smooth transition using the fade element and Jquery to achieve a series of headers that change upon clicking the links?
Here is my code:
<div class="single-page-nav">
<div class="nav-container">
<div style="max-width: 1200px; min-width: 960px; margin: 0 auto; position: relative;">
<div style="position: absolute; right: 0; top: 40px; z-index: 999999;">
Home
About Us
Practice Areas
Contact
</div>
</div>
<div class="left">
<div class="header001"><h1>Doug Peterson</h1></div>
<div class="header002"><h1>About Us.</h1></div>
<div class="header003"><h1>Practice Areas.</h1></div>
<div class="header004"><h1>Contact.</h1></div>
</div>
<div class="nav"></div>
<div class="clearboth"></div>
</div>
</div>
Help the student.
Here is a basic working version of what it sounds like you want. You will need to style it to look the way you want, but the behavior (showing/hiding divs on click of the menu) is there. You might think about changing the naming scheme for hrefs and divs to make it easier to select the header div based on the link clicked.
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"> </script>
<style>
.header{
display: none;
}
</style>
<script>
$(document).ready(function() {
var selected = '';
$( "a", "#headerLinks" )
.on( "click", function(){
var divCls = ".header00" + $( this ).attr( "href" ).substring($( this ).attr( "href" ).length -1 );
if( selected.length > 0 ){
$( selected, "#headers" )
.hide('fade', function(){
$( divCls, "#headers" )
.show('fade');
});
}else{
$( divCls, "#headers" )
.show('fade');
}
selected = divCls;
});
});
</script>
</head>
<body>
<div class="single-page-nav">
<div class="nav-container">
<div style="max-width: 1200px; min-width: 960px; margin: 0 auto; position: relative;">
<div id="headerLinks" style="position: absolute; right: 0; top: 40px; z-index: 999999;">
Home
About Us
Practice Areas
Contact
</div>
</div>
<div class="left" id="headers">
<div class="header header001"><h1>Doug Peterson</h1></div>
<div class="header header002"><h1>About Us.</h1></div>
<div class="header header003"><h1>Practice Areas.</h1></div>
<div class="header header004"><h1>Contact.</h1></div>
</div>
<div class="nav"></div>
<div class="clearboth"></div>
</div>
</div>
</body></html>