I want to create div continuously and it should come on the next line if it reaches the outer div's width in JavaScript without using canvas and float.
for(i = 0; i < 20; i++) {
var ind = (Math.round(Math.random(0,2)*2));
var child = document.createElement("div");
child.setAttribute("id","div"+i);
child.style.backgroundColor=colors[ind];
maindiv.appendChild(child);
}
You can use display: inline-block; css property. Refer this
var maindiv = document.getElementById('parent');
for (var i = 0; i < 100; i++) {
var ind = (Math.round(Math.random(0, 2) * 2));
var child = document.createElement("div");
child.setAttribute("id", "div" + i);
child.setAttribute("class", "inline");
child.innerText = 'div';
//child.style.backgroundColor = colors[ind];
maindiv.appendChild(child);
}
.inline {
display: inline-block;
}
<div id="parent"></div>
Related
Im pretty new to programming and im trying to develop a chrome extension. The website that im trying to manipulate has a div element and within this div are multiple divs and the number of these divs vary depending on the scale of the first div and the scale is draggable by the user. My problem is that, I need to declare each of these variables and have a mutation observer observe them for changes. So if a user has 8 div in there, each div should be declared as a variable and have a mutation observer observing it. Below is my code:
function tester() {
var child = document.querySelector("#__APP > div > div:nth-child(3) > div > div > div.react-grid-layout.layout > div:nth-child(5) > div > div.css-q57e4p > div > div > div.list-container.css-1kq4s3b > div.list-auto-sizer > div > div");
var childnodesofchild = [child.childNodes];
var divs = [];
console.log(childnodesofchild[0]);
childnodesofchild[0].forEach(consoler);
function consoler() {
//this is the problem
span1 = document.getElementsByClassName("text right")[0];
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
var spantext = span1.textContent;
var spandiv = span1.parentNode;
if (mutation.addedNodes) {
if (spantext > avg) {
spandiv.style.backgroundColor = "#E8E8E8"
spandiv.style.color = "black";
spandiv.style.opacity = "0.7";
}
if (spantext < avg) {
spandiv.style.backgroundColor = "black";
spandiv.style.color = "white";
spandiv.style.opacity = "1";
}
}
})
});
const options = {
childList: true,
subtree: true,
attributes: true,
characterData: true
};
observer.observe(span1, options);
}
}
I am still not 100% sure what your question is. But here, I wrote a quick example of how you can declare a few divs in a loop and mess with its properties in a loop. I hope this is helpful.
let colors = ['red','green','blue'];
let innerText = ['A','B','C'];
for (let i = 0; i < colors.length; i++) {
let testDiv = document.createElement('div');
testDiv.className = 'test';
testDiv.style = 'width: 100px; height: 50px; line-height: 50px; text-align: center; color: white;';
testDiv.style.backgroundColor = colors[i];
testDiv.innerHTML = innerText[i];
document.body.appendChild(testDiv);
}
document.getElementById('testBtn').onclick = function() {
let testDivs = document.querySelectorAll('.test');
for (let i = 0; i < testDivs.length; i++) {
testDivs[i].style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
}
}
<button id="testBtn">Change Div Colors</button>
I have two divs, one for left side and one for right side.
On the left one I appended 5 different images. I need to clone those 5 to the right one, append them to the right one and delete the last node.
For the left one:
var LS = document.getElementById("left");
var number = 5;
while(number > 0)
{
var theImage = document.createElement("img");
LS.appendChild(theImage);
number--;
}
For the right side:
var RS = document.getElementById("right");
var leftImages = LS.cloneNode(true);
RS.appendChild(leftImages);
while(RS.lastChild!=null)
{
var noviCh = RS.lastChild;
}
RS.removeChild(noviCh);
Code doesn't work. Anyone has idea why?
Instead of adding all the images and then removing one, how about just not adding the last one in the first place?
var LS = document.getElementById("left");
for (var i = 0; i < 5; i += 1) {
var theImage = document.createElement("img");
LS.appendChild(theImage);
}
var RS = document.getElementById("right");
var imgs = LS.getElementsByTagName('img');
for (var i = 0; i < imgs.length - 1; i += 1) {
RS.appendChild(imgs[i].cloneNode(true));
}
#left {
background-color: yellow;
}
#right {
background-color: green;
}
img {
width: 100px;
height: 100px;
background-color: red;
}
<div id="left"></div>
<div id="right"></div>
var LS = document.getElementById("left");
for ( var number = 5; number > 0; number--)
{
LS.appendChild(document.createElement("img"));
}
and
var RS = document.getElementById("right");
while( LS.lastChild )
{
RS.appendChild( LS.lastChild.cloneNode(true) );
LS.removeChild( LS.lastChild );
}
I wrote a bunch of JS code to add click listeners to the HTML buttons. I have some CSS that applies to the existing HTML. But the CSS doesn't appear to apply to the HTML generated by the JavaScript.
Link to JSfiddle
As you can see, line 1 has all the proper spacing. But any of the generated lines by clicking any of the three buttons lose the spacing.
Here's the CSS:
.form-block {
padding: 5px;
margin: 5px;
border: 1px solid #000;
span {
padding-right: 15px;
}
}
Thanks for the help in advance! :)
What you see are actual spaces between the elements in your original HTML/row, and then a lack of spaces between the elements in your JS generated elements.
I would either remove the spaces between the elements in your HTML, and use a left/right margin value to create that space instead, or add a space or carriage return/new line between the elements when you add them in your JS.
I removed the spaces (by inserting HTML comments) in your original HTML, and added margin-right: 1em to the input and buttons in your element row.
/*This function interprets the line position.
//input is a lpos string which is in the form of x.x.x.x
//splits it by the '.'
//returns the array with position
*/
function lposToAr(lpos) {
var ar = lpos.split('.');
for (var i = 0; i < ar.length; i++) {
ar[i] = parseInt(ar[i], 10);
}
return ar;
}
//This function turns the position array back into a string
function lposToStr(posAr) {
return posAr.join('.');
}
//This function creates a new line after clicking the NL button.
function NL(lpos, e) {
e.preventDefault();
var cLine = document.getElementsByClassName('line')[0].cloneNode(true);
var cNL = document.getElementsByClassName('new-line')[0].cloneNode(true);
var cNN = document.getElementsByClassName('new-nested')[0].cloneNode(true);
var cI = document.getElementsByClassName('input')[0].cloneNode(true);
cI.value = '';
var cNI = document.getElementsByClassName('new-input')[0].cloneNode(true);
//figure out which position
var posAr = lposToAr(lpos);
var clickNode = document.getElementsByTagName('form')[0];
for (var i = 0; i < posAr.length; i++) {
clickNode = clickNode.children;
var skipCount = 0;
for (var j = 0; j < clickNode.length - 1; j++) {
if (clickNode[j].tagName != 'DIV') {
skipCount++;
}
}
clickNode = clickNode[posAr[i] + skipCount - 1];
}
//set the last element of the posAr the total number of same level <div>+1
var siblingDivCount = 0;
for (var i = 0; i < clickNode.parentNode.children.length; i++) {
if (clickNode.parentNode.children[i].tagName == 'DIV') {
siblingDivCount++;
}
}
var newPosAr = posAr;
newPosAr[newPosAr.length - 1] = siblingDivCount + 1;
//Update the cloned items with the new line info
var newPosStr = lposToStr(newPosAr);
cLine.innerHTML = newPosStr;
cNL.addEventListener('click', function(event) {
NL(newPosStr, event);
});
cNN.addEventListener('click', function(event) {
NN(newPosStr, event);
});
//cI doesn't need to change, unless there's a bug
cNI.addEventListener('click', function(event) {
NI(newPosStr, event);
});
//Make the new Div
var newDiv = document.createElement('div');
newDiv.setAttribute('class', 'form-block');
newDiv.appendChild(cLine);
newDiv.appendChild(cNL);
newDiv.appendChild(cNN);
newDiv.appendChild(cI);
newDiv.appendChild(cNI);
//Add the new Div
clickNode.parentNode.appendChild(newDiv);
}
function NN(lpos, e) {
e.preventDefault();
var cLine = document.getElementsByClassName('line')[0].cloneNode(true);
var cNL = document.getElementsByClassName('new-line')[0].cloneNode(true);
var cNN = document.getElementsByClassName('new-nested')[0].cloneNode(true);
var cI = document.getElementsByClassName('input')[0].cloneNode(true);
cI.value = '';
var cNI = document.getElementsByClassName('new-input')[0].cloneNode(true);
var posAr = lposToAr(lpos);
var clickNode = document.getElementsByTagName('form')[0];
for (var i = 0; i < posAr.length; i++) {
clickNode = clickNode.children;
var skipCount = 0;
for (var j = 0; j < clickNode.length - 1; j++) {
if (clickNode[j].tagName != 'DIV') {
skipCount++;
}
}
clickNode = clickNode[posAr[i] + skipCount - 1];
}
var childDivCount = 0;
for (var k = 0; k < clickNode.children.length; k++) {
if (clickNode.children[k].tagName == 'DIV') {
childDivCount++;
}
}
posAr.push(childDivCount + 1);
//Update the cloned items with the new line info
var newPosStr = lposToStr(posAr);
cLine.innerHTML = newPosStr;
cNL.addEventListener('click', function(event) {
NL(newPosStr, event);
});
cNN.addEventListener('click', function(event) {
NN(newPosStr, event);
});
//cI doesn't need to change, unless there's a bug
cNI.addEventListener('click', function(event) {
NI(newPosStr, event);
});
//Make the new Div
var newDiv = document.createElement('div');
newDiv.className = 'form-block';
newDiv.appendChild(cLine);
newDiv.appendChild(cNL);
newDiv.appendChild(cNN);
newDiv.appendChild(cI);
newDiv.appendChild(cNI);
//Add the new Div
clickNode.appendChild(newDiv);
}
function NI(lpos, event) {
event.preventDefault();
//copy text box
var cI = document.getElementsByClassName('input')[0].cloneNode(true);
cI.value = '';
//find the node that has been clicked
var posAr = lposToAr(lpos);
var clickNode = document.getElementsByTagName('form')[0];
for (var i = 0; i < posAr.length; i++) {
clickNode = clickNode.children;
var skipCount = 0;
for (var j = 0; j < clickNode.length - 1; j++) {
if (clickNode[j].tagName != 'DIV') {
skipCount++;
}
}
clickNode = clickNode[posAr[i] + skipCount - 1];
}
//add the new textbox
clickNode.insertBefore(cI, clickNode.getElementsByClassName('new-input')[0]);
}
document.getElementsByClassName('new-line')[0].addEventListener('click', function(event) {
NL(document.getElementsByClassName('line')[0].innerHTML, event);
});
document.getElementsByClassName('new-nested')[0].addEventListener('click', function(event) {
NN(document.getElementsByClassName('line')[0].innerHTML, event);
});
document.getElementsByClassName('new-input')[0].addEventListener('click', function(event) {
NI(document.getElementsByClassName('line')[0].innerHTML, event);
});
/**
* Add styling to the form to make it look appealing
*/
.form-block {
padding: 5px;
margin: 5px;
border: 1px solid #000;
}
span {
padding-right: 15px;
}
.form-block button, .form-block input {
margin-right: 1em;
}
<!--
DO NOT CHANGE THE CONTENTS OF THIS BLOCK
-->
<form class='myform'>
<div class='form-block'>
<span class='line'>1</span><!--
--><button class='new-line'>New Line</button><!--
--><button class='new-nested'>New Nested Line</button><!--
--><input class='input' type='text' placeholder='Enter Value...'><!--
--><button class='new-input'>Add input</button>
</div>
</form>
What I'm trying to do is write a function that will iterate over all different html elements which have a class name beginning with rnum- followed by a number. A complete example of a span would be <span class="rnum-293"></span>.
I then want to implement the function that I have written below and have it do the increasing effect up to each of their given numbers(specified in the class name).
Does anyone have an idea how I can achieve this? Thanks!
var count = 0;
var target = 126;
var increment = target / 198;
var elements = document.getElementsByClassName('rnum');
function calc() {
if(count < target) {
count += increment;
}
for(var i = 0; i < elements.length; i++) {
elements[i].innerHTML = Math.round(count);
}
}
setInterval(calc, 10)
#import url('https://fonts.googleapis.com/css?family=Bangers');
body {
font-family: 'Bangers';
display: flex;
align-items: center;
justify-content: center;
}
.rnum {
font-size: 55px;
margin: 50px;
}
<span class="rnum"></span>
<span class="rnum"></span>
<span class="rnum"></span>
To select the elements, use:
var elements = document.querySelectorAll('[class^="rnum-"]');
Or, if only span elements, use:
var elements = document.querySelectorAll('span[class^="rnum-"]');
I am unsure about the second part of your question. For all I see, the only issue was selecting the elements.
For the second part:
JavaScript:
var elements = document.querySelectorAll('span[class^="rnum-"]');
function calc() {
var el = null;
var val = 0;
var currentValue = 0;
var incrementFactor = 198;
var increment = 0;
var maxValue = 0;
for (var i = 0, len = elements.length; i < len; i++) {
el = elements[i];
maxValue = Number(el.getAttribute('data-max-val'));
currentValue = Number(el.getAttribute('data-current-val'));
increment = maxValue / incrementFactor;
if ((currentValue + increment) > maxValue)
continue;
val = currentValue + increment;
el.innerHTML = Math.round(val);
el.setAttribute('data-current-val', Math.round(val));
}
}
setInterval(calc, 10)
HTML:
<span class="rnum-198000" data-current-val="0" data-max-val="198000">0</span>
<span class="rnum-299000" data-current-val="0" data-max-val="299000">0</span>
<span class="rnum-399000" data-current-val="0" data-max-val="399000">0</span>
<span class="rnum-499000" data-current-val="0" data-max-val="499000">0</span>
Pen: http://codepen.io/anon/pen/rjyqMd?editors=1111
I'm trying to create a grid of circles which change color when clicked. The code I currently have to create the grid visually (which works) is this:
var color = null;
for (var r = 0; r < 5; r++) { // row
for (var c = 0; c < 5; c++) { // column
var myCircle = document.createElement('div');
myCircle.id = "circle";
myCircle.style.left = r * 56 + "px";
myCircle.style.top = c * 56 + "px";
document.getElementById('grid').appendChild(myCircle); //maybe error
}
}
I want to turn this into its jquery equivalent to handle the change in state on clicking. Here's what I've got so far:
var color = null;
for (var r = 0; r < 5; r++) { // row
for (var c = 0; c < 5; c++) { // column
var $myCircle = $("#circle");
$myCircle.style.left = r * 56 + "px";
$myCircle.style.top = c * 56 + "px";
$(document).ready(function () {
$($myCircle).click(function() {
$($myCircle).css('backgroundColor', 'color');
});
});
$('#grid').append($mycircle);
}
}
Any idea where I'm going wrong? Do I need to introduce the 'div' somewhere in the above code? How?
you are selecting an element and not creating here
$("#circle");
try this
$(document).ready(function () {
for (var r = 0; r < 5; r++) { // row
for (var c = 0; c < 5; c++) { // column
var $myCircle = $("<div />").attr({class:"circle"}).css({left:r * 56 + "px" ,top :c * 56 + "px"})); //creating a div element with its attributes...
$('#grid').append($mycircle); //appending it to grid
}
}
$('#grid').on('click','#circle',function() { //using on delegate for dynamically added div
$(this).css('backgroundColor', 'color');
});
});
for click event to work for dynamically added element, we need to delegate it to closest static parent. and ID should always be unique so its better to change your ID to class which i am doing here.
updated
updated some errors in your fiddle check it out..
remove the . in mycircle
var $myCircle = $('<div />').addClass('circle').css({
//-------------^---removed the `.`..
and changed all you javascript to jquery..
working fiddle
var $myCircle = $("#circle");
Should be:
var myCircle = $("#circle")[0];
Because you use the DOM native functions, but it's a jQuery wrapper.
Note that I removed the $ prefix from myCircle because now it's a DOM element.
When you're doing a bunch of appends like this, it performs better to use a document fragment. The code would look like this:
var frag = document.createDocumentFragment();
for (var r = 0; r < 5; r++) { // row
for (var c = 0; c < 5; c++) { // column
var $circle = $('<div/>').addClass('circle').css({left: r*56, top: c*56});
frag.appendChild($circle.get(0));
}
}
$('#grid').append(frag).on('click', '.circle', function(){
$(this).css('backgroundColor', 'red');
});
But I suggest going with an inline-block approach to layout your circles. The Compass mix-in is really handy for this. Also, the border-radius Compass mix-in. This way, your code is reduce to:
var frag = document.createDocumentFragment();
for (var i = 0; i < 25; i++)
frag.appendChild($('<div/>').addClass('circle').get(0));
$('#grid').append(frag).on('click', '.circle', function(){
$(this).css('backgroundColor', 'red');
});
Also, you don't need to specify + 'px' on jQuery css props. Don't forget the / before the > in $('<div/>') either. I created a jsFiddle here with the last solution.
And here's the supporting SCSS:
$radius: 50px;
$gap: 6px;
#grid {
width: ($radius + $gap) * 5;
}
.circle {
display: inline-block;
float: left;
border-radius: $radius;
width: $radius;
height: $radius;
border: $gap/2 solid white;
background-color: yellowgreen;
}
Even better, have the click do a toggleClass('active') and set the CSS .active {color: red; }