So I need to get an array of values rendering in a selection of divs, could anyone help me as to the best way to tackle this?
I have to use javaScript.
You can add DOM elements with JavaScript by creating the element you want, setting the properties/attributes as you desire, and then appending them to the DOM (either directly to the body, or to a containing element), like so:
var arr = ["text1", "text2", "text3"];
var container = document.getElementById("container");
arr.forEach(function (text) {
var div = document.createElement("div");
div.innerText = text;
div.classList.add("div-added");
container.append(div);
});
.div-added {
padding: 10px;
border: 2px solid #333;
}
<div id="container"></div>
Alternatively, you can use jQuery, like so:
var arr = ["text1", "text2", "text3"];
var container = $("#container");
arr.forEach(function(text) {
var div = $("<div>", {
text: text,
class: "div-added"
});
container.append(div);
});
.div-added {
padding: 10px;
border: 2px solid #333;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"></div>
Related
I would like to know, if there is a way to hide certain characters in string, but not replace.
So, for example
let a = 'Hallo';
let b = a.replace('a', ' ');
alert(b);
this code will alert H llo instead Hallo.
Is there any function that really hide (don't display character, but don't replace it (so, we can't see this character, but it exists still there)) ?
Extending on ibrahim mahrir's comment, you could create a hidden class as follows:
<p>Such a nifty string, wi<span class="hidden">th</span>
some l<span class="hidden">e</span>tters missing</p>
Then some javascript could do this:
<script>
var targets = document.querySelectorAll(".hidden");
function hideLetters() {
targets.style.visibility = "hidden";
}
hideLetters();
</script>
By putting it in a function like this, you could dynamically hide them. Say a user clicks a button:
<button id="hider">Hide letters</button>
<script>
var hider = document.querySelector("#hider");
hider.addEventListener("click", hideLetters);
</script>
And then a function to show them, if you like.
<script>
function showLetters() {
targets.style.visibility = "visible";
}
</script>
let div = document.getElementById("div");
let str = "Ibrahim Mahrir plays Hallo!";
div.innerHTML = str.replace(/a/g, "<span class='hidden'>$&</span>");
#div {
margin-top: 30px;
padding: 10px;
background: #fffbec;
border-bottom: 2px solid #d89d9d;
}
.hidden {
visibility: hidden;
}
#div:hover .hidden {
visibility: visible;
}
Hover over the div to see the missing characters:
<div id="div"></div>
Say I have an element like :
var myElem='<div class="oldClass" style="color:green;" id="oldId"><span>This DIV has some
innerHTML as well</span></div>'
And a JSON like:
var myJson = {
"class": "myClass",
"id": "myId",
"style": "border: 1px solid black; color: red; font-size:20px;"
};
Now I need to update myElem with data in JSON.
What I tried is:
for(var key in myJson){
var attrName = key;
var attrValue = myJson[key];
console.log('attrName ', attrName);
console.log('attrValue ', attrValue);
$(myElem).removeAttr(attrName);
$(myElem).attr(attrName, attrValue);
}
My expectation from this code:
myElem = '<div class="myClass" style="border: 1px solid black; color: red; font-size:20px;" id="myId"><span>This DIV has some innerHTML as well</span></div>'
However, this is not working.myElem remains what it was initially.
myElem and myJson both are dynamic and not static
Can anyone please tell what am I doing wrong? (I know I'm doing something wrong but I'm unable to find it)!
You can pass the whole myJson object to attr and don't have to use a loop:
var myElem = '<div class="myClass" style="border: 1px solid black; color: red; font-size:20px;" id="myId"><span>This DIV has some innerHTML as well</span></div>';
var myJson = {
"class": "myClass",
"id": "myId",
"style": "border: 1px solid black; color: red; font-size:20px;"
};
var elem = $(myElem).attr(myJson);
But if you want, it's even possible in a loop. I don't know why you want to, but it's possible. Just define your element outside the loop and here you go:
var elem = $(myElem);
for( var key in myJson ) {
if( myJson.hasOwnProperty(key) ) {
elem.attr(key, myJson[key]);
}
}
Problem
You're not editing the myElem but the temporary jquery instances of it.
Explication
In every iteration in your for loop you're creating a new instance of jquery object $(myElem) and when the .attr() and .removeAttr() execute they will change the attributes inside this new instance and every change will be overridden in the next iteration of the loop because it will create a new instance, so you are not editing myElem variable but the temporary jquery object instances of it.
jQuery Solution
If you want to edit the attribute of object using jquery function attr() you have two choices :
Using the for loop : create a jquery object and let the function change the attributes, it will works fine check example bellow :
var myElemJQueryInstance = $(myElem);
for(var key in myJson){
myElemJQueryInstance.attr(key, myJson[key]);
}
/*
NOTE : Your code will be more clear/efficient if you use just function .attr()
(no need for removeAttr()) because it will override the old value in the
attribute if is exist.
*/
By passing JavaScript object : You could pass a plain JavaScript object. Each key-value pair in the object adds or modifies an attribute (in your case the object is myJson) :
$(myElem).attr(myJson);
JavaScript Solution
You could achieve that using pure js by the method setAttribute() :
for(var key in myJson){
myElem = myElem.setAttribute(key, myJson[key]);
}
Hope this helps.
var myElem = '<div class="oldClass" style="color:green;" id="oldId"><span>This DIV has some innerHTML as well</span></div>'
var myJson = {
"class": "myClass",
"id": "myId",
"style": "border: 1px solid black; color: red; font-size:20px;"
};
var myElemJQueryInstance = $(myElem);
for(var key in myJson){
myElemJQueryInstance.attr(key, myJson[key]);
}
$('body').append(myElemJQueryInstance);
$('body').append(myElem);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I've created a sample file that has adding and removing children elements in a mother element. The adding was successful, but I'm having a problem in removing children elements. The goal is every single click of remove button removes a child element.
var adds = document.querySelector('#add');
var remove = document.querySelector('#remove');
var section = document.querySelector('section');
var div;
adds.onclick = function() {
div = document.createElement('div');
section.appendChild(div);
div.classList.add('style');
};
// THE PROBLEM
remove.onclick = function() {
while(section.children.length !== 0) {
for(var c in section.children) {
section.removeChild(div[c]);
}
}
};
section {
display: flex;
background: #0ff;
height: 100px;
padding: 8px;
}
section > div {margin: 0 1px;}
.style {
width: 100px;
height: 100px;
background: lightgreen;
}
<button id="add">Add</button>
<button id="remove">Remove</button>
<section class="container"></section>
<br>
What's wrong with my code?
What's wrong with my code?
This line
section.removeChild(div[c]);
div could be undefined here and anyways, sections's children are not necessarily div's children
so change it to
section.removeChild(section.children [c]);
Also, while is not necessary
remove.onclick = function() {
for(var c in section.children) {
section.removeChild(section.children[c]);
}
};
EDIT
The goal is every single click of remove button removes a child
element.
remove.onclick = function() {
if(section.children length ) {
section.removeChild(section.children[0]);
}
};
changed for with if
The code
JavaScript:
var recurringF = (function(){
this.$el = $("#target");
this.arg = arguments[0];
this.spl = (!_.isEmpty(this.arg)) ? this.arg.split(" ") : false;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
if(i===0){
this.$el.append(document.createElement(this.spl[i]));
}else{
this.$el.children().last().append(document.createElement(this.spl[i]));
}
}
}
return {
"$":this.$el
}
});
var t = new recurringF("div h1 span");
HTML-Body:
<body>
<div id="target"></div>
</body>
The Goal
I'd like to append elements sequentially to an parent element $("#target") so that the end result in the HTML is the following:
<body>
<div id="target">
<div>
<h1>
<span></span>
</h1>
</div>
</div>
</body>
The loop does not append the created elements to the the last appended element, but to the in loop cycle 1 created element 'div' like the following:
<div id="target">
<div>
<h1></h1>
<span></span>
</div>
</div>
What am I missing?
By using .children(), you'll only get the immediate div on every iteration after the first, thus resulting in
<div id="target">
<div>
<h1></h1>
<span></span>
<alltherest></alltherest>
</div>
</div>
because .children only looks at children, not all descendants. What you want is .find(*) so that it will get the deepest nested descendant on each iteration.
this.$el.find('*').last().append(document.createElement(this.spl[i]));
https://jsfiddle.net/f3fb997h/
That said, it would be better if you just stored a reference to the last created element and append to it, rather than having to reselect it every iteration.
var $tempEl = this.$el, newEl;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
newEl = document.createElement(this.spl[i]);
$tempEl.append(newEl);
$tempEl = $(newEl);
}
}
https://jsfiddle.net/f3fb997h/1/
Note that at this point you're not really benefiting from jQuery at all, so a small tweak and you're not depending on it.
var recurringF = (function(){
this.el = document.getElementById('target');
this.arg = arguments[0];
this.spl = (!_.isEmpty(this.arg)) ? this.arg.split(" ") : false;
console.log(this.spl);
var tempEl = this.el, newEl;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
newEl = document.createElement(this.spl[i]);
tempEl.appendChild(newEl);
tempEl = newEl;
}
}
return {
"el":this.el
}
});
You can try using regular javascript functionality, as it has child appending built in:
const recurseElement = (elementString, target) => {
const elements = elementString.split(' ');
elements.forEach(function(ele) {
const domElement = document.createElement(ele); // create the element
target.appendChild(domElement); // append to the target
target = domElement; // this element is the new target
});
}
So now you can use it like so:
recurseElement('div h1 span', document.getElementById('target'));
const recurseElement = (elementString, target) => {
const elements = elementString.split(' ');
elements.forEach(function(ele) {
const domElement = document.createElement(ele); // create the element
target.appendChild(domElement); // append to the target
target = domElement; // this element is the new target
});
};
recurseElement('div h1 span', document.getElementById('target'));
#target div {
background: green;
height: 16px; width: 128px; padding: 10px;
}
#target div h1 {
background: red;
height: 16px; width: 64px; padding: 10px;
}
#target div h1 span {
background: purple; display: block;
height: 16px; width: 32px; padding: 10px;
}
<div id="target"></div>
It should be noted that arrow functions are available for Chrome 45+, Firefox 22.0+, Edge, and Opera. They do not work in IE or Safari. Or they will work if you have a transpiler (like babel)
The following code copies all elements given one css class, that's fine, it does render the list of elements... Now I'd like to wrap those results in HTML content, how can I achieve that?
setTimeout(function() {
var element = document.getElementById("unique_ID");
element.innerHTML = "";
Array.prototype.forEach.call(document.querySelectorAll(".a_random_class"), function(e) {
var storednode = element.appendChild(e.cloneNode(true));
});
}, 300);
How can I wrap in HTML content each of the storednode? I've been able to apply classes: storednode.className += " another-class";, but how can I wrap the results in any HTML I want? is that possible?
Thank you for your time.
Edit:
This is what the script does.
setTimeout(function() {
var element = document.getElementById("unique_ID");
element.innerHTML = "";
Array.prototype.forEach.call(document.querySelectorAll(".a_random_class"), function(e) {
element.appendChild(e.cloneNode(true));
});
}, 300);
#unique_ID {
border: 1px solid blue;
}
<div id="unique_ID"></div>
<div class="a_random_class">a</div>
<div class="a_random_class">b</div>
<div class="a_random_class">c</div>
<div class="a_random_class">d</div>
<div class="a_random_class">e</div>
<div class="a_random_class">f</div>
What I need is that each result, for example <div class="a_random_class">f</div> can be wrapped inside any HTML code I want, to get something like <div id="another-div" class="a-class" style="maybe:styles"><li><div class="a_random_class">f</div></li></div> This is certainly an example, but I'd like to know if that's possible... Not only copy the class elements but also append some HTML on them.
I think what you are looking for is something like
setTimeout(function () {
var element = document.createElement('div');
element.className = 'something';
[].forEach.call(document.querySelectorAll(".a_random_class"), function (e) {
var wrap = element.cloneNode(true);
e.parentNode.insertBefore(wrap, e)
wrap.appendChild(e);
});
}, 300);
setTimeout(function() {
var element = document.createElement('div');
element.className = 'something';
[].forEach.call(document.querySelectorAll(".a_random_class"), function(e) {
var wrap = element.cloneNode(true);
e.parentNode.insertBefore(wrap, e)
wrap.appendChild(e);
});
}, 300);
.something {
border: 1px solid red;
padding: 5px;
margin-bottom: 5px;
}
.a_random_class {
background-color: lightgrey;
}
<div class="a_random_class">a</div>
<div class="a_random_class">b</div>
<div class="a_random_class">c</div>
<div class="a_random_class">d</div>
<div class="a_random_class">e</div>
<div class="a_random_class">f</div>