jquery hide/show based on scroll - javascript

So I was given a web template that uses a jquery library called sticky, and it "sticks" the navigation (starts at the bottom and moves up) at the top of the page, as you scroll.
I want to be able to plop a logo onto the navigation once it hits its resting place (post scroll). Similar to this website - http://99u.com/. Once you scroll past the image header, the logo fade's in to the nav bar and then stays on the page. Anyhow, here is the excerpt of the jquery code:
<script>
$(window).load(function() {
$('nav').sticky({ topSpacing:0, className: 'sticky', wrapperClassName: 'my-wrapper' });
});
</script>
And here is the excerpt of the html:
<div with image slideshow></div>
<nav>
<div class="container">
<div class="thirteen columns">
<ul id="nav" class="links">
<li id="sticker"><img src="[image i want to display after scroll]" /></li>
<li>About</li>
<li>Contests</li>
<li>etc.</li>
</ul>
</div>
</div>
</nav>
<div's and the rest of the page's content></div>
This whole template is responsive. Any help would be appreciated, or if someone can point me in the right direction. Thanks!

Take a look at scrollTop and offset.
This is untested but it would look something like this:
$(window).scroll(function(){
if($("#nav").offset().top <= $(window).scrollTop)
$("#nav").css({"position":"fixed","top":"0px", "left":"0px"});
else
$("#nav").css({"position":"relative"});
});
Basically, as the user scrolls, check the windows scroll position and if it passes the top of the nav, switch the nav over to fixed positioning. In my code above, the check on the way back may need a little tweaking but when they scroll to a position less than the height of the nav, put the nav back to relative positioning.
Also instead of switching to position fixed you could show/hide a totally separate nav, might actually make life easier.
-Ken

You can test the position property of the menu and when it changes, hide/show the image via adding/removing a class:
CSS:
#sticker.hidden { width:0; height:0; border:0; padding:0; margin:0; }
#sticker.hidden * { display:none; }
Javascript:
$(window).load(function () {
$('nav').sticky({
topSpacing: 0,
className: 'sticky',
wrapperClassName: 'my-wrapper'
});
var elem = $('#sticker');
var nav = $('nav');
var pos = nav.css('position');
$(window).scroll(function(){
if (nav.css('position')!=pos) { // if changed
if (pos=='fixed') {
elem.addClass('hidden');
} else {
elem.removeClass('hidden');
}
pos = nav.css('position');
}
});
});
jsfiddle

Thanks for the suggestions. They both helped! Here is what i ended up doing:
<script>
$(window).load(function() {
$('#sticker').css({'display':'none'});
$('nav').sticky({ topSpacing:0, className: 'sticky', wrapperClassName: 'my-wrapper' });
$(this).scroll(function() {
if($('nav').offset().top <= $(window).scrollTop()) {
$('#sticker').fadeIn('fast');
} else {
$('#sticker').css({'display':'none'});
}
});
});
</script>

Related

How to change css on click in javascript?

