jQuery/javascript - Highlight for a menu when user click on it - javascript

Hi
Suppose I have a menu like:
<ul>
<li>notebook</li>
<li>camera</li>
<li>phone</li>
</ul>
When I click on a menu, the menu will be highlighted, if click on another menu, this menu will be highlighted and other menu will return to original(no highlighted). Can someone give me some idea how to do it(create a listener for <li> or anything else)?
Thanks you

The most efficient way would be via .delegate(), like this:
$("ul").delegate("li", "click", function() {
$(this).addClass("active").siblings().removeClass("active");
});
Then just give it some styling to match, for example:
.active a { color: red; }
You can test it out here, if you want a click on an already-active <li> to make it inactive, then change .addClass() to .toggleClass(), like this.

You didn't provide a lot to go on, but assuming that's the only unordered list on the page...
<script type="text/javascript">
$( document ).ready( function() {
$( 'ul li' ).click( function() {
$( 'ul li' ).removeClass( 'highlight' );
$( this ).addClass( 'highlight' );
});
});
</script>
So when any li gets clicked, the 'highlight' class (assuming there is one that does the highlighting of which you speak) gets removed from all of the li elements. Then the one that triggered the click gets the highlight class.
Might be better to have the 'a' element actually trigger the jquery, now that I think about it.
<script type="text/javascript">
$( document ).ready( function() {
$( 'ul li a' ).click( function() {
$( 'ul li' ).removeClass( 'highlight' );
$( this ).parent( 'li' ).addClass( 'highlight' );
});
});
</script>
That's the best I can do given the information that you've provided.

Related

I have a named function which works great on click. How can I run it on a specific element when the page loads?

