change list class on click or scroll div - javascript

I know there is lot of question and answer in online and stackoverflow.. but I can't solve my problem...
Please help me before give me minus.
I need to change the active list background when someone click in menu or scroll..
Like: http://stanhub.com/tutorials/change-active-state-in-sticky-navigation-on-scroll/
or like: https://www.trustwave.com/Services/Managed-Security/Threat-Correlation-Services/
I tried to manipulate them with my js code.. but I'm unable to changes them. they stuck !
Here is my code: http://codepen.io/anon/pen/dozJqw
jQuery("document").ready(function($){
var pos = $('.inner-page-nav').offset().top;
var nav = $('.inner-page-nav');
$(window).scroll(function () {
if ($(this).scrollTop() > pos) {
nav.addClass("f-nav");
(".inner-page-nav").fadeIn(3000);
('.inner-page-nav').addClass("f-nav");
} else {
nav.removeClass("f-nav");
}
});
});
$(document).on('click','.scroll_to', function(event) {
event.preventDefault();
var target = "#" + this.getAttribute('data-more-info');
$('html, body').animate({
scrollTop: $(target).offset().top - 60 }, 2000);
});
#page-nav-link{list-style:none;}
#page-nav-link li{float:left;}
.inner-page-nav{ background: #128DC3;}
.f-nav{ z-index: 2900; position: fixed; left: 0; top: 0; width: 100%;margin-top:0px;background:#128DC3;} /* this make our menu fixed top */
.page-nav-content {height: 42px;margin: 0 auto;max-width: 1170px;width: 100%;}
.page-nav-content ul { list-style: none;margin: 0; }
.page-nav-content ul li{float: left; margin: 0px 2px; padding: 10px 70px !important;}
.navActive{background:#4ccbff;}
.navActive a{color:#fff;}
.page-nav-content ul li:hover{background:#4ccbff;}
.page-nav-content ul li:hover a{color:#fff;}
.page-nav-content ul li a {font-size: 25px;line-height: 25px;}
.page-nav-content ul li a:hover {text-decoration:none;color:#fff;}
.clear{clear:both;}
a.scroll_to{
color:#fff;
cursor:pointer;
display: inline-block;
}
.box{width:100%;min-width:100px;height:500px;font-size:25px;color:#000;float:left;}
.red{background:red;}
.green{background:green;}
.blue{background:blue;}
.yellow{background:yellow;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div class="inner-page-nav" id="inner-page-nav">
<div class="page-nav-content">
<ul>
<li class="navActive"><a data-more-info="navOverview" href="#" class="scroll_to">Overview</a></li>
<li><a data-more-info="navFeatures" href="#" class="scroll_to">Features</a></li>
<li><a data-more-info="navWhiteBro" href="#" class="scroll_to">Whitepaper & Brochure</a></li>
<li><a data-more-info="navOrder" href="#" class="scroll_to">Order</a></li>
</ul>
<div class="clear"></div>
</div>
</div>
<div id="navOverview" class="box red">Overview</div>
<div id="navFeatures" class="box green">Features</div>
<div id="navWhiteBro" class="box blue">Brochure</div>
<div id="navOrder" class="box yellow">Order</div>
<div class="clear"></div>
Please help me.
Thank you.

<script>
var topMenu = $("#inner-page-nav"),
topMenuHeight = topMenu.outerHeight()+15,
// All list items
menuItems = topMenu.find("a"),
// Anchors corresponding to menu items
scrollItems = menuItems.map(function(){
var item = $($(this).attr("data-more-info"));
if (item.length) { return item; }
});
// Bind to scroll
$(window).scroll(function(){
// Get container scroll position
var fromTop = $(this).scrollTop()+topMenuHeight;
// Get id of current scroll item
var cur = scrollItems.map(function(){
if ($(this).offset().top < fromTop)
return this;
});
// Get the id of the current element
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
// Set/remove active class
menuItems.parent().removeClass("navActive").end().filter("[href=#"+id+"]").parent().addClass("navActive");
});
</script> try this

Related

How can I change li color when the navbar become sticky?

I would like to change the color of links on my Navbar when the position becomes sticky. ("links-color") is a css class to replace the existing classes on li's.
The code for Sticky position is working already.
var customNav = document.querySelector(".navbarcontainer");
var mylinks = document.querySelectorAll(".nav-link");
var CustomSticky = customNav.offsetTop;
function myNav() {
console.log("CustomSticy= " + CustomSticky);
console.log("scrollY=" + window.scrollY);
if (window.scrollY >= CustomSticky) {
customNav.classList.add("sticky-navbar");
mylinks.classlist.add("links-color")
} else {
customNav.classList.remove("sticky-navbar ");
mylinks.classlist.remove("links-color")
}
}
window.addEventListener('scroll', myNav);
Try this:
var $header = $('header');
var $sticky = $header.before($header.clone().addClass("sticky"));
$(window).on("scroll", function(){
var scrollFromTop = $(window).scrollTop();
$("body").toggleClass("scroll", (scrollFromTop > 100));
});
header.sticky ul li a {
color: red;
}
body.scroll header.sticky {
transform: translateY(0);
}
header.sticky {
position: sticky;
top: 0;
left: 0;
right: 0;
background: rgba(0,0,0,0.85);
z-index: 5;
}
<header>
<nav class="nav-wrapper">
<div class="logo">
<a href="#">
logo
</a>
</div>
<ul class="menu">
<li>Home</li>
<li>My Work</li>
<li>About</li>
</ul>
</nav>
</header>
if your dom elements are aligned --
.navbarcontainer.sticky-navbar -> ul -> li -> a.link-color
then
.sticky-navbar li{ color: red }

scroll on overflow if the children count is more than a number

I would like to add scroll on the <ul> element if the number if <li>s is more than a particular number.
Let's say we have 12 children. I would like to show 7 of them and scroll the remain.
This is what I try:
$(document).ready(function(){
$("ul.ul-scrollable, ol.ul-scrollable").each(function (key, val) {
max_num = $(this).attr('data-maxVisible') || 8;
//console.log(max_num);
var lis = $(this).children('li');
if(lis.length > max_num) {
maxHeight = 0;
for(i = 0; i < max_num; i++) {
maxHeight += +$(lis[i]).outerHeight(true);
//console.log(maxHeight);
}
$(this).css({'max-height' : maxHeight + 'px', 'overflow-y' : 'auto'});
}
});
});
ul {
background: white;
width: 70px;
}
ul li {
padding: 3px;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="ul-scrollable" data-maxVisible="7">
<li>li1</li>
<li>li2</li>
<li>li3</li>
<li>li4</li>
<li>li5</li>
<li>li6 li6 li6</li>
<li>li7</li>
<li>li8</li>
<li>li9</li>
<li>li10</li>
<li>li11</li>
<li>li12</li>
<li>li13</li>
</ul>
But, the calculation for Height is not applicable correctly.
JS FIDDLE
An easier way of accomplishing the same effect is to grab the 7th index's distance from the top and then setting the max-height to that.
$(document).ready(function(){
$("ul.ul-scrollable, ol.ul-scrollable").each(function (key, val) {
var distance = $(this).children('li').eq(7).offset().top;
$(this).css({'max-height' : distance + 'px', 'overflow-y' : 'auto'});
});
});
ul {
background: white;
width: 70px;
}
ul li {
padding: 3px;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul class="ul-scrollable" data-maxVisible="7">
<li>li1</li>
<li>li2</li>
<li>li3</li>
<li>li4</li>
<li>li5</li>
<li>li6 li6 li6</li>
<li>li7</li>
<li>li8</li>
<li>li9</li>
<li>li10</li>
<li>li11</li>
<li>li12</li>
<li>li13</li>
</ul>

Menu item colors not changing properly when I scroll down to a specific section

How can I get each menu item highlighted to it's own color as I scroll to it's section in my WordPress site?
Eg: If I scroll down to about section, the about menu item should change color. If I scroll to contacts section, the menu item should change to a different color and obviously ABOUT should dehighlight immediately.
At the moment, when I scroll down 150px, the menu get fixed to the top. Then as I scroll down to about section, the menu item gets bold, when go to another section, the respective menu item will turn bold immediately and obviously the about menu item dehighlights.
var num = 150; //number of pixels before modifying styles
$(window).bind('scroll', function () {
if ($(window).scrollTop() > num) {
$('nav#site-navigation').addClass('fixed');
} else {
$('nav#site-navigation').removeClass('fixed');
}
});
$("nav ul li a").addClass("marker");
var navLinks = $('nav ul li a'),
navH = $('nav').height(),
section = $('section'),
documentEl = $(document);
documentEl.on('scroll', function() {
var currentScrollPos = documentEl.scrollTop();
section.each(function() {
var self = $(this);
if (self.offset().top < (currentScrollPos + navH ) && (currentScrollPos + navH) < (self.offset().top + self.outerHeight())) {
var targetClass = '.' +self.attr('class') + 'marker';
navLinks.removeClass('active');
$(targetClass).addClass('active');
}
});
});
Now for the colors, I added this snippet to the first function but the colors only change when I click on each menu item more than once.
$("a.marker.active:contains(About)").addClass('item-2');
$("a.marker.active:contains(Products)").addClass('item-3');
$("a.marker.active:contains(Scent)").addClass('item-4');
$("a.marker.active:contains(Clients)").addClass('item-5');
$("a.marker.active:contains(Contact)").addClass('item-6');
Any different way of solving this?
$(window).bind('scroll', function() {
$('.toggle-menu').each(function() {
var post = $(this);
var position = post.position().top - $(window).scrollTop();
if (position <= 0) {
post.addClass('selected');
var theID = $(this).attr('id');
$('nav li a').removeClass('active');
$('#nav-'+theID).addClass('active');
} else {
post.removeClass('selected');
}
});
});
.active {
color: red;
}
#nav-about.active {
color: green;
}
#nav-products.active {
color: gray;
}
#nav-scent.active {
color: yellow;
}
header {
position: relative;}
nav {
position: absolute;
display:block;
top:0;
left:0;
width:100%;
}
nav ul {
list-style: none;}
nav li {
display: inline-block;
padding: 5px 10px;}
section {
padding:150px;
border-top:1px solid red;}
.selected {
font-weigt: 600;
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
<nav>
<ul>
<li><a class="active" id="nav-about" href="#about">About</a></li>
<li><a id="nav-products" href="#products">Products</a></li>
<li><a id="nav-scent" href="#scent">Scent</a></li>
<li><a id="nav-clients" href="#clients">Clients</a></li>
</ul>
</nav>
</header>
<section class="toggle-menu" id="about">
<div class="wrap">
About
</div>
</section>
<section class="toggle-menu" id="products">
<div class="wrap">
Products
</div>
</section>
<section class="toggle-menu" id="scent">
<div class="wrap">
Scent
</div>
</section>
<section class="toggle-menu" id="clients">
<div class="wrap">
Clients
</div>
</section>
Something like this?

How to make sure items are added to the end of a moving list?

When the user clicks "Music", "Movie", or "Computer", an item is supposed to be added to the end of that moving list. Instead, the item gets added at the beginning... and if you click the next or previous button and then try adding an item, the item will get added at a seemingly random place.
How can this be fixed...?
http://jsfiddle.net/neowot/dawvjcta/1/
HTML
<div id="choices">
<ul id="MusicDiv"><li>Music</li></ul>
<ul id="MovieDiv"><li>Movie</li></ul>
<ul id="ComputerDiv"><li>Computer</li></ul>
</div>
<div id="container">
Previous
Next
<div class="carousel">
<ul>
<li><a>x</a>1</li>
<li><a>x</a>2</li>
<li><a>x</a>3</li>
<li><a>x</a>4</li>
<li><a>x</a>5</li>
<li><a>x</a>6</li>
<li><a>x</a>7</li>
<li><a>x</a>8</li>
<li><a>x</a>9</li>
<li><a>x</a>10</li>
<li><a>x</a>11</li>
<li><a>x</a>12</li>
</ul>
</div>
</div>
CSS
#MusicDiv {
background-color:lightblue;
width:100px;
text-align:center;
}
#MovieDiv {
background-color:lightgreen;
width:100px;
text-align:center;
}
#ComputerDiv {
background-color:orange;
width:100px;
text-align:center;
}
#choices li:hover {
cursor:pointer;
}
#container {
width:auto;
height:100px;
background-color:grey;
}
.carousel {
padding-top: 20px;
width: 357px;
overflow: hidden;
height: 50px;
position: relative;
}
.carousel ul {
position: relative;
list-style: none;
list-style-type: none;
margin: 0;
height: 50px;
padding: 0;
}
.carousel ul li {
position: absolute;
height: 25px;
width: 50px;
float: left;
margin-right: 1px;
background: #f2f2f2;
text-align: center;
padding-top: 25px;
}
.carousel a {
color:red;
position:absolute;
top:0;
right:5px;
cursor:pointer;
}
JS
$(document).ready(function() {
$(document).on('click', '#MusicDiv li', function(event) {
alert('TestMusic');
$('<li>Music</li>').appendTo('.carousel ul');
$(".carousel ul").find('li').last().focus();
});
$(document).on('click', '#MovieDiv li', function(event) {
alert('TestMovie');
$('<li>Movie</li>').appendTo('.carousel ul');
$(".carousel ul").find('li').last().focus();
});
$(document).on('click', '#ComputerDiv li', function(event) {
alert('TestComputer');
$('<li>Comp</li>').appendTo('.carousel ul');
$(".carousel ul").find('li').last().focus();
});
$(document).on('click', '.carousel ul li a', function(event) {
alert('TestXButton');
$(this).parent().fadeOut();
});
$(function(){
var carousel = $('.carousel ul');
var carouselChild = carousel.find('li');
var clickCount = 0;
var canClick = true;
function numberOfElements() {
var carWidth=carousel.parent().width();
var elemWidth=carouselChild.width();
return Math.floor(carWidth/elemWidth);
}
var moveWith=numberOfElements();
itemWidth = carousel.find('li:first').width()+1; //Including margin
//Set Carousel width so it won't wrap
carousel.width(itemWidth*carouselChild.length);
//Place the child elements to their original locations.
refreshChildPosition();
//Set the event handlers for buttons.
$('.btnNext').click(function(){
if(canClick){
canClick = false;
//Animate the slider to left as item width
carousel.stop(false, true).animate({
left : '-='+itemWidth*moveWith
},600, function(){
//Find the first item and append it as the last item.
for (var i=0; i<moveWith; i++) {
clickCount++;
lastItem = carousel.find('li:first');
lastItem.remove().appendTo(carousel);
lastItem.css('left', (((carouselChild.length-1+clickCount)*(itemWidth))));
}
//refreshChildPosition();
canClick = true;
});
}
});
$('.btnPrevious').click(function(){
if(canClick){
canClick = false;
//Find the first item and append it as the last item.
for (var i=0; i<moveWith; i++) {
clickCount--;
lastItem = carousel.find('li:last');
lastItem.remove().prependTo(carousel);
console.log(itemWidth*(clickCount));
lastItem.css('left', itemWidth*clickCount);
}
//Animate the slider to right as item width
carousel.finish(true).animate({
left: '+='+itemWidth*numberOfElements()
},300, function(){
canClick = true;
});
}
});
function refreshChildPosition(){
carouselChild.each(function(){
$(this).css('left', itemWidth*carouselChild.index($(this)));
});
}
});
});
The items are properly inserted into the DOM. However, you don't set their position. After inserting them you need to call the function refreshChildPosition(). And you need to extend it to update the carouselChild collection at the beginning:
function refreshChildPosition(){
carouselChild = carousel.find('li'); // this is new
carouselChild.each(function(){
$(this).css('left', itemWidth*carouselChild.index($(this)));
});
}
Of course you need to make the function accessible in the outer scope. If you want to make only minor changes, I suggest you add a variable in the outer scope that you assign it to from the scope in which refreshChildPosition() is defined:
$(document).ready(function() {
var refresh;
// ...
// the click handlers (now calling refresh() at the end)
// ...
$(function(){
var carousel = $('.carousel ul');
var carouselChild = carousel.find('li');
var clickCount = 0;
var canClick = true;
refresh = refreshChildPosition; // <-- give it to the outer scope
// ... rest of your code
This is certainly not the nicest solution but at least it solves your immediate problem.

Creating a menu similar to Google Plus

I'm trying to achieve a responsive menu similar to Google Plus, where the main menu options are added to or removed from the "more" drop down as the window is resized.
The menu I have currently looks like this:
Here is the code:
// JQuery
$(document).ready(function() {
$("a.drop-menu").click(function () {
$('#drop-menu').toggle();
});
});
<!-- HTML -->
<ul id="navigation">
<li>Home</li>
<li>About</li>
<li>Calendar</li>
<li>Forum</li>
<li>Gallery</li>
<li>More
<ul id="drop-menu">
<li>Contact</li>
<li>Contact</li>
</ul></li>
</ul>
/* CSS */
#navigation {
list-style-type: none;
padding: 0px;
margin: 0px;
}
#navigation li {
display: inline-block;
}
#navigation li a:link, #navigation li a:visited, #navigation li a:active {
display: block;
width: 120px;
line-height: 50px;
text-align: center;
font-weight: bold;
text-decoration: none;
background-color: #27383F;
color: #CCC8C0;
}
#navigation li a:hover, #navigation li a.active {
background-color: #2C3C53;
}
#drop-menu {
display: none;
position: absolute;
padding: 0px;
margin: 0px;
}
#drop-menu li {
display: block;
}
JSFiddle
Currently, when the browser window is re-sized the menu options collapse as follows:
However, the below image is my desired result:
I'm wondering if there is a way to accomplish this without media queries? More specifically:
How can I dynamically detect whether the window size is large enough or too small to contain the li tags in the main navigation on a single line?
How do I swap the li tags between one menu and the other?
By not using media-queries I think you can use jQuery $( window ).width(); which will return width of browser viewport.. It should be like this:
$(document).ready(function() {
$("a.drop-menu").click(function () {
$('#drop-menu').toggle();
});
if($( window ).width() < $("#navigation > li").length * (120 + 5)){
//5px is the approximation of the gap between each <li>
var html = $("#navigation > li").last().prev().html();
$("#navigation > li").last().prev().remove();
$("#drop-menu").append(html);
}
var bigger = $("#navigation > li").length + 1;
var smaller = $("#navigation > li").length;
$( window ).resize(function() {
if($( window ).width() <= smaller * (120 + 5)){
//5px is the approximation of the gap between each <li>
var html = $("#navigation > li").last().prev().html();
if(html != undefined){
$("#navigation > li").last().prev().remove();
$("#drop-menu").prepend("<li>"+html+"</li>");
bigger = $("#navigation > li").length + 1;
smaller = $("#navigation > li").length;
}
}
if($( window ).width() >= bigger * (120 + 5)){
//5px is the approximation of the gap between each <li>
var html = $("#drop-menu > li").first().html();
if(html != undefined){
$("#drop-menu > li").first().remove();
$("#navigation > li").last().before("<li>"+html+"</li>");
bigger = $("#navigation > li").length + 1;
smaller = $("#navigation > li").length;
}
};
});
});
Check out this Fiddle, I believe it's not the perfect result.. But, I believe you can use it as your starting point.. Hope it helps..

Categories