I have some elements with the class "qss". I would like to go through them via a loop and change their text as per an array. It's all working fine, except if there are some qss elements that were added dynamically by JQuery (via .clone), those qss elements aren't picked up by this function. How can I go through all qss elements regardless of whether they are dynamically added?
This is my current code:
i = 0
$('body').find('.qss').each(function(){
$(this).text(big_array[i]);
i++;
});
You have to try using each() like this
$('.qss').each(function(i, obj) {
//you can use this to access the current item
});
where 'i' is the postion in the array and obj is the DOM object that you are iterating (can be accessed through the jQuery wrapper $(this) as well).
There are two possibilities, either with a simple for loop with a better performance, or with the each() function and using the index parameter.
var beforeArray = ['before 01', 'before 02', 'before 03'],
bigArray = ['after 01', 'after 02', 'after 03'];
// create dynamic elements
var beforeArrayLength = beforeArray.length;
for (var i = 0; i < beforeArrayLength; i++) {
$('body').append(
$('<p></p>').addClass('qss').text(beforeArray[i])
);
}
setTimeout(function() {
// first possibility with better performance
// but you have to put it in a function where $qss is always newly set
var $qss = $('body').find('.qss'),
qssLength = $qss.length;
for (var i = 0; i < qssLength; i++) {
$qss[i].innerHTML = bigArray[i];
}
// second possibility
$('body').find('.qss').each(function(index, element) {
$(element).text(bigArray[index]);
});
}, 2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Related
I am trying to loop through and increment the following:
var result_types = document.querySelectorAll('[data-title]')[0].attributes[2].nodeValue
specifically to grab and increment this value:
[0].attributes
Currently, I have the following:
var card = document.querySelectorAll('[data-title]')[0].attributes[2].nodeValue;
for (var i = 0; i < card.length; i++) {
console.log(card[i]);
}
I am trying to get this [0].attributes to increment to [1].attributes etc. when it is clicked
I am not sure what you are asking here, but if the issue is looping through the elements, this is happening because you get a NodeList back from querySelectorAll and not an array. Below will let you loop through node elements.
const nodes = document.querySelectorAll('.nodes');
[].forEach.call(nodes, (singleNode) => {
//Whatever you want.
})
I'm using a div with a <li> element inside where I add some dynamically created elements (localStorage keys to be more specific). I want to update the div every "x" seconds but only the <div>, not the whole page. I know that it can be done with Ajax and JQuery ($( "#here" ).load(window.location.href + " #here" );).
But is there any way to do this whit pure js?
UPDATE
The specific case is that im picking all the localstorage keys and appending them to a list inside a div. When i use like this (window.onload) it works fine. But I want to update it cyclically. If i use a "setinterval" or a button to call the function the previous keys appends repeatedly. (like: file 1.... then: file 1, file 1 file 2 ... then: file 1 file 1 file 2 file 1 file 1 file 1 file 2 file 3)
window.onload = function cargararchivos() {
localstorage = []
var keys = Object.keys(localStorage);
for (let i = 0; i < keys.length; i++) {
var elemento_lista = document.createElement('li')
elemento_lista.innerHTML = keys[i]
var lista = document.getElementById('lista_archivos')
lista.appendChild(elemento_lista)
localstorage[ keys[i] ] = localStorage.getItem( keys[i] )
elemento_lista.onclick = function()
{alert(JSON.parse(localStorage[keys[i]]))}}
};
This can be done using the setInterval function. It executes a function of your choice after a pre-determined amount of time.
To do this your DIV must have an unique ID, so we can access it using Javascript's getElementById() method.
Here's a simple example, which updates a div with the current time every 1000 milliseconds:
function update() {
document.getElementById("myDiv").innerHTML = new Date();
}
var interval = setInterval(update, 1000);
<div id="myDiv">
</div>
The reason your method works the first time, but doesn't work after that is because the method adds DOM nodes. After the second call, you're seeing DOM nodes from both the first call and second call. After the third call, you'd see nodes from the first, second, and third calls... and so on.
If you want to repeatedly call a method like cargararchivos() that adds DOM nodes, you must first remove any DOM elements that have been previously added. I've updated your code, assuming lista_archivos starts empty (no child elements):
function cargararchivos() {
localstorage = []
var keys = Object.keys(localStorage);
var lista = document.getElementById('lista_archivos')
// Ensure any previously added DOM nodes are removed.
while (lista.firstChild) {
lista.removeChild(lista.firstChild);
}
for (let i = 0; i < keys.length; i++) {
var elemento_lista = document.createElement('li')
elemento_lista.innerHTML = keys[i]
lista.appendChild(elemento_lista)
localstorage[ keys[i] ] = localStorage.getItem( keys[i] )
elemento_lista.onclick = function()
{alert(JSON.parse(localStorage[keys[i]]))}
}
};
I would like to make a function which takes a string as input, creates several elements, then appends each element to the element previously created, so that the text is displayed as a list item, within a div, within a span. The intent is to eventually make a basic to do list, but for now I'm stuck on the basic steps
I thought that a for loop could be useful for the creation of elements, though I can't figure out how to append what I have previously appended. Here's how I started:
const elementsArray = [
'ol',
'li',
'div',
'span',
];
const makeToDoItem = (toDoItem) => {
for (i = 0; i < elementsArray.length; i++) {
const createElement =
document.createElement(elementsArray[i]);
document.body.appendChild(createElement);
};
};
makeToDoItem("post on stackoverflow");
I understand that
document.body.appendChild(createElement);
is doing what I am telling it to do: create four elements in the body. How can I append them the way I would like to?
Is the .map function better for this? I am having trouble grasping how to apply .map here.
Thanks for your help!
const elementsArray = [
'ol',
'li'
];
const makeToDoItem = (toDoItem) => {
for (i = 0; i < elementsArray.length; i++) {
const createElement =
document.createElement(elementsArray[i]);
if (elementsArray[i] === 'li') {
createElement.textContent = toDoItem;
}
document.body.appendChild(createElement);
};
};
makeToDoItem("post on stackoverflow");
makeToDoItem("another post");
You can do the above but instead you probably want to create the <ol> in HMTL and then append <li> elements inside it.
I create dynamically a list content:
for (var i = 0; i<length; i++) {
var $li = $('<li />', {
text: ....
}).appendTo($list);
myArray.push($li);
// This doesn't work
$(myArray).click(function (e) { alert('cc'); });
But when I get the parent of the created elements it works
// This works
$('ul.liste').first().find('li').click(function (e) {alert('cc'); });
What's the difference between between $(myArray) and $('ul.liste').first().find('li')?
How to correctly convert a js array to a jquery collection? I thought wrapping the array with $() would work but obviously not.
Instead of pushing, you can use add:
var $set = $();
for (var i = 0; i<length; i++) {
var $li = $('<li />', {
text: ....
}).appendTo($list);
$set = $set.add($li);
}
$set.click(...
If you prefer to build a native array and then convert it to a jQuery collection, then you can do
var $set = $.add.apply($(), myArray);
myArray is native array, You need jQuery object to bind event handler which $('ul.liste').first().find('li') returns thus it works.
You can use .add() to create collection of jQuery object then use it to bind event handler.
//Create empty jQuery object
var myArray = $([]);
var $list = $('.list')
for (var i = 0; i < 5; i++) {
var $li = $('<li />', {
text: i
}).appendTo($list);
myArray = myArray.add($li);
}
// This doesn't work
myArray.click(function(e) {
console.log(this.textContent);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class='list'>
</ul>
You need to loop over the array instead,
Following is incorrect as it is not binding a click event on corresponding element.
$(myArray).click(function (e) { alert('cc'); });
Instead loop as,
$(myArray).each(function(){
$(this).click(function (e) { alert('cc'); });
});
1) What's the difference between between $(myArray) and $('ul.liste').first().find('li')?
Here, myArray is not any jQuery object but a normal array containing jQuery objects as its element. You never bind event to array or string or any other datatype. you always bind event to jQuery object (that contains some DOM elements). Therefore, instead of binding myArray, you should bind every element of myArray one by one.
When you use $('ul.liste'), it works fine because it is a jQuery object with some DOM element in it.
2) How to correctly convert a js array to a jquery collection? I thought wrapping the array with $() would work but obviously not.
You don't convert js Array to jQuery object. But you convert any DOM element to jQuery object as:
For eg,
var elem = document.getElementById("myElem"); // a DOM element
$(elem) //a jQuery object
Arrays are there just to save some data not for DOM manipulations.
I have cloned div duplicate elements in body with the class name "combo". I need to remove all duplicates except the original div element
The problem is that cloned objects will have the same attributes as the original, so it's rather hard to distinguish them, however, you could try this:
(function()
{
//or indeed: querySelector('.combo') which returns a single DOM ref
var original = document.querySelectorAll('.combo')[0];//reference to the original
//clone and add
function removeClones()
{
var i,all = document.querySelectorAll('.combo');
for(i=0;i<all.length;i++)
{
if (all[i] !== original)
{//this is a clone
all[i].parentNode.removeChild(all[i]);
}
}
}
}());
That should do it. An alternative method would be to add a class to the clones, prior to appending them to the DOM:
var clone = original.cloneNode(true);
clone.className += ' combo-clone';
//then, to remove:
var clones = document.querySelectorAll('combo-clone');//selects all clones
var fn = function(originalEl){
var els = document.querySelectorAll('.combo');
for(var i=0; i<els.length; i++){
if( els[i] !== originalEl ){
els[i].parentNode.removeChild(els[i]);
}
}
}
Keep a reference to the cloned elements somewhere (such as an array). Loop over that array and call foo.parentNode.removeChild(foo) on each value.