First of all, I am really new on JS or in any other programming language and this is my first post on Stackoverflow; Having said that, I apologize in advance for any mystake and let's go to the question.
I have this code and I need to change the classes of the li and the i elements with only one hover.
What I want is make both of them change their colors when I hover over them (the thing about the colors is just an example, as a matter of fact I will have to make some more changes), for example, If I hover over the li, the i also has its color changed and vice versa.
I provided two examples in my codepen, in the first one I selected the li and the i elements and in the second I selected the a element, all of them with their respective classes.
In the first one when I hover over the li its color changes but the i doesn't suffer any alteration and if I hover over the i it changes, but the li is kept the same.
In short, I need exactly the same effect of the codepen, but I need it happening with the text (li) and with the arrow(i) at the same time.
About the second example, it doesn't work well.
p.s. It is important that once an item has received the class active, it only backs to its original class when another item receives the hover and becomes active, if the cursor is moved to any other part of the screen then the item should hold the class, so that there is always an item with the class active.
https://codepen.io/WegisSilveira/pen/qzMqxj
<ul>
<a href="">
<li class="test">Banheiro</li>
<i class=" test ">></i>
</a>
<a href="">
<li class="test active">Cozinha</li>
<i class=" test">></i>
</a>
<a href="">
<li class="test">Quarto</li>
<i class="test">></i>
</a>
<a href="">
<li class="test">Varanda</li>
<i class=" test ">></i>
</a>
</ul>
<h1>-------------------------</h1>
<ul>
<a class="classA active" href="">
<li >Banheiro</li>
<i >></i>
</a>
<a class="classA" href="">
<li >Cozinha</li>
<i >></i>
</a>
<a class="classA" href="">
<li >Quarto</li>
<i >></i>
</a>
<a class="classA" href="">
<li >Varanda</li>
<i >></i>
</a>
</ul>
I'm having a bit of trouble understanding what you want, so two answers for two different interpretations of your Q:
Applied to each Element Individually
Based on Mobly's site navbar, you would want to essentially apply a rule for each element via CSS and/or JS/Jquery (note these are two seperate approaches, you can use either/or, though the CSS approach would usually be preferred):
CSS (or you can just change color instead of opacity):
.test {
color: black;
opacity: 0.7;
/* transition: opacity 0.5s; optional fun effect*/
}
.test:hover {
/* this would essentially be your active class */
opacity: 1.0;
}
JS Approach (w/Jquery; you can do it without Jquery, just more words to select):
$(".test").hover(function() {
$(this).children().addClass("active");
}, function() {
$(this).children().removeClass("active");
});
Using Siblings
CSS, standing for Cascading Style Sheets, cannot work backwards, but can work "sideways" to siblings. In CSS this is done with sibling selectors:
.test:hover, .test:hover ~ i {
color: red;
}
JS
$(".test").hover(function() {
$(this).addClass("active");
$(this).siblings().addClass("active");
}, function() {
$(this).removeClass("active");
$(this).siblings().removeClass("active");
});
Persistency of Class
It is important that once an item has received the class 'active', it
only backs to its original class when another item receives the hover
and becomes 'active'
To add a persistent class that only changes when another element becomes active, remove the event handler for hoveroff and instead remove the active class of all elements with the .active class:
Example Jquery:
$(".test").hover(function() {
$(".active").removeClass("active");
$(this).addClass("active");
$(this).siblings().addClass("active");
});
Other Recommendations
Instead of the <ul>, use the more semantically correct <nav> with only <a> tags underneath.
Use class instead of id; usually default to class unless you need id attribute.
NOTE TO OP: Let me know which sections actually helped answer your question specifically and I'll delete or strike through the rest.
<html>
<span id="my-id" class="one">Element</span>
<!-- Include jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(function() {
// attach event handler so that when you hover over it you change the class
$('#my-id').hover(function() {
// first remove class "one"
$(this).removeClass('one');
// next add class "two"
$(this).addClass('two');
// OR if you want to add and remove the same class you can use toggle
$(this).toggleClass('one'); // this will add "one" class if it is not there or remove it if it is there
});
});
</script>
</html>
The reason your code isn't working is that all your elements are sharing the same id. Put the "diamond" ID into the class attribute and remove the ID attribute from your elements.
ID is meant to be unique.
<ul>
<a href="" >
<li class="test active"</li>
<i class="flaticon-right-arrow test activeI"></i>
<i class="diamond flaticon-diamond"></i>
</a>
<a href="">
<li class="test">Banheiro</li>
<i class="flaticon-right-arrow testI "></i>
<i class="diamond flaticon-diamond"></i>
</a>
<a href="">
<li class="test">Cozinha</li>
<i class="flaticon-right-arrow testI "></i>
<i class="diamond flaticon-diamond"></i>
</a>
</ul>
Check this link, you can learn there how to use .removeClass() .addClass() and .toggleClass() jQuery methods. I highly recommend you to use jQuery instead plain JavaScript.
But the way, if you want to change the color is more efficient to use CSS than JS, you use that as follow:
.class{
color: red;
}
.class:hover {
color:blue;
}
There all the elements that have the class .class will be red, but when you enter the mouse in the element it will be blue ;)
Related
I want to hide the link field button when the value of the button equals to 'Work Order' see the image below.
My HTML code:
I tried this $("li[data-label='Work Order']").hide() but didn't worked.
The li is not the same element as the one with the data-label attribute. If you want to hide the <a> inside, use the selector string a[data-label='Work%20Order']:
$("a[data-label='Work%20Order']").hide()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a data-label="Work%20Order">link</a>
You do need to use the %20 inside the selector.
If you want to always hide such an element, you can achieve this with CSS alone - no need for jQuery or any Javascript at all. Use the same selector string plus display: none:
a[data-label='Work%20Order'] {
display: none;
}
<a data-label="Work%20Order">link</a>
If you want to hide the whole <li> container when one of its children has such an attribute, then select each of those elements with jQuery and call .parent() on it:
$("a[data-label='Work%20Order']").parent().hide();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li>
<a data-label="Work%20Order">link</a>
</li>
<li>
<a>link 2</a>
</li>
<li>
<a data-label="Work%20Order">link 3</a>
</li>
</ul>
I am working through an issue where I have a menu that is mutli levels deep. I am trying to get it so that if a first level element is clicked (add class .ubermenu-active) it will look for any other first level element with that class and remove it.
$('.ubermenu-item-level-0 span').on('click',function() {
var target = $('.ubermenu-item-level-0');
$('.ubermenu li.ubermenu-item-level-0').removeClass('ubermenu-active');
target.parents('.ubermenu li.ubermenu-item-level-0').toggleClass('ubermenu-active');
});
HTML (mock):
<ul class="ubermenu">
<li class="ubermenu-item-level-0">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 1</span>
</a>
<ul class="ubermenu-submenu">
<li class="ubermenu-item-level-1">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 2</span>
</a>
</li>
<li class="ubermenu-item-level-1">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 2</span>
</a>
<ul class="ubermenu-submenu">
<li class="ubermenu-item-level-2">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 3</span>
</a>
</li>
</ul>
</li>
</ul>
<li class="ubermenu-item-level-0">
<a class="ubermenu-target">
<span class="ubermenu-target-title">Level 1</span>
</a>
</li>
</li>
</ul>
Right now if any of the sub elements are clicked the parent closes
Currently your target var is selecting all elements with class .ubermenu-item-level-0, so when you toggle the class you're toggling all parent elements. Your target var should be something relative to the element clicked, like var target = $(this).closest('.ubermenu-item-level-0');
So, your sample HTML isn't what I expected to see . . . specifically, your second <li class="ubermenu-item-level-0" . . . element is currently showing as a child under the first one, while your description makes it sound like they should be siblings.
For the sake of the solution I'm going to assume that those two lis are supposed to be siblings of each other and that somehow the code got mixed up. :)
So, here's how I would handle it . . .
var sFirstLevelMenuClass = ".ubermenu-item-level-0";
var sActiveMenuClass = "ubermenu-active";
var $firstLevelMenuOptions = $(".ubermenu").find(sFirstLevelMenuClass);
$firstLevelMenuOptions.children("a").children("span").on("click", function() {
$firstLevelMenuOptions.removeClass(sActiveMenuClass);
$(this).closest(sFirstLevelMenuClass).addClass(sActiveMenuClass);
});
Basically, I've simplified your logic and fixed one small issue that you had in your jQuery code.
Detailed Explanation
The issue was that when you used $('.ubermenu-item-level-0 span') as your selector for your change event. That translates to "any span element that is a descendant of a ubermenu-item-level-0 element". So, in addition to the spans that are directly under the ubermenu-item-level-0 list items, it was also picking up the ones under the ubermenu-item-level-1 and ubermenu-item-level-2 elements, since they are also descendants.
So, I changed your selector to $firstLevelMenuOptions.children("a").children("span") which translates to "all spans, that are direct children of an a, that is the direct child of an ubermenu-item-level-0 element" (Note: $firstLevelMenuOptions is set to equal $(".ubermenu").find(".ubermenu-active"); through the logic earlier in the code). This stops the selector from picking up the lower level spans.
Outside of that and trimming down some of your selectors to be more efficient, the only other thing that I changed was the flow of how the ubermenu-active class is manipulated. In my solution, there are two steps:
Remove ubermenu-active from ALL ubermenu-item-level-0 elements
Add ubermenu-active to the closest ubermenu-item-level-0 element to the span that was clicked (i.e., $(this))
That basically resets the list and then reselects the appropriate menu item to me active.
You can stop the event propagation:
event.stopPropagation()
Without seeing the full HTML, I was going to suggest trying this:
$('.ubermenu-item-level-0 span').on('click',function(e) {
e.stopPropagation();
var target = $('.ubermenu-item-level-0');
$('.ubermenu li.ubermenu-item-level-0').removeClass('ubermenu-active');
target.parents('.ubermenu li.ubermenu-item-level-0').toggleClass('ubermenu-active');
});
I have a side menu that when clicked slides out to reveal a content panel. Based on the menu item clicked I obviously need different stuff to populate in the panel.
I wrote a function to operate the menu/panel and it partially works. However, I am trying to determine what to load based on event.target.id (as the function takes event) but it only has a value when I click very close to the edges of the linked square. When I click near the actual text which are h1 and h6 and have no id's it doesn't work.
Live demo (click near the edges of the 'Styles' square and then in the middle): http://jsfiddle.net/mANuD/
<div id="application-frame">
<div class="panel"></div>
<ul id="slide-out-menu">
<li>
<a href="#" class="item" id="styles-menu">
<h1>S</h1>
<h6>Styles</h6>
</a>
</li>
<li>
<a href="#" class="item" id="designers-menu">
<h1>D</h1>
<h6>Designers</h6>
</a>
</li>
<li>
<a href="#" class="item" id="code-menu">
<h1>C</h1>
<h6>Code</h6>
</a>
</li>
<li>
<a href="#" class="item" id="help-menu">
<h1>?</h1>
<h6>Help</h6>
</a>
</li>
</ul>
</div>
How can I fix/improve this so that it doesn't matter where in the linked area I click?
Change event.target.id to event.currentTarget.id or this.id.
The event.target is always the deepest element clicked, while event.currentTarget or this will point to the element to which the handler is bound, or to the element that the delegate selector matched.
It sounds like there's a border or padding on some of the descendant elements, and so event.target is a descendant of the element on which the handler is (effectively) hooked up.
Two options:
Use this.id to get the id of the element the handler was (effectively) bound to. This usually does what you want. Updated Fiddle
I don't think you need it in this situation, but the other handy tool in the toolkit for this is closest, which finds the first element matching a selector by looking at the element you give it, then its parent, then its parent, etc. So for instance, $(this).closest(".item").attr("id") or $(event.target).closest(".item").attr("id") (since the items you want have class item). Updated Fiddle But again, I believe #1 is what you want in this case.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="topbar">
<ul>
<li class="active">
About Us
</li>
<li>
Services
</li>
<li>
Gallery
</li>
<li>
Get Quote
</li>
</ul>
</div>
How to set class Active on li 2,3,4... where hover, and remove class active has a go
Thank you!
Unless you need it to be active for some kind of query down the line (I personally don't know why you would, though), try CSS.
li:hover {
// Active class CSS here
}
You can add further selectors to the li to keep yourself from selecting other lists on the page, and it doesn't take any JavaScript, JQuery, or fancy coding.
The :hover psuedo-selector will make it where it applies the CSS to the element that you're hovering over.
I am sliding content when the corresponding header is clicked using slidetoggle. Now I want to toggle between classes simultaneously.
I can use toggleclass and have all of the classes toggled irrespective of which one of the header is clicked, but I'm having trouble in toggling only the class corresponding to the headerclicked.
Here is my code:
<div class="Title ">
<a class="Expanded" href="#">Title1<span id="span1" class="ArrowDown"></span></a>
</div>
<ul class="Content">
<a href="#">
<li class="selected">hello1</li></a> <a href="#">
<li>hello2</li></a>
</ul>
<div class="Title">
<a class="Expanded" href="#">Title2<span id="span2" class="ArrowDown"></span> </a>
</div>
<ul class="Content">
<a href="#">
<li>hello3</li></a>
<a href="#">
<li>hij</li></a>
</ul>
Here is my script:
$(document).ready(function(){
$(".Title").click(function(){
$(this).next(".Content").slideToggle("slow");
$("#span1").toggleClass("ArrowUp", "ArrowDown");
});
});
I just put the id of the first span here, but I tried different things, but couldn't figure out what to do... I want the class of span toggled between ArrowUp and ArrowDown when the corresponding title is clicked (expanded or collapsed).
You can also use the power of jQuery chaining to write this in a single line like so.
$(this).find('span').toggleClass("ArrowUp", "ArrowDown").end()
.next(".Content").slideToggle("slow")
;
The two things to note in this are .find() (which gets the descendants of matched elements filtered by a selector) and .end() (which ends the most recent filtering operation in the current chain and returns the set of matched elements to its previous state.)
In the click callback function, make use of the this keyword, and combine it with the power of the .find() method.
example:
$('element').click(function() {
$(this).find('span').toggleClass('myclass');
});
$(this).find(' span').toggleClass("ArrowUp", "ArrowDown");