Headroom.js header with initial static state - javascript

I'm using the awesome Headroom.js plugin to build an auto-hiding header. The header is static from start and becomes pinned after an offset (when scrolling down) and then back to static (when it's back to the top).
Here is what I have done:
http://codepen.io/netgloo/pen/KmGpBL
but I got 2 problems:
scrolling down from top: when the header becomes pinned, I see it slides down and suddenly slides up
scrolling up from middle page: when the header arrives to the offset it disappears, but I need keeping it pinned to the top
Someone could give me some help or ideas?
Thanks
Here is how I initialize the plugin:
var myElement = document.querySelector("header");
var headroom = new Headroom(myElement, {
"offset": 150,
"tolerance": 0,
});
headroom.init();

The headroom.js script mainly handles the addition/removal of some classes for you. It's up to you to add the appropriate styles to achieve the effect you want. Let's start with the simplest part, the HTML:
HTML
<header>
Header
</header>
That's it!
Now for the JS setup:
JS
var myElement = document.querySelector("header");
var headroom = new Headroom(myElement, {
"offset": 220,
"tolerance": {
up: 0,
down: 0
},
"classes": {
"initial": "header--fixed",
"pinned": "slideDown",
"unpinned": "slideUp",
"top": "top",
"notTop" : "not-top",
}
});
headroom.init();
The first line selects the header element. The second creates a new Headroom object using the configuration values. I've set the values based on the effect it sounds like you're trying to achieve - the header should slide away when the page is scrolled down quickly, and should slide into view when the page is scrolled up.
The offset of 205px is the distance from the top when the header can become unpinned.
The tolerance of 5px is the scroll tolerance before the state changes.
And finally we're going to define the classes that will be added to the element for the different states. At the start the element will be assigned a class of header--fixed. When pinned, the element will receive the additional slideDown class. And when unpinned the element will receive the additional slideUp class.
The final line initializes the headroom object.
Using the state-based classes we can now create the CSS needed to achieve the effect you want.
CSS
We'll start with the .header--fixed class:
.header--fixed {
position: absolute;
top: 0;
width: 100%;
}
main {
padding-top: 110px;
}
This sets the initial placement of the header (at the top) and sets a padding for the main content of the page so it's not covered by the header.
Next we need to define the styles for various states - .top, .not-top, .slideDown and .slideUp:
.header--fixed.top {
transition: none;
transform: translateY(0);
}
.header--fixed.not-top {
position: fixed;
transform: translateY(-100%);
}
.header--fixed.slideDown.not-top {
transition: transform 0.3s ease-in-out;
transform: translateY(0);
}
.header--fixed.slideDown.top {
transition: transform 0.3s ease-in-out;
position: fixed;
}
.header--fixed.slideUp.not-top {
transition: transform 0.3s ease-in-out;
transform: translateY(-100%);
}
.header--fixed.slideUp.top {
transform: translateY(-100%);
position: absolute;
}
Most of these styles are related to setting the position and transition for each state. In short, the .not-top class is applied when the page is scrolled below the header. .top is applied when the page is scrolled near the top (within the height of the header).
In addition to this critical CSS you would need the CSS for the styling of the header - a background color, font, etc. This could be applied by targeting the header element, or header--fixed class.
The final piece, and crux of the problem is resetting the header when the page is scrolled back to the very top - ie a window.pageYOffset of 0. When the page reaches this point, we need to remove the .slideDown class so the header scrolls with the page.
window.addEventListener('scroll', function() {
if (window.pageYOffset === 0) {
myElement.classList.remove('slideDown')
}
})
The Full Code
Putting it all together we get this:
// Headroom.js
// https://github.com/WickyNilliams/headroom.js
var myElement = document.querySelector("header");
var headroom = new Headroom(myElement, {
"offset": 220,
"tolerance": {
up: 0,
down: 0
},
"classes": {
"initial": "header--fixed",
"pinned": "slideDown",
"unpinned": "slideUp",
"top": "top",
"notTop" : "not-top",
}
});
headroom.init();
// When the page is at the top, remove the slideDown class.
window.addEventListener('scroll', function() {
if (window.pageYOffset === 0) {
myElement.classList.remove('slideDown')
}
})
.header--fixed {
position: absolute;
top: 0;
width: 100%;
}
.header--fixed.top {
transition: none;
transform: translateY(0);
}
.header--fixed.not-top {
position: fixed;
transform: translateY(-100%);
}
.header--fixed.slideDown.not-top {
transition: transform 0.3s ease-in-out;
transform: translateY(0);
}
.header--fixed.slideDown.top {
transition: transform 0.3s ease-in-out;
position: fixed;
}
.header--fixed.slideUp.not-top {
transition: transform 0.3s ease-in-out;
transform: translateY(-100%);
}
.header--fixed.slideUp.top {
transform: translateY(-100%);
position: absolute;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
text-align: center;
}
header {
background: #4ECDC4;
padding: 40px;
font: normal 30px/1 sans-serif;
}
main {
padding: 110px 0 0 0;
}
<script src="https://unpkg.com/headroom.js"></script>
<header>
Header
</header>
<main>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
<p>Lorem ipsum 1</p>
<p>Lorem ipsum 2</p>
<p>Lorem ipsum 3</p>
<p>Lorem ipsum 4</p>
<p>Lorem ipsum 5</p>
<p>Lorem ipsum 6</p>
<p>Lorem ipsum 7</p>
<p>Lorem ipsum 8</p>
<p>Lorem ipsum 9</p>
<p>Lorem ipsum 10</p>
<hr>
</main>
And with that we have everything we need. For a working example with the CSS done in SCSS like your example, see this Codepen.

