new offsetHeight does not calculated after updating font size - javascript

I have a problem regarding 'offsetHeight' property does not get updated after updating font size. Bellow is the code.
function shrink_toolbar_text()
{
var toolbar = document.getElementById("toolbar");
var icons = document.getElementsByClassName("icon-alone");
var icon_size = 64;
var icon_height = icons[0].offsetHeight ;
while( icon_height > toolbar.offsetHeight)
{
// textSpan.style.fontSize = parseInt(textSpan.style.fontSize) - 1;
icon_size = icon_size -1;
for ( i=0; i< icons.length ;i++){
icons[i].style.fontSize = icon_size ;
}
icon_height = icons[0].offsetHeight ;
console.log( icon_height);
console.log( icon_size);
// console.log( parseInt(icon_size));
}
console.log("shrink_toolbar_text() ");
}
any workaround on this situation ?
I've tried following things so far.
1. Try to redraw each and every icons using show and hide.
2. Tried 'getComputedStyle()' but it don't return a value called 'offsetHeight' at all.
Any idea why code is not working?

The code should be corrected to this.
var icon_size = 64px;
and
icons[i].style.fontSize = icon_size+"px" ;
In some browsers, this code won't work without postfix 'px'. Neither it emit a error message on console. So careful coding on this.

Related

Array index out of bounds in Angular 2

I want to declare an Array with 4 dimensions, then loop some stuff with for() - and then the program breaks. Here is my code:
Typescript:
MoarInfo: any = [[[[]]]];
JavaScript:
constructor(){
for(var i = 0; i < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth].length; i++){
for(var a = 0; a < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i].length; a++){
for(var b = 0; b < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a].length; b++){
this.MoarInfo[i][a][b][0] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][0];
this.MoarInfo[i][a][b][1] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][1];
this.MoarInfo[i][a][b][2] = 'DetailsSpan';
}
}
}
}
The Problem definitively lies at the MoarInfo[][][][] array. I tested my code without it, and it works fine. I tried the following possibilities for the Typescript array declaration as well:
Moarinfo: any[]; MoarInfo = []; MoarInfo = [[[[]]]]; MoarInfo: any[][][][] = [[[[]]]];
And in JavaScript, I tried to declare a new Array, and then push some elements on the MoarInfo array, with different functions (split, unshift, push, concat) and nothing worked.
What am I doing wrong?
Check the size of this.MoarInfo[i][a][b]. You are trying to get the value by index 0,1,2. Looks like its size is less than 2 which is causing this error.
if(this.MoarInfo[i][a][b].size > 0){
this.MoarInfo[i][a][b][0] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][0];
}
if(this.MoarInfo[i][a][b].size > 1){
this.MoarInfo[i][a][b][1] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][1];
}
if(this.MoarInfo[i][a][b].size > 2){
this.MoarInfo[i][a][b][2] = 'DetailsSpan';
}
Okay, I figured it out for myself. You have to set the elements of the dimensions from the array at first blank, then you can fill them with content. First I declared an Array in TypeScript like this AnArray = [];. Then I switched to JavaScript ( to the constructer() function ) and filled it with blank elements. I archieved this with this.AnArray.push();. If you want to set elements for the first dimension use push([]);, if you want an element for the 4th dimension, use push([[[]]]);. And you can set your content space like this push([[['E1',0,0,'E2']]]);. Now you can use follwing syntax:
alert( this.AnArray[0][0][0][3] ); //returns 'E2'
The complete code from my project now works fine and looks like this:
for(var i = 0; i < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth].length; i++){
this.test.push([[[]]]);
for(var a = 0; a < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i].length; a++){
this.test[i].push([[]]);
for(var b = 0; b < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a].length; b++){
this.test[i][a].push(['',0,'']);
this.test[i][a][b][0] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][0];
this.test[i][a][b][1] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][1];
this.test[i][a][b][2] = 'DetailsSpan';
}
}
}
I wonder if there is a better way than using arrays, but if you want it too, you can do it like this.
cheers

Javascript, Dynamic Table insert option boxes into table