I am having an issue with the links in my dropdown nav menu. I believe that the issue is due to an owl carousel that is in the body, because when I inspect the nav items (right-click inspect element) the console highlights the owl-carousel, also when I change the .owl-carousel display to none in the console, then the links in the nav menu will work (color change on hover, mouse changes to pointer). Therefore, I want to change the .owl-carousel display to none when the toggle menu is active (when the burger menu is clicked).
var burgerMenu = function() {
$("body").on("click", ".js-fh5co-nav-toggle", function() {
$("#fh5co-nav > ul > li").css({ marginLeft: -50, opacity: 0 });
$(this).toggleClass("active");
var mainNav = $("#fh5co-main-nav");
mainNav.slideToggle(400).toggleClass("active");
if (mainNav.hasClass("active")) {
menuAnimate(1, 0, 400, 200);
} else {
menuAnimate(0, -50, 1, 0);
}
});
};
<!-- Mobile Toggle Menu Button -->
<i></i>
<!-- End Mobile Toggle Menu Button -->
<!-- Main Nav -->
<div id="fh5co-main-nav">
<nav id="fh5co-nav" role="navigation">
<ul class="nav">
<li class="active">Home</li>
<li>About</li>
<li>Products</li>
<li>Location</li>
<li>Cafe</li>
<li>Contact</li>
</ul>
</nav>
</div>
<!-- End Main Nav -->
I don't really have any idea how to go about this. I have tried adding:
$('.owl-carousel').css({display: none});
to the burgerMenu function, but this changed nothing.
Any ideas would be greatly appreciated.
***EDIT:
thanks! .css({"display": "none"}) - this worked, but something i didn't think of - the other pages don't have an owl-carousel and I am still having this problem. I think the best thing would be to just have the body shift down when the nav menu is clicked - is this possible? any ideas? thanks, again.
Alternatively since you don't have dynamic css, you can use another class and the class:
in your css file:
.hidden {
display: none;
}
and in you js:
$('.owl-carousel').addClass("hidden");
$('.owl-carousel').css("display", "none");
try this instead of
$('.owl-carousel').css({display: none})
You can do something like the below code.
$('#hello').click(function() {
$('#hello').css({
'background-color': 'blue',
'color': 'white',
'font-size' : '35px'
});
});
#hello{
cursor : pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div id="hello">hello world!</div>
Using core JS:
document.getElementById("my_custom_id").style.color="red";
In the above line of code you can set any CSS, I set the color to red for my_custom_id.

Apply styles for sticky nav when main nav goes out of view

I’ve made my navigation for mobile sticky with this code:
<div class="stickyTest" id="stickyTest2">
<ul id="nav">
<li class="homeicon"></li>
<?php echo $_menu ?>
</ul>
<script type="text/javascript">
document.observe('dom:loaded', function() {
new MobileNavigation();
var searchToggle = $('mobile-search-toggle'),
searchForm = $('search_mini_form');
if (searchToggle && searchForm) {
searchToggle.observe('click', function() {
searchForm.toggleClassName('shown');
});
}
});
</script>
<script type="text/javascript">
function ajaxsearchsubmit(form){
var search = encodeURIComponent(form.w.value);
document.activeElement.blur();
window.location="http://www.test.co.uk/search/go?w="+search;
return false;
}
</script>
<div class="clear"></div>
</div>
And the css:
.stickyTest {
background: #362011;
position:fixed;
z-index:1000;
width:100%;
top:0px;
}
#stickyTest2 {margin-top:40px;}
Now my problem is that I only need the position:fixed of the .stickyTest class and the margin-top:40px of the #stickyTest2 id to be applied for when the user scrolls down and the top navigation goes out of view. So two questions:
How do I apply those specific styles on scroll?
Is there a way to detect when the top navigation goes out of view? I know I could do something that the sticky nav styles are applied when the user scrolls beyond 200px for example but with different screen sizes etc. I’d like to know if there is a more flexible method?
How do I apply those specific styles on scroll?
If you can use jQuery library, you can detect the scroll event with this code :
$(window).scroll(function(){
// your code
});
Then you can use addClass() and removeClass() to play with class.
Is there a way to detect when the top navigation goes out of view?
You can get the height of the navigation bar with this piece of code, with jQuery again and do a test in your scroll() function with the scrollTop() method, like this for instead :
var stickyHeight = $('.stickyTest').height();
$(window).scroll(function(){
// if your top navbar is out of view
if($(window).scrollTop() > stickyHeight){
$('.stickyTest').addClass('fixed');
}else{
$('.stickyTest').removeClass('fixed');
}
});
See a live example
Source :
scroll() : https://api.jquery.com/scroll/
addClass() : https://api.jquery.com/addclass/
removeClass() : https://api.jquery.com/removeclass/
scrollTop() : https://api.jquery.com/scrollTop/

