selecting :last-child using jquery - javascript

I have a carousel and each anchor in the menu area is linked to selected slide and when the anchor in the menu is selected it receives a .active class.
Ex: link 1 = slide 1.
I tried to add a stop button instead of next when the carousel reaches the last slider.
<nav class="meniu">
Slide 1
Slide 2
Slide 3
</nav>
<div id="slider">
<ul>
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
</ul>
</div>
This is the script that i tried to add
if ($('.meniu a:last-child').hasClass('active')){
//change button arrow to stop sign
}
Here is the fiddle - http://jsfiddle.net/G7P46/1/

Okay, so here's your problem.
When just using the back and forth buttons, you get the element with the 'active' class, and remove the class then add it to the next sibling. Here's the problem. If you only use the buttons, no anchor ever actually gets set to active. So the jquery selector looking for active returns 0. There's no "next" so it can't check to see if the last element has active.
Now, if you click on a link, THEN use the buttons, it works because at least one anchor has been set to "active".
Here is a working fiddle.
http://jsfiddle.net/G7P46/2/
I updated the gonext function
function goNext() {
if (decount != counter) {
$('#slider ul').animate({
left: '-=' + $('#slider').width()
}, 800, 'swing', function () {
});
if ($('.active').length == 0) {
$('.meniu a:first-child').addClass('active');
}
$('.active').removeClass('active').next().addClass('active');
if ($('.meniu a:last-child').hasClass('active')) {
console.log('change button');
}
decount++;
window.location.hash = decount;
}
}
Notice that I add a check to see if there is any anchor set to active. If not, I set the first child to active. I also added the change button if statement. It now gets hit.
Also, I updated the click event
$('.meniu a').on('click', function () {
var goTo = this.id * -$('#slider').width() + $('#slider').width();
$('#slider ul').animate({
left: goTo
}, 800, 'swing', function () {});
$('.active').removeClass('active');
$(this).addClass('active');
decount = this.id;
window.location.hash = this.id;
if ($('.meniu a:last-child').hasClass('active')) {
console.log('change button');
}
});
Now it checks the last anchor there to.
Edit: I updated the fiddle again to have the actual button changing functionanlity
http://jsfiddle.net/G7P46/3/

try this :
if ($('.meniu a:last').hasClass('active')){
//change button arrow to stop sign
}
I hope it will help.

Related

document.querySelector() always selects the element with the class "Open" even after it has been removed and replaced with the class "Close" | Vue3 js

So I was trying to find a Vue Solution of the jQuery SlideUp() and slideDown() functionality. And I have run into a problem while creating the same for my Side Bar Menu Open and Close funtion. See my code below:
UPDATE: Here's the stackblitz link to the problem: https://stackblitz.com/edit/vue-lvjxmz
I'd really appreciate if someone helps me to solve this problem. Thanks.
export default {
mounted() {
let hasSubmenu = Array.from(document.querySelectorAll(".hasSubmenu.close"));//Select all hasSubmenu
let self = this;
hasSubmenu.forEach(function (el) {//Show Hide Submenu Based On Clicks
el.addEventListener("click", self.menuOpen.bind(this, el));
});
},
methods:{
//Menu Opener Function
menuOpen(el){
let ul = el.querySelector("ul");
ul.style.height = `${ul.scrollHeight}px`;
el.classList.remove("close");//Remove The Class "close"
el.classList.add("open");// add the class "open"
this.menuClose();//Call this function to close the menu
},
//Menu Closer Function
menuClose(){
console.log(document.querySelector(".hasSubmenu.open"));//Log the Selected Element
document.querySelector(".hasSubmenu.open").addEventListener("click", function (e) {
e.currentTarget.querySelector("ul").style.height = "0px";
e.currentTarget.classList.remove("open");
e.currentTarget.classList.add("close");
});
}
},
}
<ul id="main-nav">
<li class="hasSubmenu close">
<div> Main Menu One</div>
<ul style="height: 0px">
<li>
Sub Menu One
</li>
<li>
Sub Menu Three
</li>
</ul>
</li>
</ul>
So what we are doing here is: we are first selecting all the hasSubmenu items with the class close has in it. Then firing the click event where the menu opens and replace the class close with "open". Then we are calling the menuClose function where we are selecting the element which has the .open class. then firing another click event when the menu closes and removes the class .open and adds .close again.
The problem is somehow the menuClose function keeps selecting the element as if it was pointing to the hasSubmenu element and caching it in, it doesn't matter whether the class has been changed or not. I mean, even after the .open class has been removed on the click event it stills selecting it and thus clicking on the menuItem after the first 2 clicks the menuOpen function first opens the menu then calls the menuClose function and immediately closes the menu again although menuClose functionality only added to document.querySelector(".hasSubmenu.open"). As if, it first selected the element itself not the class and cached it in.
Okay, as per James Reply I have managed to solve the problem in another way. So the solution goes as below:
// Simply write one function and check if the submenu's
// height is 0px or not. Based on that write your
// open and close logics
menuOpenClose(el){
let ul = el.querySelector("ul");
let getHeight = ul.style.height;
console.dir(getHeight);
if (getHeight == '0px' || !getHeight.length) {
ul.style.height = `${ul.scrollHeight}px`;
el.classList.remove("close");
el.classList.add("open");
} else{
ul.style.height = `0px`;
el.classList.remove("open");
el.classList.add("close");
}
}

