I try to toggle class when td clicked in multiple class but it does not work. I prefer working on DOM.
window.onload = function() {
var seats = document.getElementsByClassName('seat');
for(var i = 0; i < seats.length; i++) {
seats[i].onclick = function() {
seats[i].classList.toggle = 'selected';
}
}
}
td {
width: 30px;
height: 30px;
background-color: red;
color: white;}
td.selected {
background-color: black;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td class="seat">1</td>
<td class="seat">2</td>
<td class="seat">3</td>
<td class="seat">4</td>
<td class="seat">5</td>
</tr>
</table>
</body>
</html>
http://jsbin.com/kufemuhagi/edit?html,css,js,output
Problem :
You've a scope problem in the posted code where your variable i counldn't found inside the event handler, this variable is accessible just outside of it, to fix this you need to wrap the assignment of the event listener in a closure, like :
for (var i = 0; i < seats.length; i++) {
(function(i) {
seats[i].onclick = function() {
seats[i].classList.toggle('selected');
}
})(i);
}
window.onload = function() {
var seats = document.getElementsByClassName('seat');
for (var i = 0; i < seats.length; i++) {
(function(i) {
seats[i].onclick = function() {
console.log(i);
seats[i].classList.toggle('selected');
}
})(i);
}
}
td {
width: 30px;
height: 30px;
background-color: red;
color: white;
}
td.selected {
background-color: black;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td class="seat">1</td>
<td class="seat">2</td>
<td class="seat">3</td>
<td class="seat">4</td>
<td class="seat">5</td>
</tr>
</table>
</body>
</html>
My suggestion :
Separate you logic and use addEventListener() to attach the events, then use this to toggle your class, like the sample below shows.
window.onload = function() {
var seats = document.getElementsByClassName('seat');
var clickHandler = function() {
this.classList.toggle('selected');
};
for (var i = 0; i < seats.length; i++) {
seats[i].addEventListener('click', clickHandler, false);
}
}
div.selected {
background-color: green;
}
<div class="seat">Div 1</div>
<div class="seat">Div 2</div>
<div class="seat">Div 3</div>
<div class="seat">Div 4</div>
The Problem with your code is that the variable i isn't defined per iteration it is defined in the function scope. That means that the for loop you have goes trough every element and assigns the onclick handler to each "seat" but after the last iteration the i variable will be set to an out-of-bounds index since the for loop does the i++ expression after each iteration. The problem is your onclick handler refers to the i variable, which is set to an out-of-bounds index, so that the seats[i] expression returns an undefined value. You can fix this by using the this statement inside the onclick handler or by using the first argument which is the click event. The click event contains a target which refers to the clicked EventTarget (this should be your "seat" element).
function handleSeatClick(ev) {
var seat = ev.target;
if(seat.classList.contains('selected')){
seat.classList.remove('selected');
} else {
seat.classList.add('selected');
}
}
window.onload = function() {
var seats = document.getElementsByClassName('seat');
for(var i = 0; i < seats.length; i++) {
seats[i].addEventListener('click', handleSeatClick);
}
}
td {
width: 30px;
height: 30px;
background-color: red;
color: white;}
td.selected {
background-color: black;}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td class="seat">1</td>
<td class="seat">2</td>
<td class="seat">3</td>
<td class="seat">4</td>
<td class="seat">5</td>
</tr>
</table>
</body>
</html>
Hope this will help.
window.onload = function() {
var seats = document.getElementsByClassName('seat');
for(var i = 0; i < seats.length; i++) {
seats[i].onclick = function() {
this.classList.toggle('selected'); //this will refer current object here and toggle is function
}
}
}
td {
width: 30px;
height: 30px;
background-color: red;
color: white;}
td.selected {
background-color: black;}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td class="seat">1</td>
<td class="seat">2</td>
<td class="seat">3</td>
<td class="seat">4</td>
<td class="seat">5</td>
</tr>
</table>
</body>
</html>
Related
I have create this html page and I want to put 2 or 3 background images on that(from links).I want in 5 seconds,autoplay to change auto those background images.How can I do it?I searched but nothing was helpful.Can it happen something like that?
<head>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Untitled 1</title>
<style>
body {
background-color: green;
}
IMG {width:5cm; height:5cm;text-align:center;}
TD {border: 1px solid black;}
table {border: 1px solid black;}
</style>
<script>
function the_click(event,table) {
var img = event.target;
var other_table;
if(img.tagName!='IMG') {return;}
if(table.id=='thetable1') {
other_table=document.getElementById('thetable2');
} else {
other_table=document.getElementById('thetable1');
}
var t=img.outerHTML;
other_table.rows[0].innerHTML += '<td>'+t+'</td>';
img.parentNode.outerHTML='';
}
</script>
</head>
<body >
<table id='thetable1' onclick='the_click(event,this)'>
<tr><td><img src='http://www.gettyimages.co.uk/gi-resources/images/Embed/new/embed2.jpg'>
</td><td>
<img src='https://cdn.pixabay.com/photo/2017/01/06/19/15/soap-bubble-1958650_960_720.jpg'>
</td><td>
<img src='https://cdn.pixabay.com/photo/2015/06/21/22/46/soap-bubbles-817098_960_720.jpg'>
</td><td>
<img src='https://thumb7.shutterstock.com/display_pic_with_logo/2655445/223473784/stock-vector-bubbles-background-223473784.jpg'>
</td></tr>
</table>
<table id='thetable2' onclick='the_click(event,this)'>
<tr></tr>
</table>
</body>
</html>
You can create list image
var items = [
'http://www.gettyimages.co.uk/gi-resources/images/Embed/new/embed2.jpg',
'https://cdn.pixabay.com/photo/2017/01/06/19/15/soap-bubble-1958650_960_720.jpg',
'https://thumb7.shutterstock.com/display_pic_with_logo/2655445/223473784/stock-vector-bubbles-background-223473784.jpg'
];
Get random item in list as var img = items[Math.floor(Math.random() * items.length)];
And use setInterval as
setInterval(function(){
[...document.getElementsByTagName("img")].reduce((acc, item)=>{
var img = items[Math.floor(Math.random() * items.length)];
item.src = img;
})
}, 5000);
var items = [
'http://www.gettyimages.co.uk/gi-resources/images/Embed/new/embed2.jpg',
'https://cdn.pixabay.com/photo/2017/01/06/19/15/soap-bubble-1958650_960_720.jpg',
'https://thumb7.shutterstock.com/display_pic_with_logo/2655445/223473784/stock-vector-bubbles-background-223473784.jpg'
];
function the_click(event,table) {
var img = event.target;
var other_table;
if(img.tagName!='IMG') {return;}
if(table.id=='thetable1') {
other_table=document.getElementById('thetable2');
} else {
other_table=document.getElementById('thetable1');
}
var t=img.outerHTML;
other_table.rows[0].innerHTML += '<td>'+t+'</td>';
img.parentNode.outerHTML='';
}
setInterval(function(){
[...document.getElementsByTagName("img")].reduce((acc, item)=>{
var img = items[Math.floor(Math.random() * items.length)];
item.src = img;
})
}, 5000);
<head>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Untitled 1</title>
<style>
body {
background-color: green;
}
IMG {width:5cm; height:5cm;text-align:center;}
TD {border: 1px solid black;}
table {border: 1px solid black;}
</style>
<script>
</script>
</head>
<body >
<table id='thetable1' onclick='the_click(event,this)'>
<tr><td><img src='http://www.gettyimages.co.uk/gi-resources/images/Embed/new/embed2.jpg'>
</td><td>
<img src='https://cdn.pixabay.com/photo/2017/01/06/19/15/soap-bubble-1958650_960_720.jpg'>
</td><td>
<img src='https://cdn.pixabay.com/photo/2015/06/21/22/46/soap-bubbles-817098_960_720.jpg'>
</td><td>
<img src='https://thumb7.shutterstock.com/display_pic_with_logo/2655445/223473784/stock-vector-bubbles-background-223473784.jpg'>
</td></tr>
</table>
<table id='thetable2' onclick='the_click(event,this)'>
<tr></tr>
</table>
</body>
</html>
I am trying to change button A background color to color 1 when clicked, and at the same time set button B color to color 2.
Same thing for when clicking button B.
The surprising thing is tow blocks code are totally symmetry, but one block work but another one block does not work.
How could it be?
In my main_js:
"function switchVisible_dgc() {
......
var color = '#3e8e41';
$("#dgc_click").css('background-color', color);
color='#325CA8';
$("#agc_click").css('background-color', color);
}
function switchVisible_agc() {
......
var color = '#3e8e41';
$("#agc_click").css('background-color', color);
color='#325CA8';
$("#dgc_click").css('background-color', color);
}
in my html:
<td width="0">
</td>
<td width="250">
<button class="button button5"
onclick="switchVisible_agc()"id="agc_click">Agc</button>
</td>
</td>
<td width="250">
<button class="button button5"
onclick="switchVisible_dgc()"id="dgc_click">Dgc</button>
</td>
</table>`
It might be something like this. You might include jQuery if you want.
It would be better to use CSS classes & dynamically assign them instead of modifying style attribute of elements directly.
Variables in this script are global because some outer closure assumed.
const buttons = document.querySelectorAll(`.button5`);
const switchColors = colors => {
buttons.forEach( (element, index) => {
element.style = `background-color: ${colors[index]}`
});
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
</table>
<td width="250">
<button id="agc_click" class="button button5" onclick="switchColors(['red', 'blue'])">Agc</button>
</td>
<td width="250">
<button id="dgc_click" class="button button5" onclick="switchColors(['green', 'yellow'])">Dgc</button>
</td>
</table>
</body>
</html>
UPD: In case if two pre-determined colors should be switched, the code could also be like:
const buttons = document.querySelectorAll(`.button5`);
const colors = [`#325CA8`, `#3E8E41`];
const switchColors = () => {
colors.reverse();
buttons.forEach( (element, index) => {
element.style = `background-color: ${colors[index]}`
});
};
You can do it simply by using addClass() and removeClass().
$('#agc_click').click(function(){
$('#agc_click, #dgc_click').removeClass('b2');
$('#agc_click, #dgc_click').addClass('b1');
});
$('#dgc_click').click(function(){
$('#dgc_click, #agc_click').removeClass('b2');
$('#dgc_click, #agc_click').addClass('b2');
});
html,
body {
height: 100%;
padding: 0;
margin: 0;
}
table {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
.b1 {
background-color: red !important;
}
.b2 {
background-color: blue !important;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<table>
<tr>
<td>
<button class="button button5" id="agc_click">Agc</button>
</td>
<td>
<button class="button button5" id="dgc_click">Dgc</button>
</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
Why the button "proba2" adds row in the table, but the button "Insert", who is in the table - adds row, which disappears at the function end?
My code is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Parameter AutoCgen</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
table,
th,
td {
padding: 10pt;
border-style: solid;
border-width: 1pt;
border-collapse: collapse;
text-align: center;
white-space: nowrap;
margin: auto;
}
table {
width: auto;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
input[type=text] {
background-color: transparent;
border-width: 0px;
}
</style>
<script>
'use strict';
var proba = function() {
for (var r of document.getElementsByTagName('table')[0].rows)
for (var d of r.cells) console.log(d.innerHTML);
}
var ins_after = function(obj) {
obj = obj || window.event;
var r = document.getElementsByTagName('table')[0].insertRow(obj.parentNode.parentNode.rowIndex);
var c1 = r.insertCell(0);
var c2 = r.insertCell(1);
var c3 = r.insertCell(2);
c1.innerHTML = 'drugo_ne6to';
alert(c1);
}
</script>
</head>
<body>
<form>
<table>
<caption style='font-size: 1.5em;'>Parameters list</caption>
<tr>
<th>Insert after</th>
<th>Delete</th>
<th>Parameter name</th>
</tr>
<tr>
<td>
<button onclick="ins_after(this);">Insert</button>
</td>
<td>ne6to</td>
<td>
<input type="text" name="property">
</td>
</tr>
</table>
</form>
<button onclick="proba();">proba1</button>
<button onclick="ins_after(this);">proba2</button>
</body>
</html>
The two buttons have the same one callback function on onclick event.
I try this in Chrome and Mozilla and the result is the same.
When I press "Insert" the new row appears in the table, I use alert to can see this, because after the function end, the row disappears again.
Also when I add several rows with button "proba2" and after that try the button "Insert" - it adds new row, then all new created rows disappears at the callback function end.
Apologize if this is trivial, but I'm new to JS.
It is disappearing because your button is in a form, so it is refreshing the page each time.
Try and add event.preventDefault(); at the end of your function to prevent the default functionality of the button in the form.
Here is a working example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Parameter AutoCgen</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
table, th, td {
padding: 10pt;
border-style: solid;
border-width: 1pt;
border-collapse: collapse;
text-align: center;
white-space: nowrap;
margin: auto;
}
table {
width: auto;
}
tr:nth-child(even) {background-color: #f2f2f2;}
input[type=text] {
background-color: transparent;
border-width: 0px;
}
</style>
<script>
'use strict';
var proba = function () {
for (var r of document.getElementsByTagName('table')[0].rows)
for (var d of r.cells) console.log(d.innerHTML);
}
var ins_after = function (obj) {
obj = obj || window.event;
var r = document.getElementsByTagName('table')[0].insertRow(obj.parentNode.parentNode.rowIndex);
var c1 = r.insertCell(0);
var c2 = r.insertCell(1);
var c3 = r.insertCell(2);
c1.innerHTML = 'drugo_ne6to';
event.preventDefault();
//alert(c1);
}
</script>
</head>
<body>
<form>
<table>
<caption style='font-size: 1.5em;'>Parameters list</caption>
<tr>
<th>Insert after</th>
<th>Delete</th>
<th>Parameter name</th>
</tr>
<tr>
<td>
<button onclick="ins_after(this);">Insert</button>
</td>
<td>ne6to</td>
<td>
<input type="text" name="property">
</td>
</tr>
</table>
</form>
<button onclick="proba();">proba1</button>
<button onclick="ins_after(this);">proba2</button>
</body>
</html>
A button inside a form has by default type="submit" and by clicking on it you will submit the form and reload the page, resetting your table rows (check the accepted answer here Disable form auto submit on button click)
To avoid this kind of behavior add type="button" to your "Insert" button inside the table like this:
<form>
<table>
<caption style='font-size: 1.5em;'>Parameters list</caption>
<tr>
<th>Insert after</th>
<th>Delete</th>
<th>Parameter name</th>
</tr>
<tr>
<td>
<button type="button" onclick="ins_after(this);">Insert</button>
</td>
<td>ne6to</td>
<td>
<input type="text" name="property">
</td>
</tr>
</table>
</form>
I have 4 (or more) DIV elements on which I want to set this behavior:
In the beginning, all DIVs display A
I click on a random DIV. It must display B. Other DIVs must keep displaying A
If the consecutive click is performed on the same DIV, this later one must display back A. Others must keep displaying A.
If the consecutive click is performed on a different DIV, this later one must display B. All other DIVs must display A
This is what I am working on. I have had hard time to do anything useful.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<style>
.divElt {
margin-left: 20%;
width: 80px;
height: 40px;
background-color: blue;
color: white;
font-weight: bold;
text-align: center;
}
</style>
</head>
<body>
<script>
var data = 'B';
function funct() {
var elts = document.getElementsByClassName('divElt')
for(var i = 0; i < elts.length; i++) {
elts[i].innerHTML = data
}
}
</script>
<div class ='divElt' onclick = "funct()"> A
</div>
<br/>
<div class ='divElt' onclick = "funct()"> A
</div>
<br/>
<div class ='divElt' onclick = "funct()"> A
</div>
<br/>
<div class ='divElt' onclick = "funct()"> A
</div>
</body>
</html>
Please help me to resolve this only in JavaScript (no jQuery or other libraries). Thank you a lot in advance.
var letterA = "A";
var letterB = 'B';
//Init with all "A"
var elts = document.getElementsByClassName('divElt');
for (var i = 0; i < elts.length; i++) {
elts[i].innerHTML = letterA;
}
function funct(item) {
for (var i = 0; i < elts.length; i++) {
if (elts[i] !== item)
elts[i].innerHTML = letterA;
else
elts[i].innerHTML = elts[i].innerHTML === letterA ? letterB : letterA;
}
}
.divElt {
margin-left: 20%;
width: 80px;
height: 40px;
background-color: blue;
color: white;
font-weight: bold;
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<script>
</script>
<div class='divElt' onclick="funct(this)">
</div>
<br/>
<div class='divElt' onclick="funct(this)">
</div>
<br/>
<div class='divElt' onclick="funct(this)">
</div>
<br/>
<div class='divElt' onclick="funct(this)">
</div>
</body>
</html>
To uniquely identify the div which was clicked, pass this to the called function like so onclick=func(this)
Then inside your function receive it as a parameter
function func(elem) {
var elts = document.getElementsByClassName('divElt');
for(var i = 0; i < elts.length; i++) {
elts[i].innerHTML = 'A';
}
elem.innerHTML = elem.innerHTML === 'B' ? 'A' : 'B';
}
I have a textarea and a div.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
<script type="text/javascript" src="JSFile.js"></script>
<style type="text/css">
.hidden {visibility: hidden;}
</style>
</head>
<body>
<textarea id="txtArea" onmouseover="mouseMoved();"></textarea>
<div id="hiddenDiv" class="hidden"></div>
</body>
There is onmouseover event associated with the textarea.
function mouseMoved() {
var txtArea = document.getElementById("txtArea");
var hiddenDiv = document.getElementById("hiddenDiv");
var newHtml = "";
var words=txtArea.value.split(" ");
for (i = 0; i < words.length; i++) {
newHtml += '<span>' + words[i] + '</span> ';
}
hiddenDiv.innerHTML=newHtml;
}
Is there any way to place the hiddenDiv in the same layer to the textarea?
What I intended to do is to attach an event with the spans of the div such that when users move mouse over the textarea as well as the div, that event tells, what is the word under the mouse pointer. Hope I represent my problem clearly. If you want to know more, I will provide information.
Thanks and regards.
Edit:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
<script type="text/javascript" src="JSFile.js"></script>
<style type="text/css">
.hidden {
position: relative;
/*visibility: hidden;*/
top: -50px;
left: 5px;
z-index: -1;
}
.txtArea {
position: relative;
}
</style>
</head>
<body>
<textarea id="txtArea" class="txtArea" onmouseover="mouseMovedOnTextBox();"></textarea>
<div id="hiddenDiv" class="hidden"></div>
<label id="lbl"></label>
</body>
And the .js:
function mouseMovedOnTextBox() {
var txtArea = document.getElementById("txtArea");
var hiddenDiv = document.getElementById("hiddenDiv");
var newHtml = "";
var words=txtArea.value.split(" ");
for (i = 0; i < words.length; i++) {
newHtml += '<span onmouseover="mouseMovedOnSpan(\'' + words[i] +'\');">' + words[i] + '</span> ';
}
hiddenDiv.innerHTML=newHtml;
}
function mouseMovedOnSpan(word) {
document.getElementById("lbl").innerHTML=word;
}
I suggest you to not use visibiliy:hidden but display:none, using the last one means that the element will not use space inside the page and you can handle easily your situation.
Good luck