Sticky header snapping to top to early - javascript

I've been playing around with this code forever. I have a sticky nav implemented on my site and it's supposed to activate once the header becomes out of sight when the user scrolls. The header div is above the nav div. The sticky part works fine but it activates too soon. It snaps to the top immediately once I start scrolling and then doesn't snap back to it's original position once the header comes into view again.
Here's the jquery that makes it work:
(function($) {
var $body,
$target,
targetoffsetTop,
resizetimer,
stickyclass = 'sticky'
function updateCoords() {
targetoffsetTop = $target.offset().top
}
function makesticky() { //Sets the sticky class to activate once
var scrollTop = $(document).scrollTop() //the scroll offset is greater than
if (scrollTop >= targetoffsetTop) { //how far the div is from the top.
if (!$body.hasClass(stickyclass)) {
$body.addClass(stickyclass)
}
} else {
if ($body.hasClass(stickyclass)) {
$body.removeClass(stickyclass)
}
}
}
$(window).on('load', function() {
$body = $(document.body)
$target = $('#header_lg') //This is the target div that get's sticky
updateCoords()
$(window).on('scroll', function() {
requestAnimationFrame(makesticky)
})
$(window).on('resize', function() {
clearTimeout(resizetimer)
resizetimer = setTimeout(function() {
$body.removeClass(stickyclass)
updateCoords()
makesticky()
}, 50)
})
})
})(jQuery)
CSS:
#header_lg { //Before sticky
width: 100%;
height: 75px;
padding: .7%;
background-color: blue;
-webkit-transition: height 1s, width 1s;
-moz-transition: height 1s, width 1s;
transition: height 1s, width 1s;
}
body.sticky #header_lg { //After sticky
position: fixed;
top: 0;
left: 0;
height: 100px;
width: 100%;
}
I'm fairly new with javascript so any suggestions from you experts as to why the code isn't working right would be greatly appreciated. If it's important, the page is in a bootstrap format so it's within the visible-lg class with a container class inside that set to style="width:100%; margin:0; padding:0;". The HTML code is just an empty div with some filler text.

you did not write correctly your CSS comments (different from js):
try this:(thanks #Toni for her usefull pen here i forked to demonstrate )
#header_lg { /*Before sticky*/
width: 100%;
height: 75px;
padding: .7%;
background-color: blue;
-webkit-transition: height 1s, width 1s;
-moz-transition: height 1s, width 1s;
transition: height 1s, width 1s;
}
body.sticky #header_lg { /*After sticky*/
position: fixed;
top: 0;
left: 0;
height: 100px;
width: 100%;
}

Related

Navigation menu is showing on top of the website, even though it's translated it up