Reinstate hover rules after click

I am using the below script to hide/show my main nav menu items. You can see it live here: http://205.134.239.12/~artscr6/artscrush/#!
One part of my menu uses down arrows (represented using font awesome with the <i> tags) and when the user hovers over the menu item, the arrow appears. This works in the initial state, but once the user clicks one of the menu items to show the flyout, the hover effect no longer works to show the arrows.
What would I need to add to keep that hover effect happening, but still keep the current behavior as well?
/Remove the link elements from the main nav top level
$('.menuItem a').attr('href', '#!');
//Show the down arrows on hover
$('menuItem').hover(function() {
$(this).find('i').css('opacity', '1');
})
//Once menu is clicked
$('.menuItem').click(function() {
//Reset
menuReset();
//Find the correct flyout
var item = $(this).attr('id');
var id = item.substring(item.indexOf("_") + 1);
var findFlyout = '#acFly_' + id;
//Make this item active
$(this).addClass('active');
//Bumps the current down arrow down a bit and shows it
$(this).find('i').css('opacity', '1');
$(this).find('i').css('top', '7px');
//Show the flyout
event.stopPropagation(); //This prevents dom from overriding us
$(findFlyout).toggle();
//Prevent clicks on the current menu from hiding the flyout
$(findFlyout).click(function(){
event.stopPropagation();
})
})
//Hide the menu when the user clicks anywhere
$(document).click( function(){
menuReset();
})
function menuReset() {
$('.flyMenu').hide();
//Resets the down arrows to orig position and hidden
$('.menuItem').find('i').css('opacity', '0');
$('.menuItem').find('i').css('top', '0px');
$('.menuItem').removeClass('active');
}
//Show the down arrows on hover
$('menuItem').hover(function() { // Shouldn't this be .menuItem instead?
$(this).find('i').css('opacity', '1');
})
Also, in the css file on the link you gave me I find the following:
#menu .ul .li:hover i{
opacity: 1;
}
I don't think ul and li are classes, so why is there a . ?
EDIT: Oh, I see now. You named your divs ul and li. :)

How do I change the CSS for the sequential number element on click?