Related

Loop through all elements with a specific style

If I have a bunch of elements on the page with background-color: #000685; that have nothing in common (no common ids, classes, tag names etc,.).
Is there a way to loop through them all with JavaScript and change the background color value?
Since the elements have nothing in common, the best you can do is loop through every element on the page, get the background color for each one, and then perform checks. Like so:
var elements = document.getElementsByTagName("*");
for(let i = 0; i < elements.length; i++){
var cur = elements[i];
if(cur.style.backgroundColor=="rgb(0, 6, 133)"){
cur.style.backgroundColor="red";
}
}
<div style="background-color: #000685;">I should be red</div>
<div>I should not be red.</div>
<div style="background-color: #000685;">I should be red</div>
<div style="background-color: #000685;">I should be red</div>
<div>I should not be red.</div>
<div>I should not be red.</div>
<p style="background-color: #000685;">I should be red</p>
<p>I should not be red.</p>
If the style isn't inline, use getComputedStyle().getPropertyValue("background-color"):
var elements = document.getElementsByTagName("*");
for(let i = 0; i < elements.length; i++){
var cur = elements[i];
if(window.getComputedStyle(cur).getPropertyValue("background-color")=="rgb(0, 6, 133)"){
cur.style.backgroundColor="red";
}
}
.one{
background-color: #000685;
}
.two{
background-color: #000685;
}
.three{
background-color:black;
color:white;
}
<div class="one">I should be red</div>
<div>I should not be red.</div>
<div class="two">I should be red</div>
<div class="one">I should be red</div>
<div class="three">I should not be red.</div>
<div>I should not be red.</div>
<p class="two">I should be red</p>
<p class="three">I should not be red.</p>
You can add some attribute to make the targeting proccess easier:
<span
style="background-color: #FFFFFF;"
background-color
>
Lorem ipsum dolor sit amet
</span>
<span>Lorem ipsum dolor sit amet</span>
<span
style="background-color: #FFFFFF;"
background-color
>
Lorem ipsum dolor sit amet
</span>
<div>Lorem ipsum dolor sit amet</div>
<span
style="background-color: #FFFFFF;"
background-color
>
Lorem ipsum dolor sit amet
</span>
<div>Lorem ipsum dolor sit amet</div>
<p
style="background-color: #FFFFFF;"
background-color
>
Lorem ipsum dolor sit amet
</p>
<span
style="background-color: #FFFFFF;"
background-color
>
Lorem ipsum dolor sit amet
</span>
js:
console.log(document.querySelectorAll('[background-color]'));
output:
// [object NodeList] (5)
["<span/>","<span/>","<span/>","<p/>","<span/>"]

