How to implement nav bar using jQuery - javascript

I am trying to implement nav bar navigation using jQuery. But no luck! Please have a look at this fiddle.
My requirement is to active menu item based on content scrolled, and scrolling the content based on menu item clicked. Below is the code
$('.menu-item').on('click', function () {
var that = $(this);
$('.menu-item').each(function () {
$(this).removeClass('active');
});
that.addClass('active');
var index = that.index();
var target = $('.menu .menu-target').eq(index);
$('.right').animate({
scrollTop: target.offset().top
}, 500);
});
$('.right').on('scroll', function () {
var scrTop = $(this).scrollTop(),
tgt = "";
$('.menu-target').each(function () {
var th = $(this),
offTop = th.offset().top;
if (offTop > scrTop && && tgt === "") {
tgt = th;
}
});
if (tgt !== "") {
var index = tgt.index();
$('.menu-item').each(function () {
$(this).removeClass('active');
});
$('.menu-item').eq(index).addClass('active');
}
});
But this is not working. Updating active menu item on scroll is not working. How to fix this?
Edit
Tried to fix the issue and here is the code http://jsfiddle.net/SfR2c/11/
It is working with some inconsistency in updating menu element based on scroll content!

Replace this
var target = $('.menu .menu-target').eq(index);
by this
var target = $('.right .menu-target').eq(index);

there is already a working solution to your needs. when programming please DO reuse everything you can.
the solution is to use Bootstrap from twitter ScrollSpy

Related

Adding code to existing .js to collapse navbar when click outside menu

Currently I use .js for my sticky navbar in Bootstrap 4.1.3 which works as desired. I have tried to insert a function in the script, which makes the navbar bar collapse on mobile phones if you click outside the menu. However, without luck. https://biogenity.com/RC19/index.html
The code I am currently using is:
$(document).ready(function () {
var stickyToggle = function (sticky, stickyWrapper, scrollElement) {
var stickyHeight = sticky.outerHeight();
var stickyTop = stickyWrapper.offset().top;
if (scrollElement.scrollTop() >= stickyTop) {
stickyWrapper.height(stickyHeight);
sticky.addClass("is-sticky");
}
else {
sticky.removeClass("is-sticky");
stickyWrapper.height('auto');
}
};
$('[data-toggle="sticky-onscroll"]').each(function () {
var sticky = $(this);
var stickyWrapper = $('<div>').addClass('sticky-wrapper');
sticky.before(stickyWrapper);
sticky.addClass('sticky');
$(window).on('scroll.sticky-onscroll resize.sticky-onscroll', function () {
stickyToggle(sticky, stickyWrapper, $(this));
});
stickyToggle(sticky, stickyWrapper, $(window));
});
});
I want to be able to implement a similar function as the following. It is not certain that this is the best solution for "collapse when you click outside the menu".
$(document).on('click', function(event){
var $clickedOn = $(event.target),
$collapsableItems = $('.collapse'),
isToggleButton = ($clickedOn.closest('.navbar-toggle').length == 1),
isLink = ($clickedOn.closest('a').length == 1),
isOutsideNavbar = ($clickedOn.parents('.navbar').length == 0);
if( (!isToggleButton && isLink) || isOutsideNavbar ) {
$collapsableItems.each(function(){
$(this).collapse('hide');
});
}
});
Thanks in advance.
Based on your code, try this:
$(document).click(function (event) {
var clickedOn = $(event.target),
isNavbar = clickedOn.hasClass('navbar'),
// Target only nav links not all links
isNavbarLink = clickedOn.closest('.nav-link').length == 1,
navbarCollapse = $('.navbar-collapse'),
isNavbarOpen = navbarCollapse.hasClass('show');
// if its not navbar and navbar is opened
if (!isNavbar && isNavbarOpen) {
// if the user is not cliking on the nav links
if (!isNavbarLink) {
// thes close the navbar
navbarCollapse.collapse('hide');
}
}
});

Timeline change css on enter view port

