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);
}
});
Related
I have a multi-level dropdown list that I want to make navigable with arrow keys using vanilla js. The first link of the first dropdown gets skipped as I key up the list. Because its parent li doesn't have a sibling, the traversal stops here. There must be some logical error but after a good deal of time, I can't see it.
I have tried referencing the button that should get focus after that link in many ways but with no success
I expected the traversal to go from Sub-Menu 3, to Sub-Menu 2 to Sub-Menu 1 to the Button next to Menu 2. Instead it goes from Sub-Menu 2 to the button, skipping Sub-Menu 1
<style>
ul.nav { display: flex; list-style: none; }
body:not(.js) ul.sub {
position: absolute;
left: -9999em;
}
body:not(.js) li.has-sub:hover > ul.sub,
body:not(.js) li.has-sub:focus-within > ul.sub,
body:not(.js) li.has-sub ul:hover {
position: relative;
left: 0;
}
body.js .hidden {
position: absolute;
left: -9999em;
}
.hidden {
position: absolute;
left: -9999em;
}
body.js .visible {
position: relative;
left: 0;
}
.visible {
position: relative;
left: 0;
}
</style>
</head>
<body>
<ul class="nav" id="main_nav">
<li>
Menu 1
</li>
<li class="has-sub">
Menu 2
<!-- <button class="trigger">More</button> -->
<ul class="sub">
<li>Sub-Menu 1</li>
<li class="has-sub">
Sub-Menu 2
<!-- <button class="trigger">More</button> -->
<ul class="sub">
<li>
Nested-Menu 1
</li>
<li>
Nested-Menu 2
</li>
<li>
Nested-Menu 3
</li>
</ul>
</li>
<li>
Sub-Menu 3
</li>
</ul>
</li>
<li>Menu 3</li>
</ul>
<script type="text/javascript">
document.querySelector('body').classList.add('js');
//ADD BUTTONS
let triggers = document.querySelectorAll('li.has-sub > a');
for(var i=0; i < triggers.length; i++) {
let toggler = document.createElement('button');
toggler.setAttribute("class", "trigger");
triggers[i].parentNode.insertBefore(toggler, triggers[i].parentNode.querySelector('ul.sub'));
}
//HIDE SUBS BY DEFAULT
let subs = document.querySelectorAll('ul.sub');
for(let a = 0; a < subs.length; a++) {
subs[a].classList.add('hidden');
}
//ADD TABINDEX -1
var dropdownLinks = document.querySelectorAll('ul.sub a');
dropdownLinks.forEach(dropdownLink => dropdownLink.setAttribute("tabindex", "-1"));
var dropdownButtons = document.querySelectorAll('ul.sub button');
dropdownButtons.forEach(dropdownButton => dropdownButton.setAttribute("tabindex", "-1"));
//SHOW SUBS ON CLICK - DEFINE TOGGLE AND APPLY
var toggle = function(elem) {
// elem.classList.toggle('visible');
if(elem.classList.contains('hidden')) {
elem.classList.remove('hidden');
elem.classList.add('visible');
} else if(elem.classList.contains('visible')) {
elem.classList.remove('visible');
elem.classList.add('hidden');
}
};
var hide = function(elem) {
if(elem.classList.contains('visible')) {
elem.classList.remove('visible');
}
if(!elem.classList.contains('hidden')){
elem.classList.add('hidden');
}
}
var buttonTogglers = document.querySelector('.nav').querySelectorAll('button.trigger');
for(var f = 0; f < buttonTogglers.length; f++) {
buttonTogglers[f].addEventListener("click", function(){
toggle(this.nextElementSibling);
});
buttonTogglers[f].addEventListener("focusout", function(){
//hides parent too which we don't want.
});
}
// var = document.querySelector("ul.nav");
// nav.addEventListener("keydown", function(e) {
var subMamas = document.querySelectorAll('li.has-sub');
for(var g = 0; g < subMamas.length; g++) {
subMamas[g].addEventListener("keydown", function(e) {
var active = document.activeElement;
active = '';
if(e.keyCode === 40) {
console.log('down');
if(document.activeElement.nextElementSibling) {
if(document.activeElement.nextElementSibling.classList.contains('visible')) {
document.activeElement.nextElementSibling.firstElementChild.firstElementChild.focus();
} else {
document.activeElement.parentElement.nextElementSibling.firstElementChild.focus();
}
} else if (document.activeElement.parentElement.nextElementSibling){
document.activeElement.parentElement.nextElementSibling.firstElementChild.focus();
}
else {
document.activeElement.parentElement.parentElement.firstElementChild.focus();
}
}
//UP
if(e.keyCode === 38) {
console.log('up');
var active;
console.log('start' + document.activeElement.textContent );
if(document.activeElement.parentElement.previousElementSibling) {
// console.log(active.parentElement.previousElementSibling);
active = document.activeElement.parentElement.previousElementSibling.firstElementChild;
active.focus();
console.log('finish' + active.textContent);
active = '';
}
else if(!document.activeElement.parentElement.previousElementSibling) {
console.log('no sib');
active = document.activeElement.closest('.sub').previousElementSibling;
active.focus();
active = '';
}
}
//RIGHT
if(e.keyCode === 39) {
console.log('right');
}
//LEFT
if(e.keyCode === 37) {
console.log('left');
}
});
}
</script>
In this case, adding the eventListener to the nav instead of each li.has-sub fixed the issue. i.e. removing:
var subMamas = document.querySelectorAll('li.has-sub');
for(var g = 0; g < subMamas.length; g++) {
subMamas[g].addEventListener("keydown", function(e) {
and adding this instead:
var = document.querySelector("ul.nav");
nav.addEventListener("keydown", function(e) {
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'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");
}
I have this row of thumbnails that I am animating with jQuery.
Each of these thumbnails has a hover and active class.
They work fine but when I animate the list, the new thumbnail under the mousecursor does not apply the hover? I have to move the mouse a little bit after each click?
It's kinda difficult to exaplain.. I have made a fiddle here: http://jsfiddle.net/nZGYA/
When you start clicking after thumb 3 without moving the mouse you see what I mean...
It works fine in FireFox, NOT Safari, Chrome, IE etc.
Is there something I can do about this?
For reference here is my code:
<style type="text/css">
.container { position: relative; overflow: hidden; width: 140px; height: 460px; float: left; margin-right: 100px; background: silver; }
ul { position: absolute; top: 10; list-style: none; margin: 10px; padding: 0; }
li { margin-bottom: 10px; width: 120px; height: 80px; background: gray; }
#list-2 li a { display: block; width: 120px; height: 80px; outline: none; }
#list-2 li a:hover { background: teal; }
#list-2 li a.active { background: navy; }
</style>
$(document).ready(function() {
var idx_2 = 0;
$('#list-2 li a')
.click(function() {
$('#list-2 > li a').removeClass('active');
$(this).addClass('active');
var id = $('#list-2 li a.active').data('index') - 2;
idy = Math.max(0, id * 90);
$(this).parent().parent().animate({ 'top' : -idy + 'px' });
return false;
})
.each(function() {
$(this).data('index', idx_2);
++idx_2;
});
});
<div class="container">
<ul id="list-2">
<li><a class="active" href="#"></a></li>
<li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li>
<li></li><li></li><li></li><li></li>
</ul>
</div>
I only worked on the top list but I think I got it all working. let me know if it is what you are looking for.
Here is the fiddler
var idx = 0;
$('#list-1 li').hover(function() {
$(this).addClass('hover');
}, function() {
$(this).removeClass('hover');
}).click
(function() {
var currentindex = $('.active').index();
var selectedindex = $(this).index();
var nexthoverindex = selectedindex + (selectedindex - currentindex);
//counter for starting on index 1
if(currentindex === 1 && selectedindex > 2){
nexthoverindex = nexthoverindex - 1;
}
//counter for starting on index 0
if(currentindex === 0 && selectedindex > 2){
nexthoverindex = nexthoverindex - 2;
}
//make sure the selection never goes below 0
if(nexthoverindex < 0){
nexthoverindex = 0;
}
$('#list-1 > li').removeClass('active');
$(this).addClass('active');
var id = $('#list-1 li.active').data('index') - 2; // take scroll param and subtract 2 to keep selected image in the middle
idy = Math.max(0, id * 90);
$(this).parent().animate({
'top': -idy + 'px'
},200, function(){
$('.hover').removeClass('hover');
if(currentindex > 2 || selectedindex > 2){
$('#list-1 > li').eq(nexthoverindex).addClass('hover');
}
});
return false;
}).css('cursor', 'pointer').each(function() {
$(this).data('index', idx);
++idx;
});
I've got a solution that works in Chrome and IE (haven't tested in Safari). Basically I trigger the mouseover() event of the element under the mouse in the animate() callback event if the thumbnails have moved. The solution is only implemented for list-1.
// list 1
var idx = 0;
$('#list-1 li').hover(function() {
$(this).addClass('hover');
}, function() {
$(this).removeClass('hover');
}).click(function() {
$('#list-1 > li').removeClass('active');
var $active = $(this);
$active.addClass('active');
var id = $('#list-1 li.active').data('index') - 2; // take scroll param and subtract 2 to keep selected image in the middle
var moveAmount = 90;
idy = Math.max(0, id * moveAmount);
var oldPos = $active.parent().position().top;
$active.parent().animate({
'top': -idy + 'px'
}, function(){
var newPos = $(this).position().top;
// Check if we moved
if(oldPos - newPos != 0)
{
var movement = (oldPos - newPos) / moveAmount;
$($(this).children()[$active.index() + movement])
.trigger("mouseover");
}
});
return false;
}).css('cursor', 'pointer').each(function() {
$(this).data('index', idx);
++idx;
});
And here's the link to my fork in jsfiddle if you wan't to test it out over there - http://jsfiddle.net/jimmysv/3tzAt/15/