How can i scroll one service section at a time while keeping the .service-inner element in the same place?

I'm trying to create a layout where the user will be able to scroll one service section at a time for ex if the user scrolls down from the first section i want the first section to fade out before the second section fades into the same place as the frist section was
here is a link to js bin Click [here] (https://jsbin.com/xubemivaso/edit?html,js,output)
#one, #two, #three, #four
{
padding: 0px;
margin: 0px;
height:100%;
position:absolute;
display:flex;
justify-content:center;
align-items:center;
font-size:3rem;
right: 0px;
left: 0px;
background-color:black!important;
}
#one {
top:0px;
}
#two {
top:100%;
}
#three {
top:200%;
}
#four {
top:300%;
}
.container-outer{
overflow: hidden;
margin:0px;
padding:0px;
width:100%;
height:100%;
position:relative;
}
.container-inner{
overflow:auto;
position:fixed;
width:100%;
height:100%;
padding:30px;
border:30px solid #131313;
margin:0px;
padding:0px;
}
.container-inner::-webkit-scrollbar {
display: none;
}
</style>
</head>
<body itemscope itemtype ="http://schema.org/LocalBusiness">
<div class="cursor"></div>
<div class="cursor"></div>
<div class="container-outer">
<div class="container-inner" id="fullpage">
<nav>
<a class="careers">CAREERS</a>
<a class="services">SERVICES</a>
<a class="about">ABOUT</a>
<a class="find-us">FIND US</a>
</nav>
<div class="slogan">
<h1>SERVICES</h1>
</div>
<div id="one" class="outer section">
<div class="service-inner first">
<p class="service-title-first"></p>
<p class="service-para-first">
Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor
</p>
</div>
</div>
<div id="two" class="outer section">
<div class="service-inner second">
<p class="service-title-second"></p>
<p class="service-para-second">Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor</p>
</div>
</div>
<div id="three" class="outer section">
<div class="service-inner third">
<p class="service-title-third"></p>
<p class="service-para-third">Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor</p>
</div>
</div>
<div id="four" class="outer section">
<div class="service-inner fourth">
<p class="service-title-fourth "></p>
<p class="service-para-fourth ">Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor Amet Lorem Ipsum Sit Dolor</p>
</div>
</div>
</div>
</div>
<script>
(function(container){
$.fn.stopAtTop= function (serv) {
var $this = this,
$container = $(".container-inner"),
thisPos = $this.offset().top,
//thisPreservedTop = $this.css("top"),
setPosition,
under,
over;
under = function(){
if ($(".container-inner").scrollTop() < thisPos) {
TweenMax.to($this, 0, {"position":"absolute","top":""});
setPosition = over;
}
};
over = function(){
if (!($(".container-inner").scrollTop() < thisPos) ){
TweenMax.to(serv.prev(".service-inner").find('.service-inner'), 1, {"opacity":"0"});
TweenMax.to($this, 0, {"position":"sticky","top":"0px"});
TweenMax.to(serv, 1, {"opacity":"1"});
setPosition = under;
}
};
setPosition = over;
$container.resize(function()
{
bumperPos = pos.offset().top;
thisHeight = $this.outerHeight();
setPosition();
});
$container.scroll(function(){setPosition();});
setPosition();
};
})($(".container-inner"));
$('#one').stopAtTop($("#one > .service-inner"));
$('#two').stopAtTop($("#two > .service-inner"));
$('#three').stopAtTop($("#three > .service-inner"));
$('#four').stopAtTop($("#four > .service-inner"));
</script>