I have been using excel for my project for a few years. I have finally decided to move it into a html project instead. It kinda sucks as I need to learn everything about JS, CSS and html and probably much more. And my excel project is quite advanced at this point.
But I will just have to start at the beginning and add things as I learn. In the end I think it will be worth it.
So after many hours of trial and error I have been able to create this simple code:
function myFunction2() {
var table = document.getElementById("Table1");
var row = table.insertRow(table.length);
for (i = 0; i < 10; i++) {
row.insertCell(i);
}
row.insertCell(1).innerHTML = "NEW CELL1";
}
And here is the delete function, is that phrased correctly as I thought the numbers where acting strangely
function myDeleteFunction() {
var x = document.getElementById('Table1').rows.length;
var x = (+x - +1);
if (x >= 1) {
document.getElementById("Table1").deleteRow(x);
}
}
This basically insets one new row to my table, However in cells(0,3,4,5,6,7,10) I would need a dropdown list How would I go about to add this ?
Any help would be much appreciated.
In the world of HTML the nearest analogy of a dropdown list is probably select element; a simple example would be (at the end of your myFunction2):
row.insertCell(0).innerHTML = '<select><option>opt A</option><option>opt B</option></select>';
You might want to use the DOM API (to save some parsing & prevent problems from creating HTML directly) - see for example this SO question on how to do so.
Hi guys thanks for your replies. I actually found an answer while waiting , Not sure if my way is the best:
function myFunction2() {
var img = new Image();
var table = document.getElementById("Table1");
var row = table.insertRow(table.length);
for (i = 0; i < 12; i++) {
row.insertCell(i);
}
//Add Txt
row.insertCell(1).innerHTML = "insert";
//Add drop-down list
var dd = document.createElement("select");
dd.name = "SportSelector";
dd.id = "id";
dd.options[dd.length] = new Option("Soccer", "value");
dd.options[dd.length] = new Option("Basket", "value");
dd.options[dd.length] = new Option("Hockey", "value");
row.insertCell(0).appendChild(dd);
//Done
}
I will need to study this. looks like my code was a little long. But of course I solve one problem and I get 10 more :) lol
I'm not sure if it considered polite to ask for a follow up question here as question is solved.
However I feel my next question is closely related to the first one. As my code will add a ton of these drop-downs in the end. I would need somehow to "find" the drop-down again with my next js function.
How would it be possible to add a code that "catches" which drop-down i edit and return a popup msg or something ?
frederik
For adding row you can do something like this
function myFunction2() {
var table = document.getElementById("Table1");
var row = table.insertRow(table.length);
var dropDownHtml = "<select><option>A</option><option>B</option><option>C</option></select>";
var cell;
for (i = 0; i <= 10; i++) {
cell = row.insertCell(i);
if (i == 0 || i == 10 || (i >= 3 && i <= 7)) {
cell.innerHTML = dropDownHtml;
}
}
}
FYI : You can add/remove row at starting my using index 0 and at the end by using index as -1 for insertRow()/deleteRow()
You can modify your delete row function as follows
function myDeleteFunction() {
var x = document.getElementById('Table1').rows.length;
x = (x - 1); //do you want to not allow header to be removed or what ?
if (x >= 1) {
document.getElementById("Table1").deleteRow(x);
}
}

JS increase index number array by function

I trying to make a small text based rpg game, but I came across array in js and then I came to problems, I failing to increase the index number by using i instead of 0 like myArray[i]
I made a jsfiddle so you guys can see what I mean.
jsfiddle
When you press the button til you get a warming, it should increase the i to 2, but it don't, but still comes with warming and increasing the attack variable.
This is your attackUp function:
function attackUp(){
var i = 0;
var attackCost = xpforlevel[i];
if (attackCost < attackxp) {
alert("WARMING!");
attack++;
document.getElementById('attack').innerHTML = attack;
i++;
document.getElementById('i').innerHTML = i;
}
}
Notice that your var i = 0 statement doesn't really make sense (because everytime attackUp is called, i will be reset to = 0 at the beginning). To fix that, erase this var i = 0 statement from your function and put in the beginning of your JS code:
var i = 0;
var attackxp = 0;
var attack = 1;
Further, your function will only update i if attackCost < attackxp, otherwise it will change nothing. You need to put the i++; statement outside your if-block, like this:
function attackUp(){
//erase this line: var i = 0;
var attackCost = xpforlevel[i];
i++; //added this line
if (attackCost < attackxp) {
alert("WARMING!");
attack++;
document.getElementById('attack').innerHTML = attack;
//erase this line: i++;
document.getElementById('i').innerHTML = i;
}
}
As your i is a local variable, it is initiated as 0 every time you call attackUp(). You should put it besides attackxp and attack.
For more information about the scope of variable in JavaScript, see w3schools or this question.

