How to create array and divs with a unique height using jQuery? - javascript

I need 100 small divs for my chart, every time I generate them, I they all appear as the same height; the last value from the array.
var valuesG = new Array(100);
for (i = 0; i < valuesG.length; i++ ) {
valuesG[i] = Math.floor(Math.random() * 101);
$("#second").append("<div class='single'></div>");
$(".single").css('height', valuesG[i])
}
Any ideas why this is happening?

You are applying the new height to ALL the .single elements in every iteration. In the last iteration, they end up having the same height.
You could do it like this:
$('<div class="single">')
.css('height', valuesG[i])
.appendTo($('#second'));
Also, your code is not very efficient, take a look at this:
var valuesG = [], //array literal
$elements = $(); //empty jQuery object
for (var i = 0; i < 100; i++) { //we don't have to query array length each iteration
valuesG[i] = Math.floor(Math.random()*101);
//collect the elements into a jQuery object
$elements = $elements.add($('<div class="single">').css('height', valuesG[i]));
}
$elements.appendTo($("#second")); //insert to DOM once - much quicker
jsFiddle Demo

Currently, you're selecting all elements with class single. To get the desired effect, use the appendTo method in the way as shown below.
Side note, the generated heights are not unique, but random. It's possible that two elements exist with, say, height 50. See this question for a method to generate unique random numbers.
var valuesG = new Array(100), i;
for ( i=0; i < valuesG.length; i++ )
{
valuesG[i] = Math.floor(Math.random()*101);
$("<div class='single'></div>")
.css( 'height', valuesG[i] )
.appendTo("#second");
}

You get only one height(last one) because you set same css class in all div and update it's height in every loop so last height value will be applied to all.
As a solution try this:
for ( i=0; i < valuesG.length; i++ ) {
valuesG[i] = Math.floor(Math.random()*101);
$("<div class='single'></div>").css('height',valuesG[i]).appendTo("#second");
}

Related

Different/Increasing CSS Value for Many DIVs With Same Class

I want to use javascript to change the left-margin value of many separate DIVs. The catch is that:
I want to use only one className and
I want the margin to increase, for example, 100px for each instance of the class. This way, instead of having all the DIVs land on top of each other, each DIV will be space out: the first at margin-left:0px, the second at margin-left:100px, the third at margin-left:200px, and so on.
Here is the code that I have which simply applies the same margin-left to all DIVs.
<script>
b = document.getElementsByClassName('spacing');
for (i = 0; i < b.length; i++) {
b[i].style.marginLeft = "100px";
}
</script>
Is there a way to get the javascript to find each instance of the class sequentially and instead of simply applying margin-left:100px to all, it does something like (margin applied to last instance of class + X) so each of 100 DIVs with the same className end up with a unique marginLeft value?
Yes there is a way You can simply multiply the amount of margin by iteration number like this i*100+'px' instead of this "100px"
var b = document.getElementsByClassName('spacing');
for (i = 0; i < b.length; i++) {
b[i].style.marginLeft = i*5+'px';
}
Here is the working example
What you want to do is keeping track of your increasing margin by every iteration of the loop:
b = document.getElementsByClassName('spacing');
var margin = 0;
for (i = 0; i < b.length; i++) {
margin += 100;
b[i].style.marginLeft = margin + "px";
}
That should do the trick.
Check out a working example here: https://jsfiddle.net/c4p9ry46/

Making divs fill up a containing div?

I've been searching the site for an answer, and nothing I've come across seems to help. I'm trying to make it so that a default (and eventually user-specified) number of divs fill up the containing div like a grid. I'm trying to figure out how to make the size of the boxes I append to the parent change depending on how many are added, while always filling up the div, if that makes sense. So for instance, if I specify 9, I should have 3 rows and 3 columns. If I specify 62, then I'm looking for 16 rows and 16 columns, always filling up (or coming close to, anyway) the containing div. Here's a JSfiddle I have so far: https://jsfiddle.net/psyonix/1g9p59bx/1/ Here's the code as it is:
var d = ("<div class='square'></div>");
function createGrid(numSquares){
for(var i = 0; i < numSquares; i++){
$('#g_area').append(d);
}
var squareSize = Math.floor(580/numSquares );
$('.square').height(squareSize);
$('.square').width(squareSize);
};
$(document).ready(function(){
createGrid(64);
});
The only issue you had was setting the square size to 1/64th of the height instead of 1/(64^.5) of the height. Essentially you where just making one row. https://jsfiddle.net/1g9p59bx/7/
var d = ("<div class='square'></div>");
function createGrid(numSquares){
var gridContainer = $('#g_area');
for(var i = 0; i < numSquares; i++){
gridContainer.append(d);
}
var squareSize = Math.floor(580/(Math.sqrt(numSquares)) );
$('.square').height(squareSize);
$('.square').width(squareSize);
};
$(document).ready(function(){
createGrid(64);
});
I would create a little jqueryplugin for that. You can call it in every container you like: containerForGrid.createGrid(cols, rows)
(function($){
$.fn.createGrid = function(cols, rows) {
// get width and height of sorrounding container
var w = this.width()
var h = this.height()
// calculate width and height of one cell
var colWidth = w / cols
var rowHeight = h / rows
// loop over all rows
for(var i = rows; --i;){
// loop over all cols
for(var j = cols; --j;){
$('<div>').css({
width:colWidth,
height:rowHeight,
float:'left'
}).appendTo(this)
}
}
}
})(jQuery)
jQuery('div').createGrid(10,10)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="width:1000px;height:500px">
</div>

In a for loop, how do I increment a counter once every other time?

