Why Javascript sticky header doesn't work? - javascript

I made a website with a sticky header and it worked well. Some other people worked with it too and they made some changes, but now the stickiness of the header doesn't work. I tried to put back the old code but It didn't help.
var modalBtn = document.querySelector(".cta-add"),
modalBg = document.querySelector(".modal-bg"),
modalClose = document.querySelector(".modal-close");
modalBtn.addEventListener("click", function() {
modalBg.classList.add("bg-active");
}),
modalClose.addEventListener("click", function() {
modalBg.classList.remove("bg-active");
}),
$("#booknow")
.on("click", function() {
$.getScript("https://fareharbor.com/embeds/api/v1/?autolightframe=yes");
})
.done(function() {
window.location.href =
"https://fareharbor.com/embeds/book/.../items/148437/?full-items=yes&flow=no";
});
$("#contact").on("click", function() {
$.getScript("headers.php?file=recaptcha.js");
}),
(window.onscroll = myFunction);
var header = document.getElementById("myHeader"),
sticky = header.offsetTop;
function myFunction() {
header.classList.toggle('sticky', window.pageYOffset > sticky);
}
function openTab(e, t) {
var n, c, a;
for (
c = document.getElementsByClassName("tabcontent"), n = 0; n < c.length; n++
)
c[n].style.display = "none";
for (
a = document.getElementsByClassName("tablinks"), n = 0; n < a.length; n++
)
a[n].className = a[n].className.replace(" active", "");
(document.getElementById(t).style.display = "block"),
(e.currentTarget.className += " active");
}
const hamburger = document.querySelector(".hamburger"),
navLinks = document.querySelector(".nav-links"),
links = document.querySelectorAll(".nav-links li");
var mylogo = document.getElementById("myLogo");
hamburger.addEventListener("click", () => {
navLinks.classList.toggle("open"),
links.forEach((e) => {
e.classList.toggle("fade");
});
}),
$(document).ready(function() {
$("#hamburgerID").on("click", function() {});
}),
$(".nav-links li a").on("click", function() {
$("#hamburgerID").click();
});
.sticky {
position: fixed;
top: 10;
height: 20vh;
width: 100%;
align-items: center;
background: #fff;
}
I implemented this in my old code, and it is working. My question is what else can cause this problem?

I changed the modalBtn.addEventListener function to this:
modalClose.addEventListener('click',function(){
modalBg.classList.remove('bg-active');
});
It is good now, but If someone could tell me what was the problem with the old code I would be grateful.

Related

PageRevealEffects connect to navbar

Hello all of the knowers of javascript,
I have a little problem about javascript and would like one of you to help me to solve the problem.
If you know the 'PageRevealEffects' plugin there are multiple pages that in one HTML are turning on by javascript.
Here are the plugin documentation and demo version at the bottom of documentation: https://tympanus.net/codrops/2016/06/01/multi-layer-page-reveal-effects/
So my problem is I want to connect the navbar and logo click to the plugin,
http://bagrattam.com/stackoverflow/PageRevealEffects/
Here is the code by which it works
(function() {
$('.navbar-brand').click(function(){
$(this).data('clicked', true);
});
var n;
$('#nav a').click(function () {
n = $(this).parent().index() + 1;
});
var pages = [].slice.call(document.querySelectorAll('.pages > .page')),
currentPage = 0,
revealerOpts = {
// the layers are the elements that move from the sides
nmbLayers : 3,
// bg color of each layer
bgcolor : ['#52b7b9', '#ffffff', '#53b7eb'],
// effect classname
effect : 'anim--effect-3'
};
revealer = new Revealer(revealerOpts);
// clicking the page nav
document.querySelector('.navbar-brand').addEventListener('click', function() { reveal('bottom'); });
var navli = document.getElementsByTagName("ul");
for (var i = 0; i < navli.length; i++) {
navli[i].addEventListener('click', function() { reveal('top'); });
}
// triggers the effect by calling instance.reveal(direction, callbackTime, callbackFn)
function reveal(direction) {
var callbackTime = 750;
callbackFn = function() {
// this is the part where is running the turning of pages
classie.remove(pages[currentPage], 'page--current');
if ($('.navbar-brand').data('clicked')) {
currentPage = 0;
} else {
currentPage = n;
}
classie.add(pages[currentPage], 'page--current');
};
revealer.reveal(direction, callbackTime, callbackFn);
}
})();
http://bagrattam.com/stackoverflow/PageRevealEffects/
Here is the solution
var n;
$('#navbar a').click(function(){
if($(this).attr('id') == 'a') {
n = 0;
} else if($(this).attr('id') == 'b') {
n = 1;
} else if($(this).attr('id') == 'c') {
n = 2;
} else if($(this).attr('id') == 'd') {
n = 3;
} else if($(this).attr('id') == 'e') {
n = 4;
};
});
var pages = [].slice.call(document.querySelectorAll('.pages > .page')),
currentPage = 0,
revealerOpts = {
// the layers are the elements that move from the sides
nmbLayers : 3,
// bg color of each layer
bgcolor : ['#52b7b9', '#ffffff', '#53b7eb'],
// effect classname
effect : 'anim--effect-3'
};
revealer = new Revealer(revealerOpts);
// clicking the page nav
document.querySelector("#a").addEventListener('click', function() { reveal('top'); });
document.querySelector("#b").addEventListener('click', function() { reveal('top'); });
document.querySelector("#c").addEventListener('click', function() { reveal('top'); });
document.querySelector("#d").addEventListener('click', function() { reveal('top'); });
document.querySelector("#e").addEventListener('click', function() { reveal('top'); });
// triggers the effect by calling instance.reveal(direction, callbackTime, callbackFn)
function reveal(direction) {
var callbackTime = 750;
callbackFn = function() {
classie.remove(pages[currentPage], 'page--current');
currentPage = n;
classie.add(pages[currentPage], 'page--current');
};
revealer.reveal(direction, callbackTime, callbackFn);
}