How to show and hide an element when scrolling the window using jquery

I want to show a border effect when I'll scroll down and reach on the desired section.And it'll be hide when I'll leave that section. Is this possible using jquery?
Using $(document).on('scroll'), like this:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<style>
html,body {
height:101%;
}
#box-1 {
width:200px;
height:200px;
background-color:#333;
}
.border-1 {
border: 10px solid #696969;
}
</style>
<body>
<h1 id="myTarget">This is the desire section</h1>
<p>Lorem ipsum dolor amit. Lorem ipsum dolor amit. Lorem ipsum dolor amit. </p>
<p>Lorem ipsum dolor amit. Lorem ipsum dolor amit. Lorem ipsum dolor amit. </p>
<p>Lorem ipsum dolor amit. Lorem ipsum dolor amit. Lorem ipsum dolor amit. </p>
<p>Lorem ipsum dolor amit. Lorem ipsum dolor amit. Lorem ipsum dolor amit. </p>
<div id="box-1"></div>
<script>
$(document).on('scroll', function() {
var pos = $(this).scrollTop();
if( pos >= $('#myTarget').offset().top){
$("#box-1").addClass("border-1").show();
} else {
$("#box-1").removeClass("border-1").hide();
}
})
</script>
</body>
</html>

Text floating around a div

Im trying to make text flowing around the image, in a different scenario. the image wont be inside the content. Image would be a seperate component and the div with text will be a seperate component. So markup will look like this
<img class="imgtofloat" src="images/1.png" alt="" />
<div class="divwithcontent">
<p>Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum </p>
</div>
The scenario is that we cant change the markup but we need to position the image between the content and make the content float around it.
EDIT 1:
I need the image to be in the center of the content as it is in this image https://www.flickr.com/photos/41695354#N08/14477076543/
We can stretch our CSS imagination. Hide the image and replace it with background.
Example, possibly adaptable.
Have a fiddle!
CSS
img {
display: none;
}
p:first-child:after {
content: "";
display: block;
float: left;
width: 100px;
height: 100px;
background: url(http://www.placehold.it/100) no-repeat;
margin: 20px;
}
If you can Change the image placement.
step 1) put image in between the paragraph text.
step 2) and one attribute in img tag align="left"
You can also use inline style, if you just have a few CSS rules.
<img src="images/1.png" alt="" style="float: left" />

jQuery custom scrollbar plugin doesn't update with horizontalScroll: true

I’m using jquery plugin jQuery custom content scroller
source :
http://manos.malihu.gr/jquery-custom-content-scroller/
It works very well in vertical mode.
I can call mCustomScrollbar and call the update method.
See this fiddle :
http://jsfiddle.net/Vinyl/2mU7H/1/
But in horizontal mode, i have an issue when i call the update method. There is no content.
See this fiddle :
http://jsfiddle.net/Vinyl/4CW3p/1/
Do you know why ?
JS Code :
$(document).ready(function () {
$("#content").mCustomScrollbar({
horizontalScroll: true,
scrollButtons: {
enable: true
},
theme: "dark"
});
});
$("#button").click(function () {
$("#content").show();
$("#content").mCustomScrollbar("update");
});
$("#button_close").click(function () {
$("#content").hide();
});
CSS code
#content {
display:none;
overflow:hidden;
text-align:left;
width:150px;
height:150px;
background-color: #666;
color:#fff;
}
HTML code
<div id="content">
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
<p>lorem ipsum lorem ipsum lorem ipsum lorem ipsum</p>
</div>
<p id="button">Show Content</p>
<p id="button_close">Hide Content</p>
Fiddle
You forgot the autoExpandHorizontalScroll setting :)
$("#content").mCustomScrollbar({
horizontalScroll: true,
scrollButtons: {
enable: true
},
theme: "dark",
advanced: {
autoExpandHorizontalScroll: true
}
});

Categories