Here is a video of the issue. And not sure why this problem is occurring when I decrease the height in responsive design mode. Beginner web developer, any help appreciated.
.main-navigation {
position: absolute;
height: 100%;
top: -100%;
bottom: 0;
left: 0;
right: 0;
background-color: #fffefc;
transform: translateY(0);
transition: all 500ms;
}
/* modifier class*/
.navigation-open {
transform: translateY(100%);
}
const closeButton = document.querySelector(".close-nav-btn");
const openButton = document.querySelector(".open-nav-btn");
const nav = document.querySelector(".main-navigation");
closeButton.addEventListener("click", () => {
nav.classList.remove("navigation-open");
});
openButton.addEventListener("click", () => {
nav.classList.add("navigation-open");
});
Let me know if further info is required to help out. (:
This top: -100% you have means "move the navigation to the top of the containing block's height". When you resize, the containing block's height is becoming smaller than your navigation's height, which is causing this overflow you see.
A solution could be doing as below.
Notice I'm animating the height of the navigation, instead its top property.
.main-navigation {
position: fixed;
top: 0;
left: 0;
width:100%;
height:0;
overflow:hidden;
background-color: #fffefc;
transition: all 500ms;
}
.navigation-open {
overflow:auto;
height: 100vh;
}

Make navigation menu slide in

How would I go about making this menu slide in on hamburger menu click? The background of it is an SVG and not an actual shape.
https://codepen.io/KirbStarRulz/pen/GdzOyM
$(document).ready(function() {
$('.hamburger-container').on('click', function(e) {
e.preventDefault();
$('.hideMenu').toggleClass('slideInMenu');
});
});
function myFunction(x) {
x.classList.toggle("change");
}
Here's an image of what I need slid in (orange trapezoid on the right)
https://ibb.co/nRrr1T
Thanks!
If I understand correctly you want to slide in navigation. Your code works fine the only problem is negative z-index because of it your navigation is below all other elements.
.hideMenu {
background-image: url(images/kreativez_menu_bg.svg);
width: 48%;
height: 100%;
background-size: cover;
position: fixed;
transform: translateX(200%);
z-index: 100;
top: 0;
left: 0;
transition: transform 0.5s linear;
}

Creating & Assigning a css class in jquery

//Dynamically getting the windows width
var windowwidth = $(window).width() - 50;
//dynamically assigning the windowwidth value to the class(dynamically)
$(window).load(function () {
$('.cntnt').css('width', windowwidth + 'px');
})
$("#menu-toggle").click(function(e) {
e.preventDefault();
$('.wrapper-content').toggleClass('cntnt');
});
#wrapper {
padding-left: 0;
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}
#wrapper.toggled {
padding-left: 250px;
}
#sidebar-wrapper {
z-index: 1000;
position: fixed;
left: 250px;
width: 0;
height: 100%;
margin-left: -250px;
overflow-y: auto;
background: #4a4f55;
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}
#wrapper.toggled #sidebar-wrapper {
width: 250px;
}
#page-content-wrapper {
width: 100%;
position: absolute;
padding: 15px;
}
#wrapper.toggled #page-content-wrapper {
position: absolute;
margin-right: -250px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >
<div class="wrapper-content">
<div class="container-fluid">
<a href="#menu-toggle" class="btn pull-left" id="menu-toggle" >
toggle menu
</a>
<div class="row">
<div class="col-lg-12">
<h1>Simple Sidebar</h1>
<p>This template has a responsive menu toggling system. The menu will appear collapsed on smaller screens, and will appear non-collapsed on larger screens. When toggled using the button below, the menu will appear/disappear. On small screens, the page content will be pushed off canvas.</p>
<p>Make sure to keep all page content within the <code>#page-content-wrapper</code>.</p>
</div>
</div>
</div>
</div>
Hi, Im trying to Create a css class in jQuery & assigning it to another id in jQuery.
The main agenda is, I want to toggleClass a class in jQuery, which has a width of the $(window), on click on a function that class should be toggled to an id,
here's the code which I implemented, I've got no errors, but not output too.
Help me out please.
$(window).load(function () {
$('.cntnt').css('width', + windowwidth + 'px');
})
This is not class assignation, you just find elements with this class and set them style.
If you want to dynamically set class you should create new style element, something like:
$(window).load(function () {
$('body').prepend('<style>.cntnt { width:' + windowwidth + 'px }</style>')
})
In order to dynamically create a css class you can create a <style> element and append it to <head>.
$("<style>")
.prop("type", "text/css")
.html(".cntnt { width: " + windowwidth + "px; }")
.appendTo("head");
Or, if you only need the windowidth, you can simply create a class in static css with vw and calc. Which 100vw is equal to $(window).width() and calc calculate the value between different units. In this way you get the advantage of dynamically re-calculate the width whenever user resize the window. With javascript, you need to put your code inside $(window).resize event to do so.
.cntnt {
width: calc(100vw - 50px);
}

Fire Javascript during CSS/JS animation (vanilla JS)