jQuery delay fadeIn

I have a javascript/jquery slideshow but I want to remove the somewhat long blank nothingness in between the fadein and fadeout images. I tried using a small delay because by default it still had a blank pause but that didn't work, any idea?
jsfiddle: https://jsfiddle.net/jzhang172/s624zn7d/1/
var imagesArray = ["http://assets.pokemon.com/assets/cms2/img/pokedex/full//007.png",
"http://assets.pokemon.com/assets/cms2/img/pokedex/full/001.png",
"https://assets.pokemon.com/static2/_ui/img/account/sign-up.png",
"http://static.giantbomb.com/uploads/scale_small/0/6087/2438704-1202149925_t.png",
"http://static.giantbomb.com/uploads/scale_small/0/6087/2438704-1202149925_t.png"];
function preloadImg(pictureUrls, callback) {
var i, j, loaded = 0;
var imagesArray = [];
for (i = 0, j = pictureUrls.length; i < j; i++) {
imagesArray.push(new Image());
}
for (i = 0, j = pictureUrls.length; i < j; i++) {
(function (img, src) {
img.onload = function () {
if (++loaded == pictureUrls.length && callback) {
callback(imagesArray);
}
};
img.src = src;
}(imagesArray[i], pictureUrls[i]));
}
};
function roll(imagesArray, currentPos){
var slide = $('.parallax-mirror').find('img').attr('src', imagesArray[currentPos].src);
slide.fadeIn(2000, function() {
slide.fadeOut(1500, function() {
currentPos++;
if(currentPos >= imagesArray.length){
currentPos = 0;
}
roll(imagesArray, currentPos);
});
});
}
$(function () {
preloadImg(imagesArray, function (imagesArray) {
roll(imagesArray, 0, 3);
});
});
.featured-wrapper {
height: 500px;
width: 100%;
overflow: hidden;
}
.things {
font-size: 50px;
height: 500px;
width: 100%;
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parallax.js/1.4.2/parallax.min.js"></script>
<div class="featured-wrapper" data-parallax="scroll" data-image-src="http://assets.pokemon.com/assets/cms2/img/pokedex/full//007.png">
</div>
<div class="things">I'm the stuff underneath</div>
You should use an opacity animation with an easing that fits your needs. You can use jquery ui easings

Why isn't it possible to change max-height with % in javascript?

I'm trying to build a responsive menu, with a hamburger icon. I want the menu list to slide in and out, no jquery - pure javascript only.
HTML :
<div id="animation">
</div>
<button id="toggle">Toggle</button>
CSS :
div {
width: 300px;
height: 300px;
background-color: blue;
}
Javascript :
var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function(type, callback){
var inter = -1, start = 100, end = 0;
if(type==true){
inter = 1;
start = 0;
end = 100;
}
var si = setInterval(function(){
console.log('maxheight');
div.style.maxHeight = (start + inter) + '%';
if(start == end){
clearInterval(si);
}
}, 10);
}
var hidden = false;
but.onclick = function(){
animate(hidden, function(){
hidden = (hidden == false) ? true : false;
});
}
div.style.maxHeight = "50%";
The problem is that proportional height in an element needs a fixed height on the parent, and you didn't provided any parent with a fixed height because for the maxHeight property too the % Defines the maximum height in % of the parent element.
You have to put your div in a parent container with a fixed height, this is your working code:
var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function(type, callback) {
var inter = -1,
start = 100,
end = 0;
if (type) {
inter = 1;
start = 0;
end = 100;
}
var si = setInterval(function() {
console.log('maxheight');
div.style.maxHeight = (start + inter) + '%';
if (start == end) {
clearInterval(si);
}
}, 10);
}
var hidden = false;
but.onclick = function() {
animate(hidden, function() {
hidden = !hidden ;
});
}
div.style.maxHeight = "50%";
#animation {
width: 300px;
height: 300px;
background-color: blue;
}
#parent {
width: 500px;
height: 500px;
}
<div id="parent">
<div id="animation">
</div>
<button id="toggle">Toggle</button>
</div>
Note:
As stated in comments there are some statements in your JavaScript code that need to be adjusted:
if(type==true) can be written as if(type).
hidden = (hidden == false) ? true : false; can be shortened to hidden = !hidden
There seems to be a few errors with your code. I have fixed the js and added comments to what I have changed
var but = document.getElementById('toggle');
var div = document.getElementById('animation');
var animate = function (type, callback) {
var start = 100,
end = 0;
if (type) {
start = 0;
end = 100;
}
var si = setInterval(function () {
if (type) { // check whether to open or close animation
start++;
} else {
start--
}
div.style.maxHeight = start + '%';
if (start == end) {
clearInterval(si);
}
}, 10);
callback.call(this); // do the callback function
}
var hidden = false;
but.onclick = function () {
animate(hidden, function () {
hidden = !hidden; // set hidden to opposite
});
}
/*make sure parent container has a height set or max height won't work*/
html, body {
height:100%;
margin:0;
padding:0;
}
div {
width: 300px;
height: 300px;
background-color: blue;
}
<div id="animation"></div>
<button id="toggle">Toggle</button>
Example Fiddle

