Title, my only problem is that when I've created all elements on my page, and clicked all of them, my page looks like a chess board.
I can only "toggle" the background color of half too. So it's not only that they don't change color on the first click, they don't change at all.
This is my Javascript:
for (var i = 0; i < 10; i++) {
var itemContainer = document.createElement("div" + i);
itemContainer.id = "div" + i;
itemContainer.className = "item";
itemContainer.innerHTML = "Hello!";
for (let i = 0; i < 10; i++) {
$('div' + i).click(function() {
if (this.className == "item") {
this.className = "itemselected";
} else {
this.className = "item";
}
});
}
document.getElementById("page").appendChild(itemContainer);
}
I made a JSFiddle for you who want it.
I've seen a few other questions about how to toggle the color of backgrounds, but none of them have the same problem as me.
You inserted your second loop into the first one, every second i got skipped. And probably was able to change your divs up to i=18
JSFiddle
for (var i = 0; i < 10; i++) {
var itemContainer = document.createElement("div" + i);
itemContainer.id = "div" + i;
itemContainer.className = "item";
itemContainer.innerHTML = "Hello!";
document.getElementById("page").appendChild(itemContainer);
}
for (let i = 0; i < 10; i++) {
$('div' + i).click(function() {
if (this.className == "item") {
this.className = "itemselected";
} else {
this.className = "item";
}
});
}
Edit: You could simply put the content of your second loop into the first loop, to simplify your code a bit.
You don't need 2 loops try that
for (var i = 0; i < 10; i++) {
var itemContainer = document.createElement("div");
itemContainer.id = "div" + i;
itemContainer.className = "item";
itemContainer.innerHTML = "Hello!";
document.getElementById("page").appendChild(itemContainer);
$('#div' + i).click(function() {
alert("here");
if (this.className == "item") {
this.className = "itemselected";
} else {
this.className = "item";
}
});
}
fiddle example
You were close, missing "#" of id element
$('div' + i).click(function() {
$('#div' + i).click(function() {
and you have inserted the second loop inside first one
https://jsfiddle.net/snbtchph/
Your selector at line 8 of your JavaScript is missing the # so the jQuery is looking for <div0>, <div1>, <div2>..., and, your line 2 of JavaScript is var itemContainer = document.createElement("div" + i); which actual creating elements div0, div1....
And since you are using jQuery , I have also revised some code to use it instead of native JavaScript: https://jsfiddle.net/xfr496p6/5/
I have also added css .item { display: inline-block; } to makes the elements placed in a row.
There are a few problems with your code:
var itemContainer = document.createElement("div" + i);
Creating non-existant elements like <div1> is impossible, remove the iterator.
for (let i = 0; i < 10; i++) {
jQuery's .click() doesn't need a for loop, but adds the event listener to every case, this is not needed.
document.getElementById("page").appendChild(itemContainer);
Apply this directly in after the .innerHTML
In addition, you seem to randomly use ES6, jQuery, and VanillaJS through your entire codebase, I'd like to advise you to be consistant with how you write your applications.
I've updated your fiddle with the working changes.
https://jsfiddle.net/xfr496p6/8/
Updated javascript:
for (var i = 0; i < 10; i++) {
var itemContainer = document.createElement("div");
itemContainer.id = "div" + i;
itemContainer.className = "item";
itemContainer.innerHTML = "Hello!" + i;
document.getElementById("page").appendChild(itemContainer);
}
$('div').click(function() {
if (this.className == "item") {
this.className = "itemselected";
} else {
this.className = "item";
}
});
Why do you have 2 nested loops?
try this
for (var i = 0; i < 10; i++) {
var itemContainer = document.createElement("div" + i);
itemContainer.id = "div" + i;
itemContainer.className = "item";
itemContainer.innerHTML = "Hello!";
document.getElementById("page").appendChild(itemContainer);
}
for (let i = 0; i < 10; i++) {
$('div' + i).click(function() {
if (this.className == "item") {
this.className = "itemselected";
} else {
this.className = "item";
}
});
}
JSFIDDLE
for (var i = 0; i < 10; i++) {
var itemContainer = document.createElement("div" + i);
itemContainer.id = "div" + i;
itemContainer.className = "item";
itemContainer.innerHTML = "Hello!";
$(itemContainer).click(function() {
if (this.className == "item") {
this.className = "itemselected";
} else {
this.className = "item";
}
});
document.getElementById("page").appendChild(itemContainer);
}
Related
I have some javascript that I want to convert to jQuery...
How do we change javascript to jquery code?
Do we just change the document.getElementById > $?
Do we change document.querySelectorAll > $ too?
Does the function portion also need to be tweak?
Kindly see my code apprehend below:
// Home Page Gallery
let i = 0; // current slide
let j = 5; // total slides
const dots = document.querySelectorAll(".dot-container button");
const images = document.querySelectorAll(".image-container img");
function next() {
document.getElementById("content" + (i + 1)).classList.remove("active");
i = (j + i + 1) % j;
document.getElementById("content" + (i + 1)).classList.add("active");
indicator(i + 1);
}
function prev() {
document.getElementById("content" + (i + 1)).classList.remove("active");
i = (j + i - 1) % j;
document.getElementById("content" + (i + 1)).classList.add("active");
indicator(i + 1);
}
function indicator(num) {
dots.forEach(function (dot) {
dot.style.backgroundColor = "transparent";
});
document.querySelector(".dot-container button:nth-child(" + num + ")").style.backgroundColor = "#107e31";
}
function dot(index) {
images.forEach(function (image) {
image.classList.remove("active");
});
document.getElementById("content" + index).classList.add("active");
i = index - 1;
indicator(index);
}
// FAQ JS
let toggles = document.getElementsByClassName('toggle');
let contentDiv = document.getElementsByClassName('content');
let icons = document.getElementsByClassName('icon');
for(let i=0; i<toggles.length; i++){
toggles[i].addEventListener('click', ()=>{
if( parseInt(contentDiv[i].style.height) != contentDiv[i].scrollHeight){
contentDiv[i].style.height = contentDiv[i].scrollHeight + "px";
toggles[i].style.color = "#0084e9";
icons[i].classList.remove('fa-plus');
icons[i].classList.add('fa-minus');
}
else{
contentDiv[i].style.height = "0px";
toggles[i].style.color = "#111130";
icons[i].classList.remove('fa-minus');
icons[i].classList.add('fa-plus');
}
for(let j=0; j<contentDiv.length; j++){
if(j!==i){
contentDiv[j].style.height = "0px";
toggles[j].style.color = "#111130";
icons[j].classList.remove('fa-minus');
icons[j].classList.add('fa-plus');
}
}
});
}
When using $() with selectors, it's very similar to document.querySelectorAll().
So, if you wanted to query for a specific ID, you'd need to use a pound symbol # in front of the ID:
$('#some-id')
Really though, there's no reason I can think of these days to use jQuery. Additionally, you could probably remove the need for any of this JavaScript by simply using anchor fragments/hash and the :target selector. Your URLs could be like somepage.html#slide-1.
This question already has an answer here:
Basic questions about javascript
(1 answer)
Closed 5 years ago.
I am working on a script that would generate random list of 100 elements where every third element would be clickable. So far I am stuck at stage below. Any ideas how to progress?
var hundred = Array(100);
hundred.toString();
for (i = 0; i < hundred.length; i++) {
document.write("Item " + (i + 1) + " of" + hundred.length + "</br>")
}
I used buttons. every third element will be clickable. remaining elements will have disabled property
var hundred = Array(100);
hundred.toString();
for (i = 0; i < hundred.length; i++) {
if(i%3===0 && i!==0){
var button = document.createElement("button");
button.innerHTML ="Click "+i ;
document.getElementsByTagName('body')[0].appendChild(button);
}else{
var button = document.createElement("button");
button.innerHTML ="Click "+i ;
button.disabled = true;
document.getElementsByTagName('body')[0].appendChild(button);
}
}
Edited: full example
var hundred = Array(100);
var node;
hundred.toString();
for (i = 0; i < hundred.length; i++) {
if(i%3===0 && i!==0){
node = document.createElement("button");
node.addEventListener('click', function() { alert('clicked'); });
node.innerHTML = 'clickablke';
} else {
node = document.createElement("div");
node.innerHTML = 'just div';
}
document.body.appendChild(node);
}
First you need create the element. Then apply the onclick with this consition i%3 == 0 to every 3 rd element
Updated
after click its a bolder using classList.add()
for (i = 1; i < 10; i++) {
var s = document.createElement('SPAN');
if (i % 3 == 0) {
s.className = 'clickable';
s.onclick = clicks;
}
s.textContent=i;
document.body.appendChild(s)
}
function clicks() {
console.log(this.innerHTML)
this.classList.add('bold')
}
.clickable {
color: red;
}
.bold{
font-weight:bolder;
}
As commented,
Instead of using document.write, use document.createElement to create an element and assign them event listener and append these elements to an element in html or document.body
var hundred = Array(100);
for (i = 0; i < hundred.length; i++) {
let el = document.createElement('span');
el.textContent = i + " ";
if((i+1) % 3 === 0){
el.classList.add('clickable')
el.addEventListener("click", notify)
}
document.body.appendChild(el)
}
function notify(){
this.classList.add('clicked')
console.log(this.textContent)
}
.clickable{
color: blue;
text-decoration: underline;
}
.clicked{
color: gray;
}
References
Why is document.write considered a "bad practice"?
Document.createElement
add onclick event to newly added element in javascript
Multiple wayst to do this, i'd make an event listener to every item reference, hence: every third clickable element goes bold:
var hundred = Array(100);
hundred.toString();
var btn = Array(100);
for (i = 0; i < hundred.length+1; i++) {
btn = document.createElement("p");
btn.innerHTML="Item " + (i-1 + 1) + " of" + hundred.length + "</br>";
if(i%3===0 && i!==0){
btn.addEventListener('click', function() {
this.style.fontWeight = 'bold'; }, false);
}
document.body.appendChild(btn);
}
I have the following piece of code I am working on. My purpose is to be able to grab information about different users from a specific website, display the name and other info and then have a button that when clicked, prints more information. I am able to get the information and display the name and picture, but when I click the button the information is displayed at the top of the page, not under the specific button that was clicked. I want for the information to be display under each user... I am new to Javascript and learning on my own, any help is appreciated!
function getUsers(user) {
var out = "";
var i;
for (i = 0; i < user.length; i++) {
out += '' + user[i].login + '<br>'+'</br> <img src="'+user[i].avatar_url+
'" alt="Image" style="width:304px;height:228px"</br></br>'+
'<button onclick=printRepos("'+user[i].repos_url+'")>Repositories</button></br>'+'<div id="id"></div>';
}
document.getElementById("id01").innerHTML = out;
}
Printing Function
function printF(array) {
var out = "";
var i;
for (i = 0; i < array.length; i++) {
out += array[i].id+'</br>';
}
document.getElementById("id").innerHTML = out;
}
This works fine. I just made div with dynamic ids and passed it to the function
function getUsers(user) {
var out = "";
var i;
for (i = 0; i < user.length; i++) {
out += '' + user[i].login + ' <br>'+'</br> <img src="'+user[i].avatar_url+
'" alt="Image" style="width:304px;height:228px"</br></br>'+
'<button onclick=printRepos("'+user[i].repos_url+'","'+i+'")>Repositories</button></br>'+'<div id="'+ 'id' + i +'"></div>';
}
document.getElementById("id01").innerHTML = out;
}
function printRepos(array, id) {
var out = "";
var i;
for (i = 0; i < array.length; i++) {
out += array[i].id+'</br>';
}
console.log('id' + id);
document.getElementById('id' + id).innerHTML = out;
}
Add the "this" keyword as a parameter to your onclicks, to pass in the button that was clicked:
<button onclick=printRepos(this,"'+user[i].repos_url+'")>Repositories</button>
Then locate the next div after that button in your event handler:
function printF(btn, array) {
var out = "";
var i;
for (i = 0; i < array.length; i++) {
out += array[i].id+'</br>';
}
// find the div
var d = btn; // start with the button
while (d.tagName != "DIV") d = d.nextSibling; // look for the next div
d.innerHTML = out;
}
This simple code allows me to display a list of items in an array, and to delete a chosen item from the array, and finally display a new list without the deleted item.
var carBrands = ["Toyota", "Honda", "BMW", "Lexus", "Mercedes","Peugeot","Aston Martin","Rolls Royce"];
var html="";
var newList="";
var itemToRemove;
$(document).ready (function () {
console.log("Ready to go!");
$("#displayList").bind('click', function(event) {
displayList();
});
$("#removeItem").bind('click', function(event) {
item = document.getElementById("input").value;
removeItemFromList(item);
});
});
function displayList() {
for (var i = 0; i < carBrands.length; i++) {
html+= "<li>" + carBrands[i] + "</li>";
document.getElementById("list").innerHTML=html;
}
}
function removeItemFromList(item) {
itemToRemove = item;
for (var i=0; i<carBrands.length; i++) {
if (itemToRemove == carBrands[i]) {
carBrands.splice(carBrands[i], 1);
}
newList+= "<li>" + carBrands[i] + "</li>";
document.getElementById("newList").innerHTML=newList;
}
}
This works fine on the first try,
but if i try again the new list is appended to the old list and the item i removed initially is also added to it.
My Question:
How do i display the list without the removed items?
Are html and newList objects?
First, splice() doesn't want the thing you're removing, it wants the index of the thing.
So, instead of:
carBrands.splice(carBrands[i], 1);
you want:
carBrands.splice(i, 1);
And you're never emptying newList after deleting the last item, so you're just re-adding everything to the list.
Try this instead:
function removeItemFromList(item) {
itemToRemove = item;
for (var i=0; i < carBrands.length; i++) {
if (item == carBrands[i]) {
carBrands.splice(i, 1);
break;
}
}
newList = "<li>" + carBrands.join('</li><li>') + "</li>";
document.getElementById("newList").innerHTML = newList;
}
Also, you'll notice that itemToRemove was never needed in the loop; if you're not using it elsewhere, it can just go away.
Your problem has to do with variable scope: the html and newList variables retained their values each time the functions were run (aka: each time the buttons were pressed).
You also had a severe performance issue. When looping, you don't want to update the DOM on each iteration, and you want to update the DOM as few times as is necessary.
Don't do:
var html = "";
function displayList() {
html = "";
for (var i = 0; i < carBrands.length; i++) {
html += "<li>" + carBrands[i] + "</li>";
document.getElementById("list").innerHTML = html;
}
}
Do:
function displayList() {
var html = "";
for (var i = 0; i < carBrands.length; i++) {
html += "<li>" + carBrands[i] + "</li>";
}
document.getElementById("list").innerHTML = html;
}
Here is my jsfiddle of the solution: http://jsfiddle.net/netinept/jmm93fy1/
And the complete resulting JavaScript (including Paul Roub's join solution for constructing the final list):
var carBrands = ["Toyota", "Honda", "BMW", "Lexus", "Mercedes", "Peugeot", "Aston Martin", "Rolls Royce"];
var itemToRemove;
$(document).ready(function () {
console.log("Ready to go!");
$("#displayList").bind('click', function (event) {
displayList();
});
$("#removeItem").bind('click', function (event) {
item = document.getElementById("input").value;
removeItemFromList(item);
});
});
function displayList() {
var html = "";
for (var i = 0; i < carBrands.length; i++) {
html += "<li>" + carBrands[i] + "</li>";
}
document.getElementById("list").innerHTML = html;
}
function removeItemFromList(item) {
itemToRemove = item;
for (var i = 0; i < carBrands.length; i++) {
if (itemToRemove == carBrands[i]) {
carBrands.splice(i, 1);
break;
}
}
var newList = "<li>" + carBrands.join('</li><li>') + "</li>";
document.getElementById("newList").innerHTML = newList;
}
Please Look at the following code only the last image moves.
http://jsfiddle.net/u8Bg3/
But second one works
http://jsfiddle.net/u8Bg3/1/
As pointed by the Er144 even this works with jquery
http://jsfiddle.net/u8Bg3/14/
I also found out appendchild works but not innerhtml
The difference between two is that in first one html exits in second one it's dynamically created
HTML
<body>
<div class="racetrack" id="racetrack"></div>
<div id="track-tmpl" class="hide">
<div class="track"><div id="player{{ x }}" class="runner"></div></div>
</div>
</body>
JS
var position = [0,40,80,120,80],
racetrack = document.getElementById('racetrack');
track_tmpl = document.getElementById('track-tmpl').innerHTML;
function Players(ele, ptimeout)
{
this.el = ele;
this.i = 0;
this.iterations = 0;
this.stop = 0;
this.timeout = ptimeout;
this.position = 0;
this.animate = function(){
if(this.i !== 0){
this.move((this.position + 5), this.i);
}
if(!this.stop){
if(this.i < 5){
setTimeout(function(_this){
_this.i++;
_this.animate();
},this.timeout,this);
}
if(this.i==5){
this.iterations ++;
if(this.iterations < 50){
this.i = 0;
this.animate();
}
else{
this.el.style.backgroundPosition = '120px 0px';
}
}
}
};
this.start = function(){
this.stop = 0;
this.animate();
};
this.move = function(to,positionIndex){
this.position = to;
this.el.style.backgroundPosition = '-'+position[positionIndex]+'px 0px';
this.el.style.webkitTransform = 'translate('+to+'px)';
this.el.style.mozTransform = 'translate('+to+'px)';
}
}
function Game(noOfPlayers){
this.noOfPlayers = noOfPlayers;
this.players = new Array();
for (var i = 0; i < this.noOfPlayers ; i++){
racetrack.innerHTML = racetrack.innerHTML + track_tmpl.replace('{{ x }}', i);
this.players.push(new Players(document.getElementById('player' + i), (120 + i)));
/* issue here with dynamic added content*/
}
this.start = function(){
for (var i = 0; i < this.noOfPlayers; i++){
this.players[i].start();
}
};
}
var game = new Game(3);
game.start();
Why is that in dynamically added html only the last one moves
The issue is with creating the player(n) object inside the for loop along with the assignments to innerHTML using `+='. The modified fiddle: http://jsfiddle.net/u8Bg3/15/ works fine. Cheers for a good question!
var finalized_tracks= "" ;
for (var i = 0; i < this.noOfPlayers ; i++){
finalized_tracks += track_tmpl.replace('{{ x }}', i);
}
racetrack.innerHTML = racetrack.innerHTML + finalized_tracks;
for (var i = 0; i < this.noOfPlayers ; i++){
this.players.push(new Players(document.getElementById('player'+ i),(120+i)));
}
If you use the jquery:
var element = track_tmpl.replace('{{ x }}', i);
$(racetrack).append(element);
instead of the line where you change the innerHtml of racetrack div, all elements are moving.
However, I'm not sure, why...
theCoder has pretty much nailed the issue with your code there.
Just as an additional thought, you could manually build the necessary divs using javascript instead, it's more long winded however...
for (var i = 0; i < this.noOfPlayers ; i++){
var newTrack = document.createElement("div");
newTrack.id = "track"+i;
newTrack.className = "track";
var newPlayer = document.createElement("div");
newPlayer.id = "player"+i;
newPlayer.className = "runner";
newTrack.appendChild(newPlayer);
racetrack.appendChild(newTrack);
this.players.push(new Players(document.getElementById('player' + i), (120 + i)));
}