I've made a one page layout website, where the menu doesn't show the active/current link, when users come from Google or bookmarked it.
I've made a script that works fine, but as you see.... it look horribly. How can I do this smart??
//Set .active to current page link
if (location.href.indexOf("#2") != -1) {
$("#menu li:nth-child(1) a ").addClass("active");
}
if (location.href.indexOf("#3") != -1) {
$("#menu li:nth-child(2) a ").addClass("active");
}
if (location.href.indexOf("#4") != -1) {
$("#menu li:nth-child(3) a ").addClass("active");
}
if (location.href.indexOf("#5") != -1) {
$("#menu li:nth-child(4) a ").addClass("active");
}
if (location.href.indexOf("#6") != -1) {
$("#menu li:nth-child(5) a ").addClass("active");
}
Thank you in advance...
How about something like:
$("#menu li:nth-child(" + ( location.hash.slice(1) - 1 ) + ") a ").addClass("active");
var m = location.href.match(/#(\d+)/);
if (m) {
var index = parseInt(m[1]) - 1;
if (index >= 1)
$("#menu li:nth-child("+index+") a ").addClass("active");
}
Related
I am working on a pagination script (code below); and I don't know how to select the current pagination number after clicking on the next previous buttons (I have added a comment to the missing bit below: removeClass('current'); and addClass('current') to active pagination number; ). The style should work the same as directly clicking on the page number $("#pagin li a").click(function()...
here is a picture:
pagination style when current page selected
Thank you in advance for your help!
pageSize = 4;
incremSlide = 5;
startPage = 0;
numberPage = 0;
var pageCount = $(".browsethearchive-items").length / pageSize;
var totalSlidepPage = Math.floor(pageCount / incremSlide);
for(var i = 0 ; i<pageCount;i++){
$("#pagin").append('<li>'+(i+1)+'</li> ');
if(i>pageSize){
$("#pagin li").eq(i).hide();
}
}
var prev = $("<li/>").addClass("prev").html("Prev").click(function(){
startPage-=1;
incremSlide-=1;
numberPage--;
slide();
});
prev.hide();
var next = $("<li/>").addClass("next").html("Next").click(function(){
startPage+=1;
incremSlide+=1;
numberPage++;
slide();
});
$("#pagin").prepend(prev).append(next);
$("#pagin li").first().find("a").addClass("current");
slide = function(sens){
$("#pagin li").hide();
for(t=startPage;t<incremSlide;t++){
$("#pagin li").eq(t+1).show();
}
if(startPage == 0){
next.show();
prev.hide();
}else if(numberPage == totalSlidepPage ){
next.hide();
prev.show();
}else{
next.show();
prev.show();
}
}
showPage = function(page) {
$(".browsethearchive-items").hide();
$(".browsethearchive-items").each(function(n) {
if (n >= pageSize * (page - 1) && n < pageSize * page)
$(this).show();
});
}
showPage(1);
$("#pagin li a").eq(0).addClass("current");
var $listItems = $('#pagin li a');
var activeLink;
$("#pagin li a").click(function() {
$listItems.removeClass('current');
$(this).addClass('current');
var activeLink=$(this);
showPage(parseInt($(this).text()));
});
var i = 1;
$(".prev").click(function() {
// removeClass('current');
// addClass('current') to active pagination number;
if (i != 1) {
showPage(--i);
}
});
$(".next").click(function() {
// removeClass('current');
// addClass('current') to active pagination number;
if (i < ($('.browsethearchive-items').length)/4) {
showPage(++i);
}
});
UPDATE here is a fiddle with the working code — > https://jsfiddle.net/JoChicau/em19ku8v/39/ — > thanks to #biberman!
You can select the list element with the class "current" in this way:
$("#pagin li a.current")
For setting the class "current" to the next or previous list element you can use the jQuery methods next() and prev(). Since you set the class to the anchor inside the list element you first have to select the parent of the anchor with the parent() function to get the list element itself and after using next() or prev() select the anchor inside the new list element with find("a").
Working example:
$(".prev").click(function() {
let prevLi = $("#pagin li a.current").parent().prev().find("a");
if (prevLi[0]) {
$("#pagin li a.current").removeClass("current");
prevLi.addClass("current");
}
});
$(".next").click(function() {
let nextLi = $("#pagin li a.current").parent().next().find("a");
if (nextLi[0]) {
$("#pagin li a.current").removeClass("current");
nextLi.addClass("current");
}
});
ul {
list-style: none;
}
li {
display: inline-block;
width: 20px;
height: 20px;
text-align: center;
}
li:not(.next, .prev) {
background-color: grey;
}
li a.current {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="pagin">
<li class="prev"><</li>
<li><a class="current">1</a></li>
<li><a>2</a></li>
<li><a>3</a></li>
<li><a>4</a></li>
<li><a>5</a></li>
<li class="next">></li>
</ul>
Additionally i would recommend to add and remove the classes directly to/from the li tag because it makes the script a bit easier (for example no need for parent() and find("a")).
Working example:
$(".prev").click(function() {
let prevLi = $("#pagin li.current").prev();
if (prevLi.find('a')[0]) {
$("#pagin li.current").removeClass("current");
prevLi.addClass("current");
}
});
$(".next").click(function() {
let nextLi = $("#pagin li.current").next();
if (nextLi.find('a')[0]) {
$("#pagin li.current").removeClass("current");
nextLi.addClass("current");
}
});
ul {
list-style: none;
}
li {
display: inline-block;
width: 20px;
height: 20px;
text-align: center;
}
li:not(.next, .prev) {
background-color: grey;
}
li.current {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="pagin">
<li class="prev"><</li>
<li class="current"><a>1</a></li>
<li><a>2</a></li>
<li><a>3</a></li>
<li><a>4</a></li>
<li><a>5</a></li>
<li class="next">></li>
</ul>
Warning: below code is untested.
Set an id containing the page number on every <a> representing a page. For instance
$("#pagin").append(`<li>${i+1}</li> `);
Then use this id to target the right <a>
$(".prev").click(function() {
if (i != 1) {
i--;
$listItems.removeClass('current');
$(`#pagin li a#page-${i}`).addClass('current');
showPage(i);
}
});
I have a little glitch where when you scroll to the very top of my page the class active (which detects the active section of my page and underlines the fitting link in my navbar) gets removed from #home. I tried to fix that using something like this:
var st = $(this).scrollTop();
var id = $(this).attr('id');
if (st.scrollTop == 0) {
$('a[href="#' + id + '"]').parent('li').addClass('active');
}
This didn't quite work.
This is the rest of my javascript:
$(document).ready(function () {
var navTop = $('#navbar').offset().top;
var navHeight = $('#navbar').height();
var windowH = $(window).height();
$('.section').height(windowH);
$(document).scroll(function () {
var st = $(this).scrollTop();
var id = $(this).attr('id');
if (st.scrollTop == 0) {
$('a[href="#' + id + '"]').parent('li').addClass('active');
}
// for the nav bar:
// if (st > navTop) {
// $('#navbar').addClass('fix');
// $('.section:eq(0)').css({
// 'margin-top': navHeight
// }); //fix scrolling issue due to the fix nav bar
// } else {
// $('#navbar').removeClass('fix');
// $('.section:eq(0)').css({
// 'margin-top': '0'
// });
// }
$('.section').each(function (index, element) {
if (st + navHeight > $(this).offset().top && st + navHeight <= $(this).offset().top + $(this).height()) {
$(this).addClass('active');
var id = $(this).attr('id');
$('a[href="#' + id + '"]').parent('li').addClass('active');
// or $('#nav li:eq('+index+')').addClass('active');
} else {
$(this).removeClass('active');
var id = $(this).attr('id');
$('a[href="#' + id + '"]').parent('li').removeClass('active');
//or $('#nav li:eq('+index+')').removeClass('active');
}
});
});
});
I unfortunately lost the source from where I got the code(s).
I checked if my page was at the top with
if(window.scrollY==0)
and when it was I added the class active
{
element.classList.add("active");
}
and this somehow worked :D
I use same concept like your code. But, I make it separately to make easier to understand. Firstly, take offset and height of every section. Secondly, calculate if the scrolling page between the element. Lastly, if the scrolling page between element set active on the target. You can call the element which have id, just by type the id; I got this when I want to make sure if the script success to load, so I set the id same as the object, when I use the id it became the element.
JavaScript
document.addEventListener("DOMContentLoaded", function(){
if (!window.$) location.reload(); //Sometimes jQuery failed to load, so I reload the page
//Take pos (offset) and height elelement
var pH = [];
$("section").each(function(){
pH.push([this.offsetTop, $(this).height()]);
});
$(window).on("scroll", function(){
var pos = this.scrollY + $(sc).height(), //Position when scrolling
index = pH.findIndex(x => pos >= x[0] && pos <= x[0]+x[1]); //index element of position scrolling between the element
if (index >= 0) {
//Make sure only 1 class "active"
//Remove all class "active" then add class "active" on above element
$("span", sc) //sc is an id's element
.removeClass("active")
.eq(index).addClass("active");
}
else {
//Remove class "active" If the scrolling position outside the element
$("span.active", sc).removeClass("active");
}
})
})
CSS
#sc > .active {
color: white;
text-decoration: underline;
}
section {
display: flex;
align-items: center;
justify-content: center;
font-size: 20vw;
height: 100vh;
border: 1px solid black;
}
HTML
<div class="fixed-top bg-primary" id="sc" style="color: lightblue;">
<span>1</span>
<span>2</span>
<span>3</span>
</div>
<section>1</section>
<section>2</section>
<section>3</section>
<p style="padding: 60vh 0;">Hi</p>
I'm getting error from using top property in my jquery code. The code is about navigation dots on my slider. This is the link to my page: http://54.169.61.153/teavana
Below is my code. I'm getting error in the console saying that:
Uncaught TypeError: Cannot read property 'top' of undefined
$(document).ready(function () {
var one = $("#slider").offset();
var two = $("#tabsDiv").offset();
var three = $("#teaWare").offset();
var four = $("#videoo").offset();
$(window).scroll(function () {
var screenPosition = $(document).scrollTop();
if (screenPosition < one.top) {
$(".teavanamenu li a").removeClass("active");
$(".teavanamenu li a.menu1").addClass("active");
}
if (screenPosition >= two.top) {
$(".teavanamenu li a").removeClass("active");
$(".teavanamenu li a.menu2").addClass("active");
}
if (screenPosition >= three.top) {
$(".teavanamenu li a").removeClass("active");
$(".teavanamenu li a.menu3").addClass("active");
}
if (screenPosition >= four.top) {
$(".teavanamenu li a").removeClass("active");
$(".teavanamenu li a.menu4").addClass("active");
}
});
$(window).scroll();
$(".one, .two").click(function () { $(window).scroll(); });
});
I'm not sure why it can't read the property top. Any help?
I have some jQuery that needs to activate depending on the window size.
The current code I have does trigger correctly when the page is loaded, but if I resize the window the jQuery does not enable or disable according to the size of the screen
$(document).ready(function() {
var width = $(window).width();
if ((width < 980)) {
$( '.navigation > ul > li > a' ).click(function() {
if($(this).next('ul').is(':visible')){
$(this).next("ul").slideUp(400);
} else {
$( '.navigation > ul > li > ul' ).slideUp(400);
$(this).next("ul").slideToggle(400);
}
});
$( '.navigation > ul > li > ul > li > a' ).click(function() {
if($(this).next("ul").is(":visible")){
$(this).next("ul").slideUp(400);
} else {
$( '.navigation > ul > li > ul > li > ul' ).slideUp(400);
$(this).next("ul").slideToggle(400);
}
});
$( '.menu-link' ).click(function() {
if($(this).next("div").is(':visible')){
$(this).next("div").slideUp(400);
} else {
$( '.navigation' ).slideUp(400);
$(this).next('div').slideToggle(400);
}
});
}
});
Effectively what I need is for the jQuery to trigger under a screen size of 980px and disable over that figure.
As an extra googly I need to make sure that any expanded elements are able to close or are closed when the page size exceeds 980px as over this size the usual CSS media queries take effect on hover.
An earlier version of my code was able to take into account of a dynamic window size, but left the expanded items open and unable to close since the jQuery no longer functioned.
In case it helps here's a fiddle
You need to use window.onresize method.
EDITED CODE
// flag to check that events doesn't bind twice
var isNavigationEventsEnable = false;
// enable events
var enableNavigationEvents = function () {
$(".navigation > ul > li > a").on('click.screen-lt-980', function () {
if ($(this).next("ul").is(":visible")) {
$(this).next("ul").slideUp(400);
} else {
$(".navigation > ul > li > ul").slideUp(400);
$(this).next("ul").slideToggle(400);
}
});
$(".navigation > ul > li > ul > li > a").on('click.screen-lt-980', function () {
if ($(this).next("ul").is(":visible")) {
$(this).next("ul").slideUp(400);
} else {
$(".navigation > ul > li > ul > li > ul").slideUp(400);
$(this).next("ul").slideToggle(400);
}
});
$(".menu-link").on('click.screen-lt-980', function () {
if ($(this).next("div").is(":visible")) {
$(this).next("div").slideUp(400);
} else {
$(".navigation").slideUp(400);
$(this).next("div").slideToggle(400);
}
});
}
// disable events
var disableNavigatioEvents = function () {
$(".navigation > ul > li > a").off('click.screen-lt-980');
$(".navigation > ul > li > ul > li > a").off('click.screen-lt-980');
$(".menu-link").off('click.screen-lt-980');
}
// call this method on window resize
var redesignScreen = function () {
//function (e) { // comment this line
var width = $(window).width();
if ((width < 980)) {
if (!isNavigationEventsEnable) {
isNavigationEventsEnable = true;
enableNavigationEvents();
}
} else {
isNavigationEventsEnable = false;
disableNavigatioEvents();
}
//} // comment this line
}
$(document).ready(function () {
// attach onresize function
window.onresize = redesignScreen;
// calling redesignScreen initially
redesignScreen();
});
JSFiddle: http://jsfiddle.net/hEtTg/2/
WITH FORCE CLOSE
// flag to check on that events doesn't bind twice
var isNavigationEventsEnable = false;
// enable events
var enableNavigationEvents = function () {
$(".navigation > ul > li > a").on('click.screen-lt-980', function (e, data) {
data = (typeof data == 'undefined') ? {} : data;
if ($(this).next("ul").is(":visible") || data.forceClose) {
$(this).next("ul").slideUp(400);
} else {
$(".navigation > ul > li > ul").slideUp(400);
$(this).next("ul").slideToggle(400);
}
});
$(".navigation > ul > li > ul > li > a").on('click.screen-lt-980', function (e, data) {
data = (typeof data == 'undefined') ? {} : data;
if ($(this).next("ul").is(":visible") || data.forceClose) {
$(this).next("ul").slideUp(400);
} else {
$(".navigation > ul > li > ul > li > ul").slideUp(400);
$(this).next("ul").slideToggle(400);
}
});
$(".menu-link").on('click.screen-lt-980', function (e, data) {
data = (typeof data == 'undefined') ? {} : data;
if ($(this).next("div").is(":visible") || data.forceClose) {
$(this).next("div").slideUp(400);
} else {
$(".navigation").slideUp(400);
$(this).next("div").slideToggle(400);
}
});
}
// disable events
var disableNavigatioEvents = function () {
$(".navigation > ul > li > a").trigger('click', [{
forceClose: true
}]);
$(".navigation > ul > li > ul > li > a").trigger('click', [{
forceClose: true
}]);
$(".menu-link").trigger('click', [{
forceClose: true
}]);
$(".navigation > ul > li > a").off('click.screen-lt-980');
$(".navigation > ul > li > ul > li > a").off('click.screen-lt-980');
$(".menu-link").off('click.screen-lt-980');
}
// call this method on window resize
var redesignScreen = function () {
// function (e) { // comment this line
var width = $(window).width();
if ((width < 980)) {
if (!isNavigationEventsEnable) {
isNavigationEventsEnable = true;
enableNavigationEvents();
}
} else {
isNavigationEventsEnable = false;
disableNavigatioEvents();
}
// } // comment this line
}
$(document).ready(function () {
// attach onresize function
window.onresize = redesignScreen;
// calling redesignScreen initially
redesignScreen();
});
JSFiddle:http://jsfiddle.net/hEtTg/3/
Hopes it helps.
i want to concat some string(id) with parent id...
so i'v tried this-------------->
$(' #cate_id2 > ul > li:has(ul) ').hover(function () {
$('#cate_id2 > ul' + this + ' > ul').stop().slideDown('fast');
},
want to concat #cate_id2 > ul with this and than append > ul ....
string should becomes after execute '#cate_id2 > ul' + li:has(ul) + ' > ul'
i mean li:has(ul) will replaced by with its value.......
Try it like this
$(' #cate_id2 > ul > li:has(ul) ').hover(function () {
$(this).children('ul').stop().slideDown('fast');
}