How to use jQuery .hover() in combination with Overflow

Well, i am stucked and can't find the answer myself. Hopefully someone can give me a hint.
I try to fullfill the following requirements:
There should be a Newsblock within a HTML Page with a fixed width and
height.
In this Newsblock only the title of the news are visible.
Those news are "collapsed" by default and should "expand" if the Mouse is over it.
Due the fact that the 'Newsblock' is limited by its height, there should be a Scrollbar visible. But only if the currently expanded news makes it necessary, so the user can Scroll down.
Newstitle and Newstext should never leave the Newsblock.
so far so good, i was able to fullfill all those demands except the one with the Scrollbar. If i try to reach the Scrollbar out of the currently expanded news it collapses again and the Scrollbar disappears. I understand that my .hover is configured that it always SlideUp if i leave the newsentry and the Scrollbar isn't a part of the newsentry div. But i have no idea what to change to still have an overall Scrollbar for the Newsblock, but won't disappear if i try to 'reach' it.
P.s.: A Scrollbar only per Newsentry looks weird. Thats why i want 'bind' the scrollbar to the parent container :S
HTML
<div id="newsblock">
<div> // some auto generated div's i have to life with, so the news entries are not 'direct' children of the newsblock.
<div class="newsentry">
<div class="newstitle">...</div>
<div class="newstext">...</div>
</div>
... another 9 'newsentry' divs.
</div>
</div>
JS
$(".newsentry").hover(
function() {
$(this).children(".newstext").stop(true,true).slideDown();
},
function() {
$(this).children(".newstext").stop(true,true).slideUp();
}
);
CSS
.newsblock {
height: 200px;
overflow-y: auto;
}
Instead of closing a .newsentry when the cursor goes out of it, a solution can be to close it only when it enters another .newsentry or when it leaves #newsblock.
The scrollbar being part of #newsblock, the entry isn't closed anymore when you go on it.
EDIT: Following our discussion about the scroll issue, I added a step callback to the closing animation to make sure that the top of the .newsentry getting opened remains visible when the other entries are getting closed.
Here is a working example:
var $newsblock = $("#newsblock");
function closeAllNews(slideUpArgs){
return $(".newstext").stop(true).slideUp(slideUpArgs);
}
function openNews(news, slideDownArgs){
$(news).find(".newstext").stop(true).slideDown(slideDownArgs);
}
function ensureNewsTopVisible(news){
// Check if the top of the newsentry is visible...
var top = $(news).position().top;
if(top < 0){
// ...and if not, scroll newsblock accordingly.
$newsblock.scrollTop($newsblock.scrollTop() + top);
}
}
$(".newsentry").each(function(){
var $this = $(this);
// When the mouse enter a news entry...
$this.on("mouseenter", function(){
// ...close all opened entries (normally there is at most one)...
closeAllNews({
// (while making sure that the top of this entry remains visible
// at each step)
step: ensureNewsTopVisible.bind(null, $this)
});
// ...open this newsentry.
openNews($this);
});
});
// When the mouse get out of the newsblock, close all news.
$newsblock.on("mouseleave", closeAllNews);
.newstitle {
font-size: 2em;
}
.newstext {
display: none;
}
#newsblock {
max-height: 150px;
overflow: scroll;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="newsblock">
<div>
<div class="newsentry">
<div class="newstitle">News 1</div>
<div class="newstext"></div>
</div>
<div class="newsentry">
<div class="newstitle">News 2</div>
<div class="newstext"></div>
</div>
<div class="newsentry">
<div class="newstitle">News 3</div>
<div class="newstext"></div>
</div>
<!-- Etc. -->
</div>
</div>
<!-- Ignore the script below. It is just filling in the news' text. -->
<script>
$(".newstext").each(function(i, newstext){
$.get("http://baconipsum.com/api/?type=meat-and-filler&format=html&paras=5&num=" + i)
.then(function(ipsumHtml){
$(newstext).html(ipsumHtml);
});
});
</script>
Try this:
$(".newsentry, .newsblock").hover( // <-- changed
function() {
$(this).children(".newstext").stop(true,true).slideDown();
},
function() {
$(this).children(".newstext").stop(true,true).slideUp();
}
);
This makes sure the block stays open when you hover either over the header or the block itself.
Is that what you mean?
There would be a joke , if i am wrong .. what i thing just change your css as
/* not .newsblock **/
#newsblock {
height: 200px;
overflow-y: scroll;/* not auto*/
}
It will be a lot better if you use click operation instead of hover to slide down news text block because the user can accidentally hover over any of the news entry in order to reach for the scroll bar. I think you need a accordion like functionality. You can use the below code if you are fine with click instead of hover.
$(".newsentry").click(
function() {
$(".newstext").stop(true,true).slideUp();
$(this).children(".newstext").stop(true,true).slideDown();
}
);
Or use the below one to go with hover.
$(".newsentry").hover(
function() {
$(".newstext").stop(true,true).slideUp();
$(this).children(".newstext").stop(true,true).slideDown();
},
function(){}
);
This will not close the news text block until you accidentally hover over another news entry.