Edit: this is an example of what I'm trying to do: http://codepen.io/anon/pen/OVzOjW
(Note that the menu and nav don't perfectly align, as the nav transition is being controlled by the CSS, and the menu delay is being controlled by the JS.)
I'm trying to create a slideout menu that fires some JS during the slide animation.
On page load, nav is fixed hidden to the right of the viewport and menu is fixed to the top right of the viewport. nav is wider than menu. On menu click fires the slideout animation of nav. I want to add a namespace class to nav that changes the CSS properties of menu. I want to do this the moment the visible portion of the nav becomes equal in width to the width of the menu, at which point the menu will just become part of the nav for the rest of the slideout.
I need to do this with some combination of CSS3 and vanilla JS (jQuery is unavailable). I can do the nav animation with CSS or JS easy enough, but timing the CSS property changes on menu is what I can't figure out.
I've tried to write a loop that constantly evaluates the right property value of nav to see if it's >= the width of menu (using CSS to do the transition), but that seems to fire the entire loop right away.
I'm not picky over a CSS vs JS solution for the animation itself, but I'd prefer CSS as I feel it's easier to control the transition settings and it runs smoother.
Relevant code below. Any help would be greatly appreciated!
HTML:
<nav id="nav">
<a id="menu" href="#">Menu</a>
Foo
Foo
Foo
</nav>
CSS:
#nav {
position: fixed;
right: -100px;
top: 0;
width: 100px;
}
#nav.expanded-nav {
right: 0;
}
#nav.expanded-menu #menu {
position: absolute;
right: auto;
top: auto;
width: 100%;
}
#menu {
position: fixed;
right: 0;
top: 0;
width: 50px;
}
You can do that with CSS animation chaining or animation-delay or simple setTimeout of Vanilla JavaScript
Check out the below code for CSS way..
$("#go").click(function() {
$(".container").addClass("demo");
});
.container {position: relative;}
#nav, #menu {
height: 100px;
width: 100px;
position: absolute;
}
#nav {
top: 10px;
left:-100px;
background: #000;
}
#menu {
top: 150px;
left:200px;
background: #f00;
}
.demo #nav {
-webkit-animation: demo 1s, demo1 2s;
-webkit-animation-delay: 0s, 1s;
-webkit-animation-timing-function: ease-in-out;
}
.demo #menu {
-webkit-animation: demo1 2s;
-webkit-animation-delay: 1s;
-webkit-animation-timing-function: ease-in-out;
}
#-webkit-keyframes demo {
0% {
left: -100px;
}
100% {
left: 200px;
}
}
#-webkit-keyframes demo1 {
0% {
left: 200px;
}
100% {
left: 300px;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="go">Go</button>
<div class="container">
<div id="nav"></div>
<div id="menu"></div>
</div>
This was actually way easier than I initially thought. It can actually rather easily be solved by setting a min-width on menu and allowing it to "grow" to the full length of the parent `nav' when it slides out. Demo here: http://codepen.io/anon/pen/EjobEJ

scrollTop does not work well inside iframe

I have a html file created with cloudconvert.com that I wrapped with java script to highlight text inside it and scroll to first highlight using JQuery scrollTop() function. See example:
function doSearch2(text,color) {
if (window.find && window.getSelection) {
document.designMode = "on";
var sel = window.getSelection();
sel.collapse(document.body, 0);
while (window.find(text)) {
document.execCommand("HiliteColor", false, color);
sel.collapseToEnd();
}
document.designMode = "off";
} else if (document.body.createTextRange) {
var textRange = document.body.createTextRange();
while (textRange.findText(text)) {
textRange.execCommand("BackColor", false, color);
textRange.collapse(false);
}
}
var sel2 = document.getSelection();
var seltop = $(sel2.anchorNode.parentElement).offset().top;
var doccurrenttop = $('#page-container').scrollTop();
var scrollto = doccurrenttop + seltop - 70; // spce of 70px
if (scrollto < 0) { scrollto = 0; }
$('#page-container').scrollTop(scrollto);
}
doSearch2("Cross","yellow");
http://jsfiddle.net/3c3vx862/
I try to insert doSearch2() function into the head of the html file and load it on iframe inside new html document. Then I call doSearch2() from button on the outer document.
The scrollTop works fine, except on some cases (like scrolling to the bottom of the document and other random locations). When I debug it I find that sel2 (= document.getSelection()) is zero.
Any Ideas ?
Thanks !
Well it doesnt work probably for all that generated script and html you have there but you can take a look at this jsfiddle I made for you here.
Add this to your html page:
Top
Script
jQuery(document).ready(function($){
// browser window scroll (in pixels) after which the "back to top" link is shown
var offset = 300,
//browser window scroll (in pixels) after which the "back to top" link opacity is reduced
offset_opacity = 1200,
//duration of the top scrolling animation (in ms)
scroll_top_duration = 700,
//grab the "back to top" link
$back_to_top = $('.cd-top');
//hide or show the "back to top" link
$(window).scroll(function(){
( $(this).scrollTop() > offset ) ? $back_to_top.addClass('cd-is-visible') : $back_to_top.removeClass('cd-is-visible cd-fade-out');
if( $(this).scrollTop() > offset_opacity ) {
$back_to_top.addClass('cd-fade-out');
}
});
//smooth scroll to top
$back_to_top.on('click', function(event){
event.preventDefault();
$('body,html').animate({
scrollTop: 0 ,
}, scroll_top_duration
);
});
});
CSS
.cd-top {
display: inline-block;
height: 40px;
width: 40px;
position: fixed;
bottom: 100px;
right: 10px;
z-index: 10;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
/* image replacement properties */
overflow: hidden;
text-indent: 100%;
white-space: nowrap;
background: rgba(232, 98, 86, 0.8) url(../img/cd-top-arrow.svg) no-repeat center 50%;
visibility: hidden;
opacity: 0;
-webkit-transition: opacity .3s 0s, visibility 0s .3s;
-moz-transition: opacity .3s 0s, visibility 0s .3s;
transition: opacity .3s 0s, visibility 0s .3s;
}
.cd-top.cd-is-visible, .cd-top.cd-fade-out, .no-touch .cd-top:hover {
-webkit-transition: opacity .3s 0s, visibility 0s 0s;
-moz-transition: opacity .3s 0s, visibility 0s 0s;
transition: opacity .3s 0s, visibility 0s 0s;
}
.cd-top.cd-is-visible {
/* the button becomes visible */
visibility: visible;
opacity: 1;
}
.cd-top.cd-fade-out {
/* if the user keeps scrolling down, the button is out of focus and becomes less visible */
opacity: .5;
}
.no-touch .cd-top:hover {
background-color: #e86256;
opacity: 1;
}
#media only screen and (min-width: 768px) {
.cd-top {
right: 20px;
bottom: 20px;
}
}
#media only screen and (min-width: 1024px) {
.cd-top {
height: 60px;
width: 60px;
right: 30px;
bottom: 30px;
}
}
jsFiddle here

Categories