So, I have a function called runFilter. It works great when I run it on click. If you look at the line underneath "on load, run the filter," that doesn't work at all. If it was a built-in function like .css() then it would work fine, but this isn't a built-in function and I've already failed at extending jQuery to make it one.
I'm probably doing something very obvious wrong here, but what I want to happen is for the function to fire once after the page is loaded, targeting this specific link: ul > li:first-child a.
jQuery(document).ready(function( $ ) {
function runFilter( event ) {
console.log( this );
event.preventDefault();
//* add active class on the active nav item
$( 'ul.attractions-filters a' ).removeClass( 'active' );
$( this ).addClass( 'active' );
//* add active class for visible things
term = $( this ).attr( 'data-term' );
$( '.type-attractions' ).removeClass( 'active' );
$( '.attractiontype-' + term ).addClass( 'active' );
}
// Show everything once the page is fully loaded
$( '.type-attractions' ).addClass( 'active' );
//* On load, run the filter
// $( 'ul.attractions-filters:first a' ).on( 'load', runFilter );
//* On click, run the filter
$( 'ul.attractions-filters a' ).on( 'click', runFilter );
});
While it's not clear which A of which UL you're actually trying to refer to, there are a bunch of different ways of doing it:
The example below depends on a few things:
jQuery will call any method attached through .on via the .click
method. It automatically binds it to the function.
jQuery will let you invoke known events through the .trigger method. It automatically binds it to the function
querySelector only returns the first element that matches a selector (may be easier to read than the equivalent jQuery selector)
let selector = 'ul.attractions-filters a';
let firstSelector = 'ul.attractions-filters:first a';
let firstChildSelector = 'ul.attractions-filters a:first';
let firstChildSelectorJQ = 'ul.attractions-filters:first a:first';
let whatYouAskedFor = 'ul > li:first-child a'
$(function() {
function runFilter() {
console.log(this)
}
$(selector).on('click', runFilter);
console.log( "This selector will click all A elements in the first UL with class 'attractions-filters'")
$(firstSelector).click();
$(firstSelector).trigger('click');
console.log( "This selector will click the first A element in every UL with class 'attractions-filters'")
$(whatYouAskedFor).click();
$(whatYouAskedFor).trigger('click');
console.log("These selectors will click the first A element in the first UL with class 'attractions-filters'")
$($(firstSelector)[0]).click();
$($(firstSelector)[0]).trigger('click');
$(firstChildSelector).click();
$(firstChildSelector).trigger('click');
runFilter.bind($(firstSelector)[0])();
console.log("These selectors will select only the first child of the first UL of class 'attractions-filters' and click it")
$(firstChildSelectorJQ).click();
$(firstChildSelectorJQ).trigger('click');
runFilter.bind($(firstChildSelectorJQ)[0])();
runFilter.bind(document.querySelector(selector))();
console.log("This selector is the requirement you gave")
runFilter.bind(document.querySelector(whatYouAskedFor))();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li>What You Asked For</li>
</ul>
<ul class="attractions-filters">
<li>UL 1, LI 1</li>
<li>UL 1, LI 2</li>
</ul>
<ul class="attractions-filters">
<li>UL 2, LI 1</li>
<li>UL 2, LI 2</li>
</ul>
You're very close!
Your code, modified below, with a few comments:
// altered to be a briefer document ready (Still no-conflict safe!)
jQuery(function( $ ) {
function runFilter( event ) {
event.preventDefault();
// add active class on the active nav item
$( 'ul.attractions-filters a' ).removeClass( 'active' );
$( this ).addClass( 'active' );
// add active class for visible things
term = $( this ).attr( 'data-term' );
$( '.type-attractions' ).removeClass( 'active' );
$( '.attractiontype-' + term ).addClass( 'active' );
}
// Show everything once the page is fully loaded
$( '.type-attractions' ).addClass( 'active' );
// On click, run the filter
$( 'ul.attractions-filters a' ).on( 'click', runFilter );
// NOTE: Choose ONE of the following three methods:
// Method #1: using trigger
$( 'ul.attractions-filters:first a' ).trigger( 'click' );
// Method #2: using click
$( 'ul.attractions-filters:first a' ).click();
// Method #3: better yet "chain" the methods to reduce duplicate code...
// NOTE: this replaces BOTH your .on('click') AND the .trigger or .click above...
$( 'ul.attractions-filters a' )
.on( 'click', runFilter )
.trigger( 'click');
});

Vertical Navbar should collapse when clicked anywhere other than the bar-icon

I have a verticalNavbar(having a bar-icon) which is based on toggle so when one clicks it toggles out(opens up) and clicks again it togglesin(closes). but however I want the navbar to toggle in(close) when user clicks anywhere on the web page other than the bar-icon(on verticalNavbar) - given that it was opened else the page click should not do nothing. I am finding it difficult to manage with jquery toggle, here's my code
$('.bar-icon').on("click", function(){
$( ".left-side" ).toggleClass('wdt80');
$( ".left-side" ).toggleClass('wdt210');
$('.left-side-inner').toggle('fast');
$( ".left-side" ).toggleClass("shadow");
$('.overlay').toggle();
});
<div class="bar-icon">
<a ><img src="///_baricon_img.jpg"></a>
</div>
My Solution -
// closing vertical navbar - while opened
$('.page').on("click",function(){
if ($('.left-side-inner').is(':visible')) {
$( ".left-side" ).toggleClass('wdt210');
$( ".left-side" ).toggleClass('wdt80');
$('.left-side-inner').toggle('fast');
$( ".left-side" ).toggleClass("shadow");
$('ul.sub-menu').hide();
// $('.overlay').toggle();
}
});
Michael, you could addClass instead of using toggleClass, also comparing if something has a class to prevent adding repeated classes, so you could do something like this:
$('.bar-icon').on("click", function(){
if($( ".left-side" ).hasClass('wdt210'){
$( ".left-side" ).addClass('wdt210');
$('.left-side-inner').show('fast');
$( ".left-side" ).addClass("shadow");
$('.overlay').show();
}
});
You can use document.click or window.click to achieve this.
$(window).click(function(){
//Close menu
});
$(document).on('click', function(){
//Close menu
});
Try to add class to navbar when it open and remove same when it is close. Use same class.
$(document).click(function() {
if($('.bar-icon').hasClass('active')) {
$('.bar-icon').trigger('click');
}
});

CSS - better way to remove class in this case?

I have a menu of 5 items. When I click any item, I add a class to change color on it. I also remove the color from the other 4 items, whether they have color or not. Is there a better way, perhaps through CSS, to remove those classes that aren't selected?
switch(currentC.data("template")) {
case "cataction1": {
currentC.addClass( "active cataction1Current" );
$( ".catbarlist li" ).not( currentC ).removeClass( "cataction2Current cataction3Current cataction4Current cataction5Current active activenotransit" );
break;
}
case "cataction2": {
currentC.addClass( "active cataction2Current" );
$( ".catbarlist li" ).not( currentC ).removeClass( "cataction1Current cataction3Current cataction4Current cataction5Current active activenotransit" );
break;
}
case "cataction3": {
currentC.addClass( "active cataction3Current" );
$( ".catbarlist li" ).not( currentC ).removeClass( "cataction1Current cataction2Current cataction4Current cataction5Current active activenotransit" );
break;
}
case "cataction4": {
currentC.addClass( "active cataction4Current" );
$( ".catbarlist li" ).not( currentC ).removeClass( "cataction1Current cataction2Current cataction3Current cataction5Current active activenotransit" );
break;
}
case "cataction5": {
currentC.addClass( "active cataction5Current" );
$( ".catbarlist li" ).not( currentC ).removeClass( "cataction1Current cataction2Current cataction3Current cataction4Current active activenotransit" );
break;
}
}
Drop using a unique class for each item and use a single common class for marking current item.
For example, with jQuery:
$(document).on('click', '.my-menu > LI', function() {
// Unmarking previously marked item.
$(this.parentNode).children('.cur').removeClass('cur');
// Marking new current item.
$(this).addClass('cur');
});
Example menu:
<li class="menu-item">
About
Home
</li>
Add the following CSS:
.menu-item .active{
background-color:#1B3E70;
color:white;
}
Then with jquery:
$('.menu-item a').click(function(){
$(this).addClass('active').siblings().removeClass('active');
});
Other solution might be:
$(document).on("click", ".catbarlist li", function(e){
$(this).addClass('active');
$(this).siblings('.active').removeClass('active');
});
I assume all those classes are necessary (as you have an .active class already). I also assume there's a good reason you're not using a click event.
If so, the first thing you could do is make it a lot cleaner/easier on yourself by creating a function to remove the unwanted styles. Lots of repeating code is not good -- hard to read, hard to maintain. For example:
function removeCatbarColor() {
$(".catbarlist li").removeClass("cataction1Current cataction2Current
cataction3Current cataction4Current cataction5Current active activenotransit");
}
And then calling it before applying the style to the active one:
switch(currentC.data("template")) {
case "cataction1": {
removeCatbarColor();
currentC.addClass( "active cataction1Current" );
break;
}
case "cataction2": {
removeCatbarColor();
currentC.addClass( "active cataction2Current" );
break;
}
...
There could probably be further improvements, but without seeing your HTML/CSS I can only guess. (Do you really need so many classes? A working JSFiddle would really help.)
A better way of handling things, given your description below, would be to have permanent classes for each cataction. So something like:
<ul>
<li class="cataction1">Link</li>
<li class="cataction2">Link</li>
<li class="cataction3">Link</li>
<li class="cataction4">Link</li>
</ul>
That way all you need in your CSS is:
.cataction1 {
// styles when not active
}
.cataction1.active {
// styles when active
}
// etc
Which allows you to simplify your JS like so:
$('li').on('click', function() {
$(this).siblings().removeClass('active');
$(this).addClass('active');
});
That is a much better way of handling things.

Changing the ID for an element doesn't work with jQuery

I want to change the ID of an element (a <div>) using jQuery. Below is an example of my JavaScript, CSS and HTML. Right now, when I click the <div>, nothing happens.
$( ".pre_div" ).click(function() {
$( ".pre_div" ).attr('id','after_div');
});
$( ".after_div" ).click(function() {
$( ".after_div" ).attr('id','pre_div');
});
#pre_div {width:20px;height:20px;background-color:red;cursor:pointer;}
#after_div{width:20px;height:20px;background-color:blue;cursor:pointer;}
<div id="pre_div">:-)</div>
. is for classes and # is for ids, plus you have to use the .on() function, otherwise it will not work
$(document).on('click','#pre_div',function() {
$(this).attr('id','after_div');
});
$(document).on('click','#after_div',function() {
$(this).attr('id','pre_div');
});
JSFIDDLE DEMO
You should use # – id selector – instead of . – class selector (also, you can use this to access element within it's event listener):
$( "#pre_div" ).click(function() {
$(this).attr('id','after_div');
});
$( "#after_div" ).click(function() {
$(this).attr('id','pre_div');
});
JSFiddle
Please use $(this) to refer to the clicked item otherwise you may give many item the same id. However, with this approach, you are still assiging the same id to each clicked div, which is not good. How about adding the index of the clicked div to make it a unique id:
$(".pre_div").click(function() { //any div with pre_div class
$(this).attr('id'+ $(this).index(),'after_div');
});
$(".after_div").click(function() { //any div with after_div class
$(this).attr('id'+ $(this).index(),'pre_div');
});
"pre_div" and "after_div" are not classes, they are id's of your div
Should access it like this way.
$( "#pre_div" ).click(function() {
$( "#pre_div" ).attr('id','after_div');
});
$( "#after_div" ).click(function() {
$( "#after_div" ).attr('id','pre_div');
});

JQuery button each click, show/hide forms

Guess I'm just starting out here, so might as well look for any kind of help since I'm quite frustrated with this novice question...
I have a button that shows a form I created, with 1 click, but the problem comes when I want to show another form that comes with another button.
What I want, basically is that buttonA shows formA, but when I click buttonB, I want to hide formA and show formB. Now what's happening is that it's overlaying formA and formB.
Here's my current code..
function runEffect() {
$( "#effect" ).show( "drop");
};
function runEffect2() {
$( "#effect2" ).show( "drop");
};
//callback function to bring a hidden box back
function hideEffect() {
$( "#effect:visible" ).hide( "drop");
};
// set effect from select menu value
$( "#button" ).each(function(index) {
$(this).click(function(){
runEffect();
});
});
$( "#button2" ).each(function(index) {
$(this).click(function(){
runEffect2();
});
});
$( "#effect" ).hide();
$( "#effect2" ).hide();
I know this is easy, but I can't seem to find the answer to it.
Thanks!
try this
function runEffect() {
$( "#effect" ).show( "drop");
$( "#effect2" ).hide( "drop");
};
function runEffect2() {
$( "#effect2" ).show( "drop");
$( "#effect" ).hide( "drop");
};
$('#buttonB').click(funciton()(
$('#formA').hide();
$('#formB').show();
});
something like this?
I haven't tested it, but maybe you want to a more dynamic function.
Button class must be something like "formButton" and the id like "form1Button", the form id then should be "form1" and so on..
(Form 2 would have a button with class "formButton", id like "form2Button" and form 2 needs id "form2"
$(".formButton").click(function(e) {
e.preventDefault(); //prevent default action
var id = $(this).attr('id');
var formId = id.replace('Button', '');
$('#' + formId).show();
$('form').not(document.getElementById(formId)).hide();
});
When a formButton is clicked, the form will be shown. All other forms, wich do not have the requested ID, will be hidden.

Categories