Use function everywhere without writing it more than once

Trying to get my code cleaner I don't want to write the same code many times but don't know how to accomplish it. You can see in the code below is the if/else written twice but doing the same. How can I return data and call that function again with writing it only once?
Help and advices are much appreciated.
Code is like this:
(function($){
var scroll = $(this).scrollTop();
var header = $('header');
var headerSmall = header.children('.small');
var headerBigWrap = header.children('.big');
var headerBigWrapHeight = headerBigWrap.height();
var showNav = function() {
header.css('position','fixed');
headerBigWrap.css('display','none');
headerSmall.css('display','block');
}
var hideNav = function() {
header.css('position','static');
headerSmall.css('display','none');
headerBigWrap.css('display','block');
}
// don't want to write this more than once
// but need to call here on document ready
if( scroll >= headerBigWrapHeight ) {
showNav();
} else {
hideNav();
}
$(window).scroll(function(event){
scroll = $(this).scrollTop();
// here I need it again
// scroll is changing on scroll
// but "function" does exactly the same like above
if( scroll >= headerBigWrapHeight ) {
showNav();
} else {
hideNav();
}
});
})(jQuery);
if you need html and css working example: fiddle http://jsfiddle.net/cejs3jhs/ and rest of code:
<header>
<div class="big">
<h1>Page Title</h1>
</div>
<div class="small">
<span class="icon nav-icon">Nav Icon</span>
</div>
</header>
<div class="page"></div>
<style type="text/css">
header {
width:100%;
background-color:red;
opacity:0.5;
}
header.toggle-nav {
height:100%;
}
header.toggle-nav ul {
display:block;
}
header > div {
position:relative;
width:976px;
margin:0 auto;
}
header > div.big {
padding:30px 0;
}
.page {
height:5000px;
background-color:orange;
opacity:0.5;
}
</style>
So just make separate function for that:
function showHideNav(scroll, headerBigWrapHeight, element) {
var scroll = element.scrollTop(),
header = $('header'),
headerSmall = header.children('.small'),
headerBigWrap = header.children('.big')
headerBigWrapHeight = headerBigWrap.height();
if( scroll >= headerBigWrapHeight ) {
header.css('position','fixed');
} else {
header.css('position','static');
}
headerBigWrap.toggle();
headerSmall.toggle();
}
(function($){
showHideNav(scroll);
$(window).scroll(function(event){
scroll = $(this).scrollTop();
showHideNav(scroll);
});
})(jQuery);
The answer to your question is simply what Justinas said, make another function. But you can improve a bit with some more aggressive editing, which is what I've done.
(function ($) {
var header = $('header');
var headerSmall = header.children('.small');
var headerBigWrap = header.children('.big');
var headerBigWrapHeight = headerBigWrap.height();
function setNavStyle() {
var scroll = $(this).scrollTop();
if( scroll >= headerBigWrapHeight ) {
header.css('position', 'fixed');
headerSmall.css('display', 'block');
headerBigWrap.css('display', 'none');
} else {
header.css('position', 'static');
headerSmall.css('display', 'none');
headerBigWrap.css('display', 'block');
}
}
$(window).scroll(setNavStyle);
setNavStyle();
})(jQuery);
That's one way, but it would be better (more maintainable, simpler, faster) to do the bulk of
the work with CSS, like so:
CSS:
header {
position: static;
}
header>.small {
display: none;
}
header>.big {
display: block;
}
.stickyNav header {
position: fixed;
}
.stickyNav header>.small {
display: block;
}
.stickyNav header>.big {
display: none;
}
JavaScript:
(function ($) {
var bigNavHeight = $('header>.big').height();
function setNavStyle() {
var bigIsOffscreen = $(this).scrollTop() >= bigNavHeight;
$(document.body).toggleClass('stickyNav', bigIsOffscreen);
}
$(window).scroll(setNavStyle);
setNavStyle();
})(jQuery);
You can define a new function just as you did with the showNav & hideNav functions
(function($){
var scroll = $(this).scrollTop();
var header = $('header');
var headerSmall = header.children('.small');
var headerBigWrap = header.children('.big');
var headerBigWrapHeight = headerBigWrap.height();
var showNav = function() {
header.css('position','fixed');
headerBigWrap.css('display','none');
headerSmall.css('display','block');
}
var hideNav = function() {
header.css('position','static');
headerSmall.css('display','none');
headerBigWrap.css('display','block');
}
var checkScroll = function (scroll,headerBigWrapHeight){
if( scroll >= headerBigWrapHeight ) {
showNav();
} else {
hideNav();
}
checkScroll(scroll,headerBigWrapHeight);
$(window).scroll(function(event){
scroll = $(this).scrollTop();
checkScroll(scroll,headerBigWrapHeight);
});
})(jQuery);
Please find below updated JS code:
(function($){
var scroll = $(this).scrollTop();
var header = $('header');
var headerSmall = header.children('.small');
var headerBigWrap = header.children('.big');
var headerBigWrapHeight = headerBigWrap.height();
var showNav = function() {
header.css('position','fixed');
headerBigWrap.css('display','none');
headerSmall.css('display','block');
}
var hideNav = function() {
header.css('position','static');
headerSmall.css('display','none');
headerBigWrap.css('display','block');
}
var callFun = function(scroll) {
if( scroll >= headerBigWrapHeight ) {
showNav();
} else {
hideNav();
}
}
callFun(scroll);
$(window).scroll(function(event){
scroll = $(this).scrollTop();
callFun(scroll);
});
})(jQuery);
Do it exactly like you have done with functions showNav and hideNav: define a function with if/else inside somewhere and you can call it by name wherever needed. There are also some variables which can be omitted then, so I show all code here:
(function($){
// var scroll is moved into function scrollFunc
var header = $('header');
var headerSmall = header.children('.small');
var headerBigWrap = header.children('.big');
// var headerBigWrap is moved into function scrollFunc
var showNav = function() {
/* your code */
}
var hideNav = function() {
/* your code */
}
var scrollFunc = function () {
if($(this).scroll() >= headerBigWrap.height() ) {
showNav();
} else {
hideNav();
}
}
$(window).scroll(function(event){
scrollFunc();
});
scrollFunc(); // call it first time to initialize
});

How to modify this jQuery plugin slider for scrolling and orientation?

I found a jQuery slider plugin that does almost what I need. I need to change the tabs so it is on the right side (by adding an option). Also, I would like to add scrolling to the tabs in case there is more than 3 tabs (also by an option). I am trying to make it look like this which is an artist mock up:
http://i.stack.imgur.com/nR8RY.png
This is the script I am trying to modify with the code below it:
http://jqueryglobe.com/labs/feature_list/
/*
* FeatureList - simple and easy creation of an interactive "Featured Items" widget
* Examples and documentation at: http://jqueryglobe.com/article/feature_list/
* Version: 1.0.0 (01/09/2009)
* Copyright (c) 2009 jQueryGlobe
* Licensed under the MIT License: http://en.wikipedia.org/wiki/MIT_License
* Requires: jQuery v1.3+
*/
;(function($) {
$.fn.featureList = function(options) {
var tabs = $(this);
var output = $(options.output);
new jQuery.featureList(tabs, output, options);
return this;
};
$.featureList = function(tabs, output, options) {
function slide(nr) {
if (typeof nr == "undefined") {
nr = visible_item + 1;
nr = nr >= total_items ? 0 : nr;
}
tabs.removeClass('current').filter(":eq(" + nr + ")").addClass('current');
output.stop(true, true).filter(":visible").fadeOut();
output.filter(":eq(" + nr + ")").fadeIn(function() {
visible_item = nr;
});
}
var options = options || {};
var total_items = tabs.length;
var visible_item = options.start_item || 0;
options.pause_on_hover = options.pause_on_hover || true;
options.transition_interval = options.transition_interval || 5000;
output.hide().eq( visible_item ).show();
tabs.eq( visible_item ).addClass('current');
tabs.click(function() {
if ($(this).hasClass('current')) {
return false;
}
slide( tabs.index( this) );
});
if (options.transition_interval > 0) {
var timer = setInterval(function () {
slide();
}, options.transition_interval);
if (options.pause_on_hover) {
tabs.mouseenter(function() {
clearInterval( timer );
}).mouseleave(function() {
clearInterval( timer );
timer = setInterval(function () {
slide();
}, options.transition_interval);
});
}
}
};
})(jQuery);
This is the CSS:
body {
background: #EEE;
font-family: "Trebuchet MS",Verdana,Arial,sans-serif;
font-size: 14px;
line-height: 1.6;
}
#content {
width: 750px;
margin: 50px auto;
padding: 20px;
background: #FFF;
border: 1px solid #CCC;
}
h1 {
margin: 0;
}
hr {
border: none;
height: 1px; line-height: 1px;
background: #CCC;
margin-bottom: 20px;
padding: 0;
}
p {
margin: 0;
padding: 7px 0;
}
.clear {
clear: both;
line-height: 1px;
font-size: 1px;
}
a {
outline-color: #888;
}
Can anyone help with this?
Answer: jsFiddle: features box that slides and scrolls
Features:
Slides over time
Click next and previous
Support for lots of slides
Smooth scrolling
Move to item on click
Stop movement on hover
Easily extended because it uses the cycle plug-in.
Time spent on project: 4hrs
Ok, no fancy scrollbars or anything, but it will iterate through each one bringing it to the top index. I spent ages getting this working properly.
You can test it by adding additional items to the Lists.
/*
* FeatureList - simple and easy creation of an interactive "Featured Items" widget
* Examples and documentation at: http://jqueryglobe.com/article/feature_list/
* Version: 1.0.0 (01/09/2009)
* Copyright (c) 2009 jQueryGlobe
* Licensed under the MIT License: http://en.wikipedia.org/wiki/MIT_License
* Requires: jQuery v1.3+
*/
;(function($) {
$.fn.featureList = function(options) {
var tabs = $(this);
var output = $(options.output);
new jQuery.featureList(tabs, output, options);
return this;
};
$.featureList = function(tabs, output, options)
{
function slide(nr) {
if (typeof nr == "undefined") {
nr = visible_item + 1;
nr = nr >= total_items ? 0 : nr;
}
tabs.removeClass('current').filter(":eq(" + nr + ")").addClass('current');
output.stop(true, true).filter(":visible").fadeOut();
output.filter(":eq(" + nr + ")").fadeIn(function() {
visible_item = nr;
});
$(tabs[(nr - 1 + total_items) % total_items]).parent().slideUp(500,function(){
var order = "";
for(var i = total_items; i > 0; i--)
{
var nextInd = ((nr - 1) + i) % total_items;
var tab = $(tabs[nextInd]);
if(i == total_items)
tab.parent().slideDown(500);
tab.parent().prependTo(tab.parent().parent());
order += nextInd + ", ";
}
});
}
var options = options || {};
var total_items = tabs.length;
var visible_item = options.start_item || 0;
options.pause_on_hover = options.pause_on_hover || true;
options.transition_interval = options.transition_interval || 2000;
output.hide().eq( visible_item ).show();
tabs.eq( visible_item ).addClass('current');
tabs.click(function() {
if ($(this).hasClass('current')) {
return false;
}
slide( tabs.index( this) );
});
if (options.transition_interval > 0) {
var timer = setInterval(function () {
slide();
}, options.transition_interval);
if (options.pause_on_hover) {
tabs.mouseenter(function() {
clearInterval( timer );
}).mouseleave(function() {
clearInterval( timer );
timer = setInterval(function () {
slide();
}, options.transition_interval);
});
}
}
};
})(jQuery);
To increase the height of the box simply change the height of div#feature_list and to add additional items simply add an additional li item in both the ul's within feature_list

Categories