Am trying to change the background color of the timeline on scroll like on this site.My replication of the sample is development site. Take a look at the codepen I tried using. The closest I have come to replicating it is with the code below which makes the change in color on each timeline circle flicker on/off on scroll.
jQuery(document).ready(function($) {
function onScroll() {
$('.cd-timeline-block').each( function() {
if( $(this).offset().top <= $(window).scrollTop()+$(window).height()*0.05 && $(this).find('.cd-timeline-img').hasClass('cd-inactive') ) {
$(this).find('.cd-timeline-img').removeClass('cd-inactive').addClass('cd-active');
$(this).find('.cd-date').addClass('cd-ssf-color');
} else {
$(this).find('.cd-timeline-img').addClass('cd-inactive').removeClass('cd-active');
$(this).find('.cd-date').removeClass('cd-ssf-color');
}
});
};
$(window).scroll(onScroll);
});
I have made some modification to the above code.
CodePen link:
http://codepen.io/anon/pen/KzqWVm
Javascript:
jQuery(document).ready(function($) {
var $timeline_block = $('.cd-timeline-block');
var firstelm = $timeline_block.first();
//on scolling, show/animate timeline blocks when enter the viewport
$(window).on('scroll', function() {
var _win = $(window), iselm = null;
$timeline_block.each(function(index) {
var _this = $(this);
if (((_this.offset().top - _win.height())) <= (_win.scrollTop())) {
iselm = _this;
}
});
if (_win.scrollTop() < $(firstelm).offset().top) {
iselm = $(firstelm);
}
if (iselm) {
$('.cd-active').removeClass('cd-active').addClass('cd-inactive');
iselm.find('.cd-timeline-img').removeClass('cd-inactive').addClass('cd-active');
if ((iselm.offset().top - _win.height()) > (_win.scrollTop() * 0.75)) {
$('.cd-date').removeClass('cd-ssf-color');
}
iselm.find('.cd-date').addClass('cd-ssf-color');
}
});
});
Continuing each loop on scroll might not work properly.

jquery show hide each div onclick

