Im running a function that create img elements. I only want it to create the element if and identical element doesnt already exists. There are 2 copies of 6 diffrent cards in the cardArray, and right now the function create copies of previously found cards.
Is there any easy way to do this?
function wonCards() {
for (let j = 0; j < cardsWonMerged.length; j++) {
for (let i = 0; i < cardArray.length; i++) {
if (cardsWonMerged[j] == cardArray[i].name) {
const card = document.createElement('img')
card.setAttribute('src', cardArray[i].img)
card.setAttribute('dataTwo-id', i)
card.setAttribute('name-id', cardArray[i].name)
gridTwo.append(card)
}
}
}
}
Related
So... I'm making a page that has notifications, a mark as read button and a mark all as read button, when i try to activate the mark all as read using my loop
let markAllAsRead = () => {
let buttons = document.getElementsByClassName("markAsRead");
let notifications = document.getElementsByClassName("notification");
let newValue = Number(counter.innerText) - 7;
if (newValue < 0) {
newValue = 0;
}
console.log(buttons);
counter.innerText = newValue;
for (let i = 0; i < notifications.length; i++) {
notifications[i].classList.remove("new");
}
for (let i = 0; i < buttons.length; i++) {
buttons[i].remove(buttons[i]);
}
};
it only will eliminate one element yes and other no like so:
live test of the function
I'm back just to update this one, the problem it self was
for (let i = 0; i < buttons.length; i++) {
buttons[i].remove(buttons[i]);
}
instead of make it look for a "default loop" I made "i" be equal to the HTMLCollection lenght, then i>= 0; --i
for (let i = buttons.length - 1; i >= 0; --i) {
buttons[i].remove();
}
making it, the function works as it should removing all the buttons of mark as read.
So I'm just beginning to code and have learnt only basic codes and I have created arrays dynamically with:
for (var j=0; j<20; j++) {
this["row"+j] = [];
for (var i=0; i<10; i++) {
["row"+j].push("false");
}
}
but now I want to make it so that I can push items into the previously created row1[], row2[], etc... so that it could be like row1[false, false...] and row2[false, false...] Is there a way to do that?
It is not clear what this is referring here. Rather I will suggest to create an object and in that object keys will be ["row" + j], the value of which will be an [] and then inside the nested loop push value to that array
let obj = {};
for (var j = 0; j < 20; j++) {
obj["row" + j] = [];
for (var i = 0; i < 10; i++) {
obj["row" + j].push("false");
}
}
console.log(obj)
If you want to create arrays not inside object but like normal arrays you can use window and then variable name to create variable.
Normally when you declared varibale in will be inside window object(you can access it without writing window.{variable name}). So you can take advantage of window to created dynamic variable.
for (var j = 0; j < 20; j++) {
window["row" + j] = []; //<-----use window to create dynamic array
for (var i = 0; i < 10; i++) {
window["row" + j].push("false");
}
}
row1[0] = "true"; // editing content of array
console.log(row1,row2);
In the above we have created 20 variable name row0,row1,.... and you can directly access it like normal arrays.
This question already has answers here:
$.each() vs for() loop - and performance
(6 answers)
Closed 5 years ago.
I want to replace my
$("p").each(function(i)
with
for (var i = 0, len = $('p').length; i < len; i++) {
$('p')[i];
}
for faster performance. I want to keep the same switch statement. How do i do it? I'm new with javascript and also my switch statement is alot longer , but i shorten it so you guys can see it better. My problem is $(this) . Thanks in advance.
for (var i = 0, len = $("p").length; i < len; i++) {
$("p")[i];
}
$("p").each(function(i) {
switch(window.localStorage['kgenfavred' + i])
{
case 'yred':
$(this).addClass("favoritesred");
$(this).removeClass("favoritesyellow");
break;
}
});
var paragraphs = document.getElementsByTagName('p');
for (var p = 0; p < paragraphs.length; p++) {
switch(window.localStorage['kgenfavred' + p]) {
case 'yred':
paragraphs[p].classList.add('favoritesred');
paragraphs[p].classList.remove('favoritesyellow');
break;
}
}
JSFiddle example
Your current approach is likely to be slower, since you've added a DOM lookup on each iteration. If you really want to convert to a for loop, capture your element set first, then iterate over it - accessing the current element with .eq(index):
var $p = $('p');
for (var i = 0, len = $p.length; i < len; i++) {
// get jquery element
console.log($p.eq(i));
// or get DOM node
console.log($p.get(i));
}
As #Kinduser pointed out, it probably would be fastest/easiest just to cut jQuery out of the picture altogether:
var p = document.querySelectorAll('p');
for (var i = 0; i < p.length; i++) {
console.log(p[i]);
}
Or newer:
document.querySelectorAll('p').forEach((element) => {
console.log(element);
});
This would be incorrect. You can use .each() method of jQuery:
var $ps = $(document).find('p');
for (var i=0; i<$ps.length; i++)
{
let temp = $ps[i]; /// this is a dom element and if you want use jQuery methods, you need to use a selector over it;
let $temp = $(temp); /// this is jQuery element
/// Do whatever you want here
}
I want to clone some players inside my .shuffler div. Because I attached click-listeners to the .player divs I want to append the entire object instead of just their HTML.
When I loop through the code below I do get the correct result when logging playerClones[j] in the each loop but it doesn't append anything.
Any ideas on how to clone my players and append every player 25 times to my .shuffler. without losing the click listener?
this.amountOfDuplicates = 25;
var playerClones = [];
this.parentObject.find('.player').each(function () {
playerClones.push(jQuery(this).clone());
});
for (var i = 0; i < this.amountOfDuplicates; i++) {
for (var j = 0; j < playerClones.length; j++) {
this.parentObject.find('.shuffler').append(playerClones[j]);
}
}
Fiddle here!
Normally when you use $(this).clone(), everything of the object is cloned except the click listener.
It is better if you could declare a function like this and call it every time u clone the object.
attachClickToClone = function() {
$('.player').on('click', function() {
//to-do-function
}
}
And call it like this.
for (var i = 0; i < this.amountOfDuplicates; i++) {
for (var j = 0; j < playerClones.length; j++) {
this.parentObject.find('.shuffler').append(playerClones[j]);
}
}
attachClickToClone();
I want to remove all elements (suppose they're all divs) whose id name contains the string bs. How to do this via javascript regardless of they are nested elements or not? (not jquery)
<div id="new_bs_add"></div>
<div id="bsremove"></div>
<div id="somethingelse"></div>
... and many more
No jQuery, but if there's support for CSS3 selectors you can go for
var rem = document.querySelectorAll("[id*='bs']"), i = 0;
for (; i < rem.length; i++)
rem[i].parentNode.removeChild(rem[i]);
Otherwise, just go for this slight edit of VisioN's solution:
var divs = document.querySelectorAll("[id]");
for (var i = 0, len = divs.length; i < len; i++) {
var div = divs[i];
if (div.id.indexOf("bs") > -1) {
div.parentNode.removeChild(div);
}
}
Pure JavaScript:
var divs = document.getElementsByTagName("div");
for (var i = divs.length; i;) {
var div = divs[--i];
if (div.id.indexOf("bs") > -1) {
div.parentNode.removeChild(div);
}
}
As an example, in jQuery it is one line:
$("div[id*='bs']").remove();
DEMO: http://jsfiddle.net/c4ewU/
The most portable method to obtain a list of elements is document.getElementsByTagName. However the resulting list is a live node list which means that if you modify the document, the list changes too!
There are two solutions for this. One is to take a copy of the list:
var nodes = document.getElementsByTagName('div');
var copy = [].slice.call(nodes, 0); // take a copy
for (var i = 0, n = copy.length; i < n; ++i) {
var d = copy[i];
if (d.parentNode && d.id.indexOf('bs') >= 0) {
d.parentNode.removeChild(d);
}
}
The second is to either work through the list backwards, or ensure that you don't advance the iterator if you modify the list. This takes the latter approach:
var nodes = document.getElementsByTagName('div');
for (var i = 0; i < nodes.length; /* blank */ ) {
var d = nodes[i];
if (d.id.indexOf('bs') >= 0) {
d.parentNode.removeChild(d);
} else {
++i; // iterate forward
}
}
try this code
first get all elements contain certain text (here 'bs')
var matches = [];
var searchElements = document.getElementsByTagName("body")[0].children;
for(var i = 0; i < searchElements.length; i++) {
if(searchElements[i].tagName == 'DIV') {
if(searchElements[i].id.indexOf('bs') != -1) {
matches.push(searchElements[i]);
}
}
}
Then delete them from body of html
for(var i = 0;i<matches.length; i++)
matches[i].parentNode.removeChild(matches[i]);
If you remove them in the first loop, there will be some tags will not deleted as the children array length is decreased each time you delete a node. So the better way to get them all in an external array and then delete them.