CSS animated hamburger icon and remove class on scroll?

I want to achieve 2 things when in responsive small screen size:
Create a onclick CSS animated 'hamburger' icon into a cross icon (now it is just a fadeIn/Out effect).
Remove class on scroll event so cross icon turns back in default hamburger icon.
I'm now using svg images for the nav-btn.
I know that i have to add a removeClass action on the scroll event, but tried some different things, but my JS-skills aren't that good.
Hope there is someone that can help or guide me threw this either the one or the other.
Here the FIDDLE
Screenshots:
Cross need to changes back in hamburger icon on scroll:
Html:
<header>
<nav>
<div class="col-nav">
Logo
</div>
<ul>
<li class="col-nav">Item1</li>
<li class="col-nav">Item2</li>
<li class="col-nav">Item3</li>
</ul>
</nav>
</header>
Javascript:
$(function() {
$('.nav-btn').click(function() {
$('nav ul').fadeToggle(300);
$(this).toggleClass("open");
})
});
$(window).scroll(function() {
if ($(this).scrollTop() > 50) {
$('nav ul').hide(); }
});
Add $('.nav-btn').removeClass('open');
$(window).scroll(function() {
if ($(this).scrollTop() > 50) {
$('nav ul').hide();
$('.nav-btn').removeClass('open');
}
});

Box content scroll on mouse over

I have this navigation that can expand when the user clicks a drop down arrow, This navigations is held within a box container with overflow hidden. What I'm trying to achieve is when the users mouse is in the top 20% of the box it scrolls up, and when its in the bottom 20% it scrolls down. I've tried a various number of plugins and tried coding it myself but so far no luck!
This has to be responsive so I am working in percentages.
HTML SET UP:
<div class="container">
<div class="title">Where to next? <span>(this title will be fixed)</span></div>
<ul class="pagesNav">
<li>Page1</li>
<li class="has_children">
Page2
<ul class="children">
<li>Child1</li>
<li>Child2</li>
<li>Child3</li>
</ul>
</li>
<li>Page3</li>
<li>Page4</li>
<li>Page5</li>
<li>Page6</li>
</ul>
</div>
Take a look at my fiddle:
http://jsfiddle.net/7d8fA/
You can get the desired effect by this :
var height=$('.container').height();
var top20=(height/100)*20;
var top80=height-top20;
$('.container').mouseover(function(e) {
e.stopPropagation();
if ((e.clientY-e.currentTarget.offsetTop)<top20) {
$(".container").animate({
scrollTop: 0
}, 10);
} else if (e.clientY>top80) {
$(".container").animate({
scrollTop: height
}, 10);
}
});
forked fiddle -> http://jsfiddle.net/U5Uk8/

Categories

Resources