I have a dynamic number of divs which generated through asp.net. I need to show each div contents by clicking on its header. I have tried this {
$(function () {
var myHead = $(".toggle-container").find(".toggle-header");
var myBody = $(myHead).parent().find(".toggle-content");
$(myHead).click(function () {
if ($(myBody).css('display') === 'none') {
$(this).children('i').removeClass('icon-chevron-sign-down').addClass('icon-chevron-sign-up');
$(this).parent().find(".toggle-content").slideDown("slow");
} else if ($(myBody).css('display') === 'block') {
$(this).children('i').removeClass('icon-chevron-sign-up').addClass('icon-chevron-sign-down');
$(this).parent().find(".toggle-content").slideUp("slow");
};
});
});
But it's working only for first header and rest of the headers doesn't collapse it's children content. Here is the JsFiddle Link what I have tried so far. Can anyone give a fix?
The problem was how you were finding the content to be displayed/hidden. You need to find the content related to the clicked header you the code var myBody = $(myHead).parent().find(".toggle-content"); should go inside the click handler as var myBody = $(this).next()
$(function () {
var myHead = $(".toggle-container .toggle-header");
$(myHead).click(function () {
var myBody = $(this).next()
if ($(myBody).css('display') === 'none') {
$(this).children('i').removeClass('icon-chevron-sign-down').addClass('icon-chevron-sign-up');
$(this).parent().find(".toggle-content").slideDown("slow");
} else if ($(myBody).css('display') === 'block') {
$(this).children('i').removeClass('icon-chevron-sign-up').addClass('icon-chevron-sign-down');
$(this).parent().find(".toggle-content").slideUp("slow");
};
});
});
Demo: Fiddle
Note: Still the up-down arrows are nor working because you need to use find() instead of children()
But it can be simplified as
jQuery(function ($) {
var $heads = $(".toggle-container .toggle-header");
$heads.click(function () {
var $this = $(this);
$this.find('i').toggleClass('icon-chevron-sign-down icon-chevron-sign-up');
$this.next().slideToggle("slow");
});
});
Demo: Fiddle
The below would work.
In your original code you had assigned the variable myBody a value at the time of load itself. Since there are many such elements, it used only the first one.
Now I have moved the value setting for the myBody variable to be inside the click event and used $(this). This will make sure that it always finds the element in relation to the current element that was clicked.
$(function () {
var myHead = $(".toggle-container").find(".toggle-header");
$(myHead).click(function () {
var myBody = $(this).parent().find(".toggle-content");
//console.log('yes');
if ($(myBody).css('display') === 'none') {
$(this).children('i').removeClass('icon-chevron-sign-down').addClass('icon-chevron-sign-up');
$(this).parent().find(".toggle-content").slideDown("slow");
} else if ($(myBody).css('display') === 'block') {
$(this).children('i').removeClass('icon-chevron-sign-up').addClass('icon-chevron-sign-down');
$(this).parent().find(".toggle-content").slideUp("slow");
};
});
});
Fiddle Demo

jQuery Show/Hide divs one at a time

I have slightly modified the code in this post jQuery div content partial hide, show all to show/hide a list of div's on my page.
I am still learning jQuery and am trying to figure out how I can modify the code so that when I open one div, it will close any other's that are open.
Thanks a lot for any help. Here is my code block:
function setScroll(){
var slideHeight = 80;
$(".container").each(function() {
var $this = $(this);
var $wrap = $this.children(".wrap");
var defHeight = $wrap.height();
if (defHeight >= slideHeight) {
var $readMore = $this.find(".heading");
$wrap.css("height", slideHeight + "px");
$readMore.append("<div id='clickButton' class='expand-div'>Click for More Info</div>");
$readMore.children("#clickButton").bind("click", function(event) {
var curHeight = $wrap.height();
if (curHeight == slideHeight) {
$wrap.animate({
height: defHeight
}, "normal");
$(this).removeClass("expand-div").addClass("collapse-div");
$(this).text("Close");
$wrap.children(".gradient").fadeOut();
} else {
$wrap.animate({
height: slideHeight
}, "normal");
$(this).removeClass("collapse-div").addClass("expand-div");
$(this).text("Click for More Info");
$wrap.children(".gradient").fadeIn();
}
return false;
});
}
});
}
Simple example (jsfiddle) demonstrates closing all and opening one.
var divs = $('div.highlander').hide();
var which = divs.length;
$('#cycler').click(function () {
which += 1;
if (which >= divs.length) {
which = 0;
}
divs.hide();
divs.eq(which).show();
});
Roy's answer is good. I have another example of something you could do. A little bit more general and possible easier to understand. http://jsfiddle.net/sFR6Q/2/
<button class="show1">show1</button>
<button class="show2">show2</button>
<button class="show3">show3</button>
<button class="show4">show4</button>
<div class="show1">1</div>
<div class="show2">2</div>
<div class="show3">3</div>
<div class="show4">4</div>
var divs = $("div")
$('button').click(function () {
divs.hide();
$("div." + $(this).attr("class")).show();
});
First close all the div's irrespective of if they are open or closed.
Then just open the div you need.

slideToggle is creating a wobble at the end of an accordion

Creating an accordion - on the slide - the elements underneath the element that is sliding seem to move down a px and then back up, creating a juddering effect.
$(document).ready(function() {
//Promos banners rotation and accordion
$(function(){
var $accordionList = $('.accordion').find('li');
var numberOfItems = $accordionList.length;
var currentItem = 0;
// Set first item to active
$accordionList.eq(currentItem).addClass('active').find('.content').slideToggle(800, function() {});
// Loops through promos
var infiniateLoop = setInterval(function() {
if(currentItem == numberOfItems - 1){
currentItem = 0;
}
else {
currentItem++;
}
// Remove active class, if is has it, and close content
$accordionList.parent().find('li.active').removeClass('active')
.find('.content').slideToggle(800, function() {
});
// Add active class and open content
$accordionList.eq(currentItem).addClass('active').find('.content').slideToggle(800, function() {
});
}, 4000 );
// Click to show promo
$accordionList.on('click', function () {
// Stop rotation
clearInterval(infiniateLoop);
var $accordionHead = $(this);
// Remove active class, if is has it, and close content
if($accordionHead.hasClass('active')) {
// Do nothing
}
else {
$accordionHead.parent().find('li.active').removeClass('active')
.find('.content').slideToggle(800, function() {
});
// Add active class and open content
$accordionHead.addClass('active').find('.content').slideToggle(800, function() {
});
};
});
});
});
Fiddle here demonstrating the problem
I've seen some suggestions that you fix the height of the content div - but the site is responsive so that won't work.
Ya, I've had this problem before to. My favorite fix is to just make my own .slideToggle()
div = $('div');
height = div.height();
width = div.width();
$('div').click( function() {
if ($(this).hasClass('hidden')) {
$(this).animate({height: "0", width: "0"}, 200).hide().addClass('hidden');
} else {
$(this).animate({height: height, width: width}, 200).show().removeClass('hidden');
}
});
You could even wrap it in a prototype function if you wanted to.

Categories

Resources