I have used jQuery to generate a sequential numbering for my menu items.
When clicked, the hyperlink text becomes red.
However, the problem here is that I want the respective number to turn into red as well when the hyperlink is clicked (active).
Such as when 'WHY YOU NEED IT' is clicked, the text turns red perfectly. But I need the number 1's background color to change into red as well.
I tried replacing classes but it didn't work.
This is the JS.
jQuery(function ($) {
$(".menu-solutions-menus-container ul li").each(function (i, el) {  $(this).children('a').prepend("<number>" + (i + 1.) + "</number>");
});
$('.local-scroll').click(function (event) {
event.preventDefault();
var full_url = this.href;
var parts = full_url.split('#');
var trgt = parts[1];
var target_offset = $('#' + trgt).offset();
var target_top = target_offset.top;
$('html, body').animate({
scrollTop: target_top
}, 500);
});
$('.menu-solutions-menus-container a').click(function () {
$('.menu-solutions-menus-container a').removeClass('active');
$(this).addClass('active');
});
$('.number').click(function () {
$('.number').removeClass('active');
$(this).addClass('active');
});
Here's the jsfiddle workspace. (Change jQuery version to jQuery 1.7.2 or above if you don't see the numbers.)
The secondary menu in this site is where I would really want to implement it.
Thanks a lot in advance.
Your class names just need a tweek and this'll work fine
change
number.active {
background: white;
}
To
.active number {
background: red;
}
Edit (explanation)
The CSS selector number.active is looking for an html element number that has a class of active like this <number class="active" /> but what your HTML shows is that you wanted the parent <a> to have the active with a child node of <number>.
So to do that you put the parent class first, followed by a space to note a child node of the parent, followed by the element you want to target.
so:
parentElement.parentClass childElement.childClass {
defs
}
you could write
a.active number {
background: red
}
Edit 2 for top bars:
There's a few things, the first being that the grey areas are actually background colors, as opposed to borders. Second the CSS selector is looking for a parent class of "active" but your "active" is a child of the <li>'s
<li id="menu-item-205" class="local-scroll menu-item menu-item-type-custom menu-item-object-custom menu-item-205">
</li>
what you can do is make the li the get the active class like this
$('.menu-solutions-menus-container a').click(function () {
$('.menu-solutions-menus-container a').removeClass('active');
$(this).parent('li').addClass('active');
});
$('.number').click(function () {
$('.number').removeClass('active');
$(this).parent('li').addClass('active');
});
$('.menu-solutions-menus-container a').click(function(){
$('ul.shortcode_menu.solution-menu li').removeClass('active');
$(this).parent('li').addClass('active');
});
Then change your CSS to reflect the <li> is the element with the active class.
ul.shortcode_menu.solution-menu li.active {
background: black;
}
Again I've changed it to background: black instead of border-top, as I think that's the effect you want.

Change class of item when scrolled to

I have a nav set up that when a link is clicked, the page scrolls down to the corresponding item in a list, changing the class of the link when the item is reached.
<nav>
one
two </nav>
<ul>
<li id="one"></li>
<li id="two"></li>
</ul>
Here is a rather crude example
http://jsfiddle.net/FSk5Q/1/
I would also like to change the background colour of the item once it is reached (preferably fading to a new colour), and then restore it's original class when another item is scrolled to, then changing the next item's class.
I need this to happen when clicked to AND scrolled to, so the :target option is not really ideal.
Many thanks for an advice. Not too good in the js department.
Hopefully this can at least get you started. What I have done is check that the offset top is less than the document's scroll top (you could also do something like if it's within X number of pixels).
The color fading can be done with CSS3 transitions.
$(document).on('scroll', function () {
$("li").each(function () {
if ($(this).offset().top <= $(document).scrollTop()) {
$("li").removeClass('highlight');
$(this).addClass('highlight');
}
else {
$(this).removeClass('highlight');
}
});
});
http://jsfiddle.net/FSk5Q/6/
I did a fixed version based on Explosion Pills' one. Hope it's what you wanted.
$(document).on('scroll', function ()
{
$("nav a").removeClass('highlight'); // reset all menu items
temp = $();
$("li").each(function (i) // for each content blcok (you schould give them a class)
{
if ($(this).offset().top <= $(document).scrollTop()) // if it's position is above/at the page top
{
temp = $("nav a:nth-child("+(i+1)+")");
}
});
temp.addClass('highlight');
});
http://jsfiddle.net/maxmeuten/FSk5Q/8/

Display one list element at a time using jQuery; "Previous" link broken

I am wanting to display one list element at a time. Ideally, the first list element would be showing when the user opens the page. When the user clicks the "next" button the first list element will disappear and the second one will appear. When the user clicks the "previous" button the previous element will be shown. So far, the next button works just fine but the previous button scrolls through the li elements but continues on to the link elements, which is not suppose to happen. Here is the code I am using.
HTML:
<div class="event_months">
<a class="prev" href="#"><</a>
<a class="next" href="#">></a>
<li>one</li>
<li>two</li>
</div>
CSS:
.event_months .noShow {
display:none;
}
.event_months .doShow {
display:inline;
}
.event_months .first {
display:inline !important;
​}
jQuery:
<script type = "text/javascript" > $('document').ready(function() {
$(".event_months li:nth-child(3)").addClass("doShow");
$("a.next").click(function() {
$('.first').toggleClass("first");
var $toHighlight = $('.doShow').next().length > 0 ? $('.doShow').next() : $('.event_months li').first();
$('.doShow').removeClass('doShow');
$toHighlight.addClass('doShow');
});
$("a.prev").click(function() {
$('.first').toggleClass("first");
var $toHighlight = $('.doShow').prev().length > 0 ? $('.doShow').prev() : $('#event_months li').last();
$('.doShow').removeClass('doShow');
$toHighlight.addClass('doShow');
});
});
</script>​​​​​​
The reason why the next work and not the previous is because .prev() on the first item will give you the anchor tag before it, use a selector in prev for it to work
$(".event_months li:nth-child(3)").addClass("doShow");
$("a.next").click(function() {
$('.first').toggleClass("first");
var $toHighlight = $('.doShow').next('li').length > 0 ? $('.doShow').next('li') : $('.event_months li').first();
$('.doShow').removeClass('doShow');
$toHighlight.addClass('doShow');
});
$("a.prev").click(function() {
$('.first').toggleClass("first");
var $toHighlight = $('.doShow').prev('li').length > 0 ? $('.doShow').prev('li') : $('.event_months li').last();
$('.doShow').removeClass('doShow');
$toHighlight.addClass('doShow');
});
FIDDLE
Change:
$('#event_months li')
to
$('.event_months li')
You've used an id selector instead of a class selector.

Categories

Resources