So when someone hover a <li> I need that my Div get his class changed.
How can I do This?
Is this possibile using only css or do I need to put some JS inside?
Edit 1: each li will have a especific id, and the div would recive the id as a class.
I think you should to use JQuery:
$(document).ready(function(){
$("li").mouseover(function(event){
$("#capa").addClass("class");
});
});
To assign a class to the parenting <div> element based on the ID of a hovered child <li>, first check for the hover and get the ID name, then assign it to the parenting <div>.
The following is a code that you will be able to use for several divs on a page, and it will reset the class names on leaving the <li> hover, by using the out handler of the jQuery method:
$(".changeme ul li").hover(function(){
$(this).parents("div").addClass($(this).attr("id"));
}, function(){
$(this).parents("div").removeClass($(this).attr("id"));
});
.changeme{
background-color:#eee;
}
.changeme.firstli{
background-color:#ffd;
}
.changeme.secondli{
background-color:#fdd;
}
.changeme.thirdli{
background-color:#dfd;
}
.changeme.fourthli{
background-color:#ddf;
}
.changeme.fifthli{
background-color:#ddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="unaffected">
<p> some other parenting div, not affected</p>
<div class="changeme">
<p>some text, nothing changes</p>
<ul>
<li id="firstli">we are changing our parentting div!</li>
<li id="secondli">we are changing our parentting div!</li>
<li id="thirdli">we are changing our parentting div!</li>
</ul>
<p>some text, nothing changes</p>
<ul>
<li id="fourthli">we are changing our parentting div!</li>
<li id="fifthli">we are changing our parentting div!</li>
</ul>
<p>some text, nothing changes</p>
</div>
</div>
https://jsfiddle.net/svArtist/adq5dr68/
Go to your div style class definitions and add "li:hover" near the name;
.yourDiv { font-size:14pt; }
then turn to this
.yourDiv li:hover { font-size:14pt; }
You could just use the :hover property, that way you wouldn't have to change the div's class, which you can only do with javascript.
CSS hover attributes can be used to specify how an element should appear on hover, but not how some other element should appear when the first is hovered over. Achieving behavior of that complexity requires a touch of JavaScript.
(function() {
var div = document.getElementById("parent"); // save a reference to the target div
var lis = div.querySelectorAll("li"); // get your <li> tags
for (var i = 0, len = lis.length; i < len; i++) {
lis[i].onmouseover = updateDivClass; // attach the event listener to each tag
}
div.onmouseout = function() { // remove class when no longer hovering over div
this.className = "";
};
function updateDivClass() { // apply class to div when hovering over <li> tag
div.className = this.id;
}
})();
.Class1 {
background-color: #df7000;
font-family: Calibri;
color: black;
}
.Class2 {
background-color: purple;
color: white;
font-family: Segoe UI;
}
.Class3 {
background-color: black;
color: lightgreen;
font-family: courier;
}
<div id="parent">
Hover over a class below to apply the class to the entire div.
<ul>
<li id="Class1">Black Calibri with Orange Background</li>
<li id="Class2">White Segoe UI with Purple Background</li>
<li id="Class3">Light Green Courier with Black Background</li>
</ul>
</div>
Related
I have a nav menu that needs to trigger with clicks rather than hovers. When the links are clicked, an .open class would be added to the parent li. If that parent already has the .open class, then it would get removed. It would also be removed if another link is clicked on. So far I can get the class added when clicked and removed when a sibling is clicked, but not removed when it's already .open.
I tried adding a hasClass conditional, but that didn't work either. Seemed like it reruns the function every time it's clicked and therefore ignores the hasClass conditional.
Can anyone provide help? I tried toggleClass, but that didn't work.
$('li a').on('click', function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
To do what you require you can use toggleClass() on the parent li when the element is clicked. To remove the class from all other li elements you can use removeClass() along with not() to exclude the current li. Try this:
$('li a').on('click', function() {
let $li = $(this).parent().toggleClass('open');
$('li').not($li).removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
You can use
jquery toggleClass() to toggle yellow highlight (.open css class) on click/unclicking the same link.
jquery siblings() to remove .open class on all the other li items.
Below is the link for the demo
https://jsfiddle.net/so1u8hq6/
$('li a').on('click', function() {
$(this).parent().siblings().removeClass('open');
$(this).parent().toggleClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 2
</li>
<li>
Item 3
</li>
</ul>
</nav>
Late to the party, but, after seeing the provided answers and some of the CSS you use I had to urge with my suggestions:
UX. Avoid styling LI tags in general, or at least set the desired display and move on. Style directly the a tag (with the necessary paddings etc.). You'll not only get less CSS to take care of, but also a larger touch interaction area. Makes no sense to style something yellow if it's not a UI part of something interactable. Also in JS, you don't need to take care about the LI wrappers any more - but only about the actual A Elements.
Don't use common selectors like $('li a') - those might target any LI→A elements in your app. Instead be more specific and use a Class like i.e: .tabs for the parent UL. Both in CSS and JS.
Try to use Event Delegation (in jQuey using the .on() method). Not only it will help you to catch the Event.delegateTarget parent UL where needed, but also the this (the clicked element), but mainly reference all the "group" of a elements enclosed in the common parent. That way you can have as many .tabs in a single page as you like. And yes, thanks to Event delegation you can even add dynamically LI Elements - and your JS will still work as expected.
Since you're using <a href="#"> Anchor elements, instead of (more properly) <button type="button>" Elements, you need to also use Event.preventDefault() in order to prevent the browser its default behavior and that's to follow anchors (scroll the page, navigate, etc...)
Use the selector "a.open" when you want to target and remove the "open" class. By just using "a" (or in other answers on this page - "li") you're uselessly touching elements trying to remove a class that's not there in the first place.
Finally, here's the CSS retouch and the proper jQuery needed for your task:
$(".tabs").on("click", "a", function(ev) {
ev.preventDefault();
$("a.open", ev.delegateTarget).not(this).removeClass("open");
$(this).toggleClass("open");
});
.tabs {
display: flex;
list-style: none;
padding: 0;
}
/* Style your Anchors, not the dummy LI wrappers */
.tabs a { padding: 10px; }
.tabs a.open { background-color: yellow; }
<ul class="tabs">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
To explain the only complicated line:
$(
"a.open", // Target just the ones (if any) of class "open"
ev.delegateTarget // inside the common ".tabs" ancestor
)
.not(this) // ... not the clicked element (since later we'll use .toggleClass on it)
.removeClass("open"); // ... remove that class "open"
the rest is pretty self explanatory.
Further read:
jQuery Event Delegation
jQuery event.delegateTarget
Event.preventDefault
So you only want the yellow background to appear as a signifier of user interaction rather than for the background color to be displayed? Have you tried using the mousedown/mouseup functions instead of .on('click', function(){...}?
I was able to simulate the click event where the color showcases via this method:
$('li a').mousedown(function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
$('li a').mouseup(function() {
$('li a').parent().removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
Ok, so i have an unordered list and it has two items. Now in my javascript i am trying to add event listener to these items so that a CSS class can be applied to them once clicked. here is the code. can anyone fill the missing part in here.Thanks
html part:-
<body>
<h3>Simple Add/Remove Task</h3>
<h4>To do List</h4>
<ul>
<div>
<li class="todos">Wake up</li>
<li class="todos">Study</li>
</div>
<div>
<button>Delete</button><br>
<button>Delete</button>
</div>
</ul>
<script type="text/javascript" src="./script.js"></script>
</body>
Js part:-
var listItems = document.getElementsByClassName("todos");
for (var i = 0; i<listItems.length; i++){
listItems[i].addEventListener("click", function(){
})
}
Just add or toggle the desired class with classList.add() or classList.toggle().
Also (FYI):
Headings should not be used because of the way they style the text
within them. As with everything else in HTML, they are semantic. You
shouldn't have an h4 unless you want a new sub-section to an h3,
which you wouldn't have unless it was a sub-section of an h2 an so
on. You can (and should) do your formatting with CSS, not HTML.
It is also invalid to put a div directly inside of a ul. Only
li, script, or template elements can be children of a ul or
ol.
Don't use .getElementsByClassName(). Use .querySelectorAll() instead.
var listItems = document.querySelectorAll(".todos");
for (var i = 0; i<listItems.length; i++){
listItems[i].addEventListener("click", function(){
this.classList.toggle("active"); // each click toggles the use of the class
});
// While looping over the bullets, search for the button within each
// and set up a click handler for when the delete button gets clicked
// .closest() will look for the nearest ancestor that matches the selector.
listItems[i].querySelector("button").addEventListener("click", function(){
this.closest(".todos").remove();
});
}
h1 { font-size: 1.2em; }
h2 { font-size: 1em; }
.active { background-color:yellow; }
<h1>Simple Add/Remove Task</h1>
<h2>To do List</h2>
<ul>
<li class="todos">Wake up <button>Delete</button></li>
<li class="todos">Study <button>Delete</button></li>
</ul>
use this line in js to change the class:
listItems[i].className = 'cssClass';
and then make some 'cssClass' css. Unless you want to make the css created in js, in which case you would do this beforehand:
var style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = '.cssClass { color: green; }';
Use for...of to iterate over the elements.
Use the event.currentTarget to get the selected element.
Use classList.add to add a class to an element
var listItems = document.getElementsByClassName("todos");
for (let listItem of listItems) {
listItem.addEventListener("click", event => {
event.currentTarget.classList.add('selected')
})
}
.selected {
background: green;
}
<body>
<h3>Simple Add/Remove Task</h3>
<h4>To do List</h4>
<ul>
<li class="todos">Wake up</li>
<li class="todos">Study</li>
</ul>
</body>
Sorry if this is an extremely simple question, but for some reason, I cant get this working.
What I'm trying to do is to add the activeButton class to each list item you click and remove the activeButton class to the list-item that had the activeButton class before the list-item was clicked.
Here is a code snippet of my problem
$(document).ready(function () {
$('.buttons').click(function () {
$('.activeButton').removeClass('.activeButton');
$(this).addClass('.activeButton');
});
});
.buttons {
/*This is for decorative and visual purposes.
So you can ignore the CSS for now.*/
display: inline-block;
margin: 10px;
}
.activeButton {
border-bottom: 1px solid black;/*I use border-bottom to provide underlines for my text. This allows the underline to be transitioned or animated*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="buttons activeButton">Link1</li>
<li class="buttons">Link2</li>
<li class="buttons">Link3</li>
<li class="buttons">Link4</li>
</ul>
For the sake of clarification, I will explain my goal and the current problem.
GOAL: Once a list item is clicked, the class .activeButton will be added to the list item that was clicked and the JS will remove .activeButton from the list item that originally had the activeButton class.
PROBLEM: The attempted solution that I have coded does not work.
Like this you mean?
$(document).ready(function () {
$('.buttons').click(function () {
$('.buttons').removeClass('activeButton'); // <-- remove from all .buttons class
$(this).addClass('activeButton'); // <-- add to clicked link only
});
});
.buttons {
/*This is for decorative and visual purposes.
So you can ignore the CSS for now.*/
display: inline-block;
margin: 10px;
}
.activeButton {
border-bottom: 1px solid black;/*I use border-bottom to provide underlines for my text. This allows the underline to be transitioned or animated*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="buttons activeButton">Link1</li>
<li class="buttons">Link2</li>
<li class="buttons">Link3</li>
<li class="buttons">Link4</li>
</ul>
You don't need the class selector in the strings you pass to addClass() and removeClass().
Update as follows:
$(function () {
$('.postalProvider').click(function () {
$('.activeButton').removeClass('activeButton');
$(this).addClass('activeButton');
});
});
Update :
$(document).ready(function () {
var $buttons = $('.buttons');
$buttons.click(function () {
$buttons.removeClass('.activeButton');
$(this).addClass('.activeButton');
});
});
I think this is what you were after.
I have trouble in writing a script to change the appearance of the clicked tab in a webpage navigation list. In other words, I want to make the clicked tab appear as the selected (in code). I tried to do that by changing its id to selected_link and restoring the id of the previously selected tab.
EDIT: Following jamespaned's suggestion, I replaced element IDs with classes.
My tabs appear like in this picture:
So, when I click to "bio", I want it to appear as "home" and "home" to appear as the other tabs.
As I'm a newbie in JavaScript coding, I didn't managed to accomplish that. Here is what I've done:
The HTML code for the (inline) navigation list:
<nav>
<ul id="navlist">
<li class="selected"> home </li>
<li class=""> bio </li>
<li class=""> publications </li>
<li class=""> software </li>
<li class=""> contact </li>
</ul>
</nav>
its respective CSS:
nav ul {
list-style:none;
padding:0;
margin:0;
}
nav li {
background-color:black;
display:inline;
border:solid;
border-width:1px 1px 0 1px;
margin:0 5px 0 0;
}
nav li a {
color:white;
padding:0 10px;
}
.selected {
background-color:white;
padding-bottom: 1px;
}
.selected_link{
color:blue;
}
and the JavaScript which I've designed to accomplish this task, but it didn't worked:
function changeSelected(clickedId)
{
var ulist = document.getElementById("navlist");
var elems = ulist.getElementsByTagName("class");
for (var i = 0; i < elems.length - 1; i++)
{
var sel = elems[i].getAttribute("class");
if (sel == selected)
{
var selli = elems[i];
break;
}
}
selli.setAttribute("class", "");
selli.lastElementChild.setAttribute("class", "");
var clicked = document.getElementById(clickedId);
clicked.setAttribute("class", "selected_link");
clicked.parentNode.setAttribute("class", "selected");
}
How could I do that using only plain JavaScript?
This Javascript will do what you want:
function changeSelected(clickedId)
{
var selli = document.getElementById("selected");
var sela = document.getElementById("selected_link");
sela.setAttribute("id", "");
selli.setAttribute("id", "");
var clicked = document.getElementById(clickedId);
clicked.setAttribute("id", "selected_link");
clicked.parentNode.setAttribute("id", "selected");
}
That said, here are some ideas that might help your Javascript education:
You are using Javascript to set your IDs, but the Javascript won't work on the next page after you've clicked on one of the links. You'll probably need to do some backend (PHP/Ruby, etc) coding to get your styles to change.
IDs are normally used to refer to a unique element on the page that doesn't change, such as a #header or #sidebar_banner. You might want to use a class instead, such as ".selected_link".
You don't need both #selected_link and #selected. You could do ".selected" and ".selected a" to change the CSS so you only need to change one element.
Hope that helps!
I'm in the process of learning Javascript and I'm trying to create a simple dropdown menu.
An example of my desired functionality can be seen on the google homepage in the top menu with the "more" and "settings" dropdown.
I have a ul that is set to display:inline using the onclick() JS event handler. How do I make the ul go back to display:none when I click any where else on the page other than the now visible ul?
I've Googled about blur and setting the focus to another element but I don't know how to actually do it.
I want to do this in straight Javascript, not jQuery.
Here is the html I use:
<div class="info">
Some Text Boom A <a onclick="menu('id1');">Link</a> | More text
<a onclick="menu('id2');">Another Link</a> | more text
<ul id="id1" class="submenu">
<li>A1</li>
<li>A2 This is Long</li>
<li>A3</li>
</ul>
<ul id="id2" class="submenu">
<li>B1</li>
<li>B2</li>
<li>B3</li>
</ul>
</div>
When the user clicks on one of the linked <a> tags, the <ul> which is hidden and directly below the <a> tag becomes visible. I want the <ul> element to dissapear when the user clicks anywhere but the <ul>.
Edit:
Here is my javascript:
function menu(id) {
var myLayer = document.getElementById(id);
if (myLayer.style.display == "none" || myLayer.style.display == "") {
myLayer.style.display = "block";
} else {
myLayer.style.display = "none";
}
}
Edit 2:
Complete CodE:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Untitled 1</title>
<style type="text/css">
a
{
color:blue;
}
.info ul.submenu
{
border: solid 1px #e0e0e0;
background-color: #fff;
position: absolute;
padding: 0;
z-index: 2;
display: none;
}
.info ul.submenu li
{
display: block;
border-top: solid 1px #e0e0e0;
margin: 0px 10px 0 10px;
}
.info ul.submenu li a
{
display: block;
padding: 7px 0px 6px 0;
color: #1177ee;
cursor:pointer;
}
</style>
<script type="text/javascript">
function menu(id) {
var myLayer = document.getElementById(id);
myLayer.onblur = function() {
myLayer.style.display = 'none';
};
if (myLayer.style.display == "none" || myLayer.style.display == "") {
myLayer.style.display = "block";
} else {
myLayer.style.display = "none";
}
}
</script>
</head>
<body>
<div class="info">
Some Text Boom A <a onclick="menu('id1');">Link</a> | More text
<a onclick="menu('id2');">Another Link</a> | more text
<ul id="id1" class="submenu">
<li>A1</li>
<li>A2 This is Long</li>
<li>A3</li>
</ul>
<ul id="id2" class="submenu">
<li>B1</li>
<li>B2</li>
<li>B3</li>
</ul>
</div>
</body>
</html>
This is quite simple actually.
Once you have a reference to the DOM element that you want to bind the blur event listener to, assign it like this:
myLayer.onblur = function() {
myLayer.style.display = 'none';
};
jQuery creates a blur event you can bind a function to, is there a strong reason not to use jQuery? Using a JavaScript library even if it is just for event handling, helps insulate you from browser differences. I've only ever used focus/blur events for text input or textarea elements in a form. It sounds like you want a list to float on top of the other elements. I'd position the list relatively and give it a z-index that is higher than the background. I'd bind a click event to the area outside the list, to dismiss the list pop-up. Is toggling a pop-up/modal window what you want? I'd have a look at jQuery SimpleModal for modal window examples, or look at how one is implemented if you want to roll your own.
If you are looking for a way to stop "onclick" event if it happens inside your menu then "event.stopPropagation();" may be what you need
<body onclick="menu('id1'); menu('id2');">
<div class="info">
Some Text Boom A <a onclick="menu('id1');">Link</a> | More text
<a onclick="menu('id2');">Another Link</a> | more text
<ul id="id1" class="submenu" onclick="alert('click menu'); event.stopPropagation();">
<li>A1</li>
<li>A2 This is Long</li>
<li>A3</li>
</ul>
<ul id="id2" class="submenu" onclick="alert('click menu'); event.stopPropagation();">
<li>B1</li>
<li>B2</li>
<li>B3</li>
</ul>
</div>
</body>