I apologize for the clunky wording of the question. English is not my first language.
I am creating a scrollable list. Each element of this list consists of a column with two rows. I don't want to offset the column until each row is filled. I basically only want to increment the offset counter every two cycles of the for loop. My code for this is as follows:
var j = 0;
for(var i=0;i<localArray.length;i++){
var iconLeft = 145 * j;
var div = document.createElement('div');
div.id = "page_icon_" + i;
div.style.position = "absolute";
div.style.height = "45px";
div.style.width = "145px";
div.style.left = iconLeft + "px";
var item = fishListItem(localArray[i].info);
div.appendChild(item);
var parent = document.getElementById('tut_icons_scroll');
if(i%2){
item.style.top = "40px";
parent.appendChild(div);
}else{
parent.appendChild(div);
}
if (i%2) {
j++;
}
Is there a way to do with without introducing the variable 'j'?
You could just do:
Math.floor(i/2)
in place of j.
In this case, you can replace all instances of j with Math.floor(i/2).
I would like to use pure css nth-child to accomplish this requirement
if(i%2){
item.style.top = "40px";
parent.appendChild(div);
}
to replace this, in your css div:nth-child(even) { top: 40px; }
to replace j, just create a class for the column, set the margin for it, and position set to relative, float set to left.
can you provide your code in jsbin or jsfiddler so I can help you out. I thought this solution is much clear and easy to maintain.
Would it be easy to use a pass element i and then (i+1) to a function and then count up by 2s?
Something like:
function appendFunction(elementToAdd, addItTo) {}
for (var i = 0; i < localArray.length; i+=2) {
var iconLeft = 145*(i%2); // at 0
var iconRight = 145*(i%2 + 1); // at 145
appendFunction(elementToAdd[i], addItTo}
appendFunction(elementToAdd[i+1], addItTo}
}
Not sure if the function helps a lot, but anyways, adding by twos and treating the cases of (x) and (x+1) within the for loop should allow you to increment a counter once every other time. You have to say what to happen twice each time, but one you make a function for it, it's about as long and leaves you with an easily reusable bit to append the elements in the way to place the text.
You can use Math.floor as stated in a couple of answers. Or bit-shift right by one:
i>>1;
Either substitute j with this expression, or use: var j=i>>1;. i>>1 will have the following values for each loop with an incrementing i:
0,0,1,1,2,2,3,3,4,4,...
Try this:
for(var i=0, j=0; i < 10; i++%2 && ++j) {
console.log(i,j);
}

How do I set the style of SVG CSS attributes in Javascript?

I'm trying to dynamically determine the length of an array of SVG paths and then insert this value into the HTML DOM style object for the attributes stroke-dasharray and stroke-dashoffset.
var horizontals = document.getElementsByClassName('hLine');
for (var i = 0; i < horizontals.length; i++ ) {
var drawingComponent = horizontals[i],
length = svgPiece.getTotalLength();
horizontals[i].style.strokeDasharray = length;
horizontals[i].style.strokeDashoffset = length;
}
In the example found here, all the .hLine paths (all the horizontal lines) should animate, but they do not.
Is this because strokeDasharray and strokeDashoffset aren't supported?
For a start, there are some things wrong with that Javascript:
var horizontals = document.getElementsByClassName('hLine');
Your SVG doesn't have any elements with the class 'hLine'.
length = svgPiece.getTotalLength();
'svgPiece' is not defined anywhere.
Try something like this:
var horizontals = document.querySelectorAll('#horizontal path')
for (var i = 0; i < horizontals.length; i++ ) {
var path = horizontals[i],
length = path.getTotalLength();
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
}
Demo here - although there is still some work to do to get the animation working properly.
You can always also just fix the path length by setting pathLength (https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/pathLength) to a value (like 100 for easy percent-based modification).

How to characterize z-indexing for the DOM? (2)

I've been a bit care-less with choosing z-indexes in my CSS.
I'd like to traverse the DOM and report all the z-indexes with their respective ID's.
For example:
id z-index
header 10
main 0
menu 20
The end result would be an object whose keys are the element id and the value is the z-index. One might call it z_obj
// pseudo code
var z_obj = {el_id: el_zindex};
Getting the z-index for each element ( el ) should be easy using something like filter and the code below:
// attr is attribute
data = _.filter(el.attributes, function (attr) {
return (/^z-index/).test(atttr.name);
});
But how would I traverse the DOM to get all z-indexes and store that in an object?
I'd like to do this w/ out libraries, and using the code above if possible.
This would be a good debug tool in general.
You can get all elements with getElementsByTagName("*"), iterate over the collection with a for loop, and use window.getComputedStyle(Node). From there, you can retrieve the z-index. Here's an example:
var zObj, allEls, i, j, cur, style, zIndex;
zObj = {};
allEls = document.body.getElementsByTagName("*");
for (i = 0, j = allEls.length; i < j; i++) {
cur = allEls[i];
style = getComputedStyle(cur);
zIndex = style.getPropertyValue("z-index");
zObj[cur.id] = zIndex;
}
DEMO: http://jsfiddle.net/mj3cR/1/
Where zObj is an Object, keys represented by the id attributes, and values represented by the z-index style.
Note that getComputedStyle is not supported in IE < 9, but of course there are many polyfills :)
reportZ = function () {
var z_arr = {},
all_el = document.body.getElementsByTagName("*"),
i,
len,
cur,
style,
z_index;
for (i = 0, len = all_el.length; i < len; i++) {
cur = all_el[i];
style = win.getComputedStyle(cur);
z_index = style.getPropertyValue("z-index");
if (z_index !== "auto") {
z_arr[i] = [cur.id, cur.tagName, cur.className, z_index];
}
}
return z_arr;
};

Categories