I am trying to style each <li> element at a time on click, not all at once. For each click, the first one, then on the second click, the next one and so on...
This code puts style on all li elements at once. How do I do it?
$("a").click(function() {
var menu = document.getElementsByTagName("li");
for (var i = 0; menu[i]; i++) {
$(menu).css("background", "red");
}
});
p {
color: red;
margin: 5px;
cursor: pointer;
}
p:hover {
background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a>sdadsa</a>
<ul>
<li>asda</li>
<li>sadada</li>
<li>sada</li>
<li>asdad</li>
</ul>
You can use jQuery's .css() to check the css value of specified element
$("a").click(function() {
var menu = document.getElementsByTagName("li");
for (var i = 0; menu[i]; i++) {
// get element of current index
const menuElement = menu[i];
// if the first element's background is not red.
if ($(menuElement).css("background") !== "red") {
// set it red.
$(menuElement).css("background", "red");
// escape for loop
break;
}
}
});
You can use a variable that points to current li element which should change background on the next click. When the anchor tag is clicked we remove the background of previous li element and change the current element's background
<script>
let current = 0;
$("a").click(function () {
var menu = document.getElementsByTagName("li");
let prev = current-1;
if(prev==-1) prev = menu.length-1;
menu[prev].style.background = "none";
menu[current].style.backgroud = "red";
current = (current + 1)%menu.length;
});
</script>
One approach would be to add a class to do the styling.
When you click your element find the first <li> that doesn't have that class and add it to that one.
Adding and removing classes is typically easier than modifying and undoing inline style
$("a").click(function() {
$('li').not('.red-bg').first().addClass('red-bg')
});
.red-bg {background:red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a>sdadsa</a>
<ul>
<li>asda</li>
<li>sadada</li>
<li>sada</li>
<li>asdad</li>
</ul>
Related
I have a div container with a certain number of div's created with a for loop inside of it. When i click one of these a divs, i need to make it change the colour. My problem is can't figure out how to select an specific element with the addEventListener to change the color.
<body>
<div id="main-container"></div>
<script src="script.js"></script>
</body>
const mainContainer = document.getElementById("main-container");
for (let i = 0; i <= 11; ++i) {
const gridChildrens = document.createElement("div");
gridChildrens.setAttribute("class", `gridChildrens`);
const grids = document.querySelector('.gridChildrens')
mainContainer.appendChild(gridChildrens);
}
For the moment, i figure out how to change the color of the firt or the last of the elements with a click listener, but not for the rest of the of the divs.
For the moment, i figure out how to change the color of the firt or the last of the elements with a click listener, but not for the rest of the of the divs.
I expect to click any of the divs and change the color.
Try to add an event listener to each div created in the loop and then use 'this' to set your colour. Here's an example :
const mainContainer = document.getElementById("main-container");
for (let i = 0; i <= 11; ++i) {
const gridChildrens = document.createElement("div");
gridChildrens.setAttribute("class", `gridChildrens`);
gridChildrens.addEventListener('click', function() {
this.style.backgroundColor = 'red';
});
mainContainer.appendChild(gridChildrens);
}
Code snippet sample:
<html>
<head>
<style>
.gridChildrens {
width: 50px;
height: 50px;
background-color: blue;
margin: 10px;
}
</style>
</head>
<body>
<div id="main-container"></div>
<script>
const mainContainer = document.getElementById("main-container");
for (let i = 0; i <= 11; ++i) {
const gridChildrens = document.createElement("div");
gridChildrens.setAttribute("class", `gridChildrens`);
gridChildrens.addEventListener('click', function() {
this.style.backgroundColor = 'red';
});
mainContainer.appendChild(gridChildrens);
}
</script>
</body>
</html>
To explicitly target an element the querySelector without click event (which will inspect the event.target ) you can use the nth-child or nth-of-type style css selector as below.
To identify an element based upon user click the event itself will expose the target property which will be the element that caused the event handler to fire. The following uses a delegated event listener bound to the document itself which processes all click events if required but here responds only to those bound to the gridChildrens elements
const mainContainer = document.getElementById("main-container");
for (let i = 0; i <= 11; ++i) {
const div = document.createElement("div");
div.setAttribute("class", `gridChildrens`);
div.textContent=i;
mainContainer.appendChild( div );
}
document.querySelector('.gridChildrens:nth-of-type(4)').classList.add('banana')
document.querySelector('.gridChildrens:nth-of-type(7)').classList.add('banana')
document.querySelector('.gridChildrens:nth-of-type(10)').classList.add('banana')
document.addEventListener('click',e=>{
if( e.target instanceof HTMLDivElement && e.target.classList.contains('gridChildrens') ){
e.target.classList.toggle('tomato')
}
})
.gridChildrens{
width:50%;
height:1rem;
margin:0.25rem;
}
.banana{
background:yellow
}
.tomato{
background:tomato
}
<div id="main-container"></div>
This should give you a good idea of how to use addEventlistner. Basically, you can pass the event object whenever you make some event. That has all the information of the specific div that you are looking for, you can change anything with that. But remember to bind the elements with addEventlistner first.
var containers= document.getElementsByClassName("container");
const changeColor = (e)=>{
if(e.target.style.background =="orange"){
e.target.style.background ="red"
}
else
e.target.style.background ="orange";
}
for(var i=0; i< containers.length; i++){
containers[i].addEventListener('click',function(e){
changeColor(e)
} );
}
.container{
height:50px;
width:100px;
background: #000;
margin :10px 10px;
border-radius:10px;
cursor:pointer;
}
.holder{
display:flex;
flex-wrap:wrap;
}
<div class="holder">
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
</div>
There are several ways to do this. For example, you can add the same class to your divs inside the loop. Then you can access them via document.querySelectorAll('.class-name'). So smth like this:
[...document.querySelectorAll('.class-name')].forEach( el => {
el.addEventListener('click', (e) => { changeColor(e); });
});
Any Help would be very much appreciated! I'm working on Angular8. For further assistance, I also watched an image in which you can see all the div are being selected on whichever image I click. Instead of removing border effect from the previous image and showing only on selected div.
My HTML Code
<img
src="{{category?.CategoryImage || 'https://giftclubimagestorage.blob.core.windows.net/images/biryani.jpg'}}"
class="rounded-circle"
alt="{{category?.CategoryTitle || ''}}" class="imgrr">
</div>
</div>
My CSS Code
.icon:hover {
border: 2px solid red;
}
.selitem
{
border: 20px solid blue;
}
My TS Code
[![public sel(event): void {
const divs = document.getElementById('container').getElementsByTagName('div');
for (let i = 0; i < divs.length; i++) {
if (divs\[i\] !== event.target) {
divs\[i\].className = 'icon';
}
}
event.target.className = 'selitem';
}]
For this I would have every image that is a select-able have a class such as .selectable and on click point to a function such as:
function clickHandler(element) {
// Get currently selected element(s)
const old = document.getElementsByClassName("selectable");
for (i = 0; i < old.length; i++) {
// Remove current selected class
console.log(old[i].classList.remove("selected"));
}
// On element that called the function add selected class
element.classList.add("selected");
}
Live example on JSFiddle: https://jsfiddle.net/36pszgxo/15/
If I'm looping through different elements with the same class with mouseenter / mouseout events and I'm trying to incorporate the 'this' keyword so the JS only triggers on the element I'm hovering over. I can't get it to work though.
I've stripped out my attempts to use the 'this' keyword to make the code easier to read. How do I go about having it so that only the element being hovered over has the mouseenter and then mouseout events applied to it whilst looping through the elements?
I can't use a jQuery solution.
codepen pen: https://codepen.io/emilychews/pen/mMEEBw
Code is below:
JS
// declare variable for the CSS class
var menuItem = document.querySelectorAll('.menu-item');
//loop through CSS class to change background to red
function myMouseEnter() {
for (i = 0; i < menuItem.length; i++) {
menuItem[i].style.background = "red";
}
}
//loop through CSS class to change remove red background
function myMouseLeave() {
for (i = 0; i < menuItem.length; i++) {
menuItem[i].style.background = "none";
}
}
//event handler to add function on mouseenter
for (j = 0; j < menuItem.length; j++) {
menuItem[j].addEventListener('mouseenter', myMouseEnter, false)
}
//event handler to add function on mouseout
for (k = 0; k < menuItem.length; k++) { menuItem[k].addEventListener('mouseout', myMouseLeave, false)
}
CSS
.menu-item {padding: 10px;
font-family: arial;
}
HTML
<ul class="unclick--menuitems">
<li class="menu-item">About</li>
<li class="menu-item"><a href="//google.com">Projects</a</li>
<li class="menu-item">Contact</li>
</ul>
In your two functions, all you need to do is refer to this. In that context, this refers to the .menu-item event that you are currently hovering over.
Note that you'll also probably want to attach a handler for the <a> tag children, or else whenever you hover over them, the script will think you're leaving the <li>, and attempt to change the colours.
This can be done by checking the toElement and relatedTarget of the event in question, and then checking whether those are the parent <li> element.
All up, your code would look like this:
// declare variable for the CSS class
var menuItem = document.querySelectorAll('.menu-item');
// loop through CSS class to change background to red
function myMouseEnter() {
this.style.background = "red";
}
// loop through CSS class to change remove red background
function myMouseLeave() {
// prevent the 'mouseout' from affecting the <a> children
var e = event.toElement || event.relatedTarget;
if (e.parentNode == this || e == this) {
return;
}
this.style.background = "none";
}
// event handler to add function on mouseenter
for (j = 0; j < menuItem.length; j++) {
menuItem[j].addEventListener('mouseenter', myMouseEnter, false);
}
// event handler to add function on mouseout
for (k = 0; k < menuItem.length; k++) {
menuItem[k].addEventListener('mouseout', myMouseLeave, false);
}
.menu-item {
padding: 10px;
font-family: arial;
}
<ul class="unclick--menuitems">
<li class="menu-item">About</li>
<li class="menu-item">Projects</li>
<li class="menu-item">Contact</li>
</ul>
Note that the functions themselves don't have to loop through the menu items again ;)
Hope this helps! :)
I have a page full of links and they're paired. What I would like to do is once I've clicked a question mark (for help) the first 2 pairs are selected, then the next 2 and so on. The problem is that the links are created randomly on the page. I have the following code which selects the first link and its pair.
$(".main .container a:first").css("color", "#0c0");
var valid = $(".main .container a:first").attr("class").split(" ");
var links = $(".main .container a");
for (i = 0; i < links.length; i ++) {
var attributes = $(links[i]).attr("class").split(" ");
if (attributes[1] == valid[1]) {
$(links[i]).eq(0).css("color", "#0c0");
}
}
EDIT:
$(".help a").on("click", function()
{
var unchecked = $(".main .container a:not(.selected)");
var valid = unchecked.eq(0).attr("class").split(" ");
var links = $(".main .container a");
unchecked.eq(0).addClass("selected");
for (i = 0; i < links.length; i ++) {
var attributes = $(links[i]).attr("class").split(" ");
if (attributes[1] == valid[1]) {
$(links[i]).eq(0).addClass("selected");
}
}
});
Looks like you can simply manage that by adding a CSS class to the elements that were already "selected".
Check this simple test I did at JSFiddle: http://jsfiddle.net/L4rUM/1/
// When you click the "?"
$('button#btnHelp').on('click', function(){
// Gathers the list of ALL <a> elements that were not "selected" yet
var uncheckeds = $('.main .container > a:not(.selected)');
// If you have at least 2 available elements
if(uncheckeds.size() > 1){
// Adds the .selected CSS class to first 2 non-selected elements
uncheckeds.eq(0).addClass('selected');
uncheckeds.eq(1).addClass('selected');
}
});
And the CSS manipulation you are doing is now controlled by just adding the CSS class:
.selected { color: #0c0; }
I hope this helps and solve your problem :)
I've got this code:
<script type="text/javascript">
$(document).ready(function () {
$('.thumbspiccolimabelli').hover( function(e){
var ider = $(this).attr('title'); // e.g. the other element I want to change colour on
console.log(ider);
var test = document.getElementsByClassName(ider);
for(var i = 0; i < test.length; i++) {
if(test[i].style.color = 'red'){
test[i].style.color = 'white';
}
else{
test[i].style.color = 'red';
}
}
console.log(test);
});
});
</script>
And i'm trying to change the colour of all element on the page that have the id of the element i'm hovering over, but it does'nt quite work.
The element im hovering over has a ID of "myhoverelement" and I have span elements that share the same ID, these ones I want the colour to change on.
Thanks
You dont need javascript for this
CSS:
.thumbspiccolimabelli {
background-color: none;
}
.thumbspiccolimabelli:hover {
background-color: #fff;
}
Is this what you want?
'#myhoverelement' is being replaced with '.myhoverelement'. IDs must be unique.
$('.thumbspiccolimabelli').on('hover' , function() {
$('.myhoverelement').each(function() {
$(this).css('background' , '#ffffff');
});
});