Element accessible with ID

I saw a strange behavior.
I created a Input.
<input id='inputid' value='value'/>​
and tried to access it directly from id. Instead of throwing an exception console was showing above input element.
console.log(inputid);
After that I tried to compare it with getElementById
console.log( inputid == document.getElementById('inputid'));
console was showing true.
You can see this behavior on jsfiddle.
Is it a strange behavior or am I missing something?
I tested it in Chrome 23.0.1271.10 dev-m and firefox 15.0.1.
Back in the days of 4.0 browsers, Microsoft decided that it would be convenient to create, for every element with an id, a global variable with the same name as the id containing a reference to that element.
Support for this has appeared in some other browsers (in some rendering modes). This support is not universal so the feature should be avoided.
To just expand a little on this situation based on a curiosity:
<html><head>
<script type="text/javascript">
var overWrite = "world";
window.onload = function(){ alert(overWrite); };
</script></head><body>
<input id="overWrite" value="hello" />
</body></html>
Will alert "world". However, with //var overWrite = "world"; (as in with that line commented out), it will alert the [html element]. Note that this is after the page loads so it is persistent and not some sort of temporary assignment.
Strongly agree that it should not be used due to inconsistency and readability issues.
EDIT
Still was curious about this issue and did some more testing. I was curious if access was faster with document.getElementById or by variable reference. Made this test:
html
<div id="contentZone"></div>
js
var startTime = Date.now();
for( var i = 0; i < 1000; i++){
for( var n = 0; n < 2000; n++){
var ni = document.getElementById("contentZone");
}
}
var endTime = Date.now();
console.log( endTime - startTime );
var aTime = Date.now();
for( var i = 0; i < 1000; i++){
for( var n = 0; n < 2000; n++){
var ni = contentZone;
}
}
var bTime = Date.now();
console.log( bTime - aTime );
console
431
814
Tested on this machine only, but it would seem that using document.getElementById is still faster making this variable access even less desirable.

how to get the actual box bigger than the others?

i'm new to javascript and i'm having a problem. I want the actual (function updateBoxes) box [boxIx] to be bigger than the other ones but i can't seem to find a code that works. i've tried box[boxIx].size ="100px"; box[boxIx].style.size ="100px"; without result. This is my code;
function init() {
box = document.getElementById("boxes").getElementsByTagName("div");
for (var i=0; i<box.length; i++) {
box[i].style.left = 70*i+"px";
} // End for
boxIx = box.length - 8;
updateBoxes();
} // End init
function browseLeft() {
if (boxIx > 0) boxIx = boxIx - 1;
updateBoxes();
}
// End browseLeft
function browseRight() {
if (boxIx < box.length-1) boxIx = boxIx + 1;
updateBoxes();}
// End browseRight
**function updateBoxes() {
box[boxIx].style.backgroundColor ="#CCC";
box[boxIx].style.top = "20px";
box[boxIx].style.zIndex = 9;**
var z = 8;
for (var i=boxIx-1; i>=0; i--) {
box[i].style.backgroundColor ="#666";
box[i].style.top = "0px";
box[i].style.zIndex = z;
z = z - 1;
} // End for
z = 8;
for (var i=boxIx+1; i<box.length; i++) {
box[i].style.backgroundColor = "#666";
box[i].style.top = "0px";
box[i].style.zIndex = z;
z = z - 1;
} // End for
} // End browseLeft
As thirtydot pointed out, you have two instances of "**" in your sample code that I've removed in the assumption that this is a markdown glitch when editing.
Your example shows only the JavaScript code. The HTML markup and CSS styling you're using would be most helpful. I've created a fiddle for discussion and to resolve this for you here: http://jsfiddle.net/bhofmann/zkZMD/
A few things I noticed that might be helpful:
You're using a magic number 8 in a few places. Can we assume this is the number of boxes? I would store that in a variable for use in the functions.
You used a lot of direct styling. Your code might be cleaner if you used CSS classes to alter the appearance of the boxes.
Unless you're altering the default styling of DIV, you won't see much change by simply setting the left offset.
PS. I took the liberty of invoking the init function on page load because I saw nothing else to invoke it. I don't know what would invoke browseLeft and browseRight but I'll leave that to you.

Categories

Resources