Say I have a number in a div:
<div id="value">100</div>
And I have this javascript acting on it:
function animateValue(id){
var obj = document.getElementById(id);
var current = obj.innerHTML;
setInterval(function(){
current++;
},1000);
}
animateValue(value);
To my understanding, this script translates to:
• Grab the HTML element called (in this case) "value" and store it in "obj"
• Take the inner html from obj and store it in "current"
• Take the "current" variable and increment it every second
It was supposed to take the content of #value and increment it up by one every second, but instead it does nothing. How do I solve this? What have I done wrong? As you can tell, I am not experienced in javascript, so go easy on me.
You changed the current number but never updated the innerHTML of the obj, which is what is actually displayed. If you set obj.innerHTML = current; right after current++ it should do something for you.
And change animateValue(value); to animateValue('value'); (thanks, #nevermind)
I'm not sure if you wanted to update the contents of the DIV. Maybe this is what you wanted?
function animateValue(id){
var obj = document.getElementById(id);
var current = parseInt(obj.innerHTML);
setInterval(function(){
current++;
// Update the contents of the element
obj.innerHTML = current;
},1000);
}
animateValue('value');
http://jsfiddle.net/L1q5t9gz/
Use jQuery. It's easier... The other answers are more complex, this is an easy one.. No parse or something like that.... Simpler code, more effective.
So, It's more simple than you think: First... check the current value, then add and print
$(function(){
//Get Current HTML
var currentValue = $("#value").html();
//do this every 1000 ms (1 second)
setInterval(function(){
//add the value to the current
var newValue = currentValue++
// print the new value
$("#value").html(newValue);
},1000)
})
Here is the JSFiddle example solving your problem: http://jsfiddle.net/rszczypka/f5jfn5bo/
the html part:
<div id="value">100</div>
the javascript part:
function animateValue(id){
var obj = document.getElementById(id);
var current = parseInt(obj.innerHTML);
setInterval(function(){
obj.innerHTML = current++;
},1000);
}
animateValue('value');
Related
I'm struggling understanding some basics concept I guess,
I have this JavaScript function which take a dom element and should increase it's number every time the button is clicked, the thing is, the number increase once and never increase again, console.log show the actual number but not the stPage element. From my understanding it has to deal with the DOM element stored, so I have to kill the first child, I think I did so, but it doesn't seems to work.
If some can help me, please do, thank you really much <3
function stpage(){
//Setting child element + simple increment function
let numberNode = document.getElementById('stPage');
let articleNumber = 0;
articleNumber++;
//killing the child then display the element on the page
numberNode.removeChild(numberNode.childNodes[0]);
document.querySelector('#stPage').innerHTML = articleNumber;
};
Edit: articleNumber has to be outside the function scope.
let articleNumber = 0;
function stpage(){
articleNumber++;
document.querySelector('#stPage').innerHTML = articleNumber;
};
You are re-initializing articleNumber to 0 every time the function is called on this line:
let articleNumber = 0;
It should be something like:
let articleNumber = 0; // outside function scope, doesn't reset
function stpage() {
let numberNode = document.getElementById('stPage');
articleNumber++;
numberNode.innerHTML = articleNumber;
};
I added dynamic images display in specific div but I could not set link (a href)for each image individually.Could you help me?
Here is my script which I used but not working:
<script>
var i;
var timerid = 0;
var images = ["img1.jpg",
"img2.jpg",
"img3.jpg","img4.jpg"];
var countimages = 0;
function startTime()
{
if(timerid)
{
timerid = 0;
}
var tDate = new Date();
if(countimages == images.length)
{
countimages = 0;
}
if(tDate.getSeconds() % 4 == 0)
{
document.getElementById("img1").src = images[countimages];
}
countimages++;
timerid = setTimeout("startTime()", 800);
switch(countimages){
case images[0]: images[0].setAttribute('href',"dhow-cruise-creek-dubai.html");
images[0].innerHTML="dhow-cruise-creek-dubai.html";
document.appendChild(images[0]);
break;
case images[1]: images[1].setAttribute('href',"dhow-cruise-creek-dubai.html");
images[1].innerHTML="dhow-cruise-creek-dubai.html";
document.appendChild(images[1]);
break;
case images[2]: images[2].setAttribute('href',"dhow-cruise-creek-dubai.html");
images[2].innerHTML="dhow-cruise-creek-dubai.html";
document.appendChild(images[2]);
}
}
</script>
Several things here:
1: Your function is incrementing an array index (countimages) and wrapping it when it reaches the end of the index range of the array it is intended to subscript (images). You currently have two lines of code to accomplish this task, which are separated by another line of code. The two lines are
countimages++;
which is executed immediately after the subscripting of the aforementioned array, and
if (countimages == images.length) countimages = 0;
which is executed just before.
It would be much better, both for human readability and for code simplicity, to locate these two operations at the same spot in the code, because together they represent a single isolated and inseparable action. Also, the length cap can be applied more idiomatically and concisely using a modulus operation. The end result is you should delete the second line I showed above, and change the first to this:
countimages = (countimages+1)%images.length;
2: You are incrementing countimages in every evaluation of the function. This is happening even when the modulus test fails, and therefore the image is not changed. I suspect this is a mistake. Therefore I would change
if (tDate.getSeconds()%4 == 0) {
document.getElementById("img1").src = images[countimages];
}
countimages = (countimages+1)%images.length;
to
if (tDate.getSeconds()%4 == 0) {
document.getElementById("img1").src = images[countimages];
countimages = (countimages+1)%images.length;
}
3: I don't see any point in zeroing the timerid variable at the start of the function. It will inevitably be overwritten by the return value of the setTimeout() call later in the function. So the statement
if (timerid) timerid = 0;
should be removed.
4: The setTimeout() function supports two overloads. The first argument to the function can be either a function reference or a string of code. The former is preferable, both for performance and security reasons. So you should change
timerid = setTimeout('startTime()',800);
to
timerid = setTimeout(startTime,800);
But see below.
5: The setInterval() function is preferable to setTimeout() for a continuously repeating function call. Under this design, the function does not even need to reference timerid, or concern itself with its own invocation. We can just call setInterval() once during page load to start the chain of calls.
6: The switch statement at the end of the function is switching on countimages, which is of numeric type, against various elements of the images array specified by literal index, i.e. images[0], images[1], and images[2]. The images array holds string values representing image URLs, not numbers. So obviously this switch statement is incorrect. Also, the final element (images[3]) is omitted, which may be a mistake. If your intention was to switch on the indexes of the array, your case values should be 0, 1, etc. But see below.
7: Each of the case branches in the switch statement is identical to the others, except for the literal index. That is, they all follow this pattern, where i is the literal index:
case images[i]:
images[i].setAttribute('href','dhow-cruise-creek-dubai.html');
images[i].innerHTML = 'dhow-cruise-creek-dubai.html';
document.appendChild(images[i]);
break;
except that the final break; statement is missing from the final case branch.
This is an example of duplicate code that should be simplified by proper parameterization; in this case, parameterizing on i. Observe that the literal index always corresponds to the current value of countimages, so that is our i. In other words, the entire switch statement can be replaced with the following, again, assuming you wanted to switch on the indexes of the array:
images[countimages].setAttribute('href','dhow-cruise-creek-dubai.html');
images[countimages].innerHTML = 'dhow-cruise-creek-dubai.html';
document.appendChild(images[countimages]);
But see below.
8: The above lines of code are incorrect because they appear to be treating images as an array of elements, when it is in fact an array of strings. You cannot call setAttribute() on a string, nor is there a meaningful innerHTML property of strings, and you cannot append strings to the DOM tree using appendChild() (because strings do not implement the interface Node).
This brings us to your question. Your code seems to be trying to append a new anchor link element at the bottom of the entire document every time the image is advanced, but I doubt that's what you really want. I'm guessing you want to advance a single fixed anchor link element to a new href attribute and innerHTML content corresponding to the new image. To do this, I would recommend you change the array of strings to an array of hashes and store the href and innerHTML alongside the image URL using three key/value pairs.
9: The design of advancing the image and link during every multiple of 4 seconds, but checking for such a condition every 800 milliseconds, is very questionable. In some cases the check will be true twice in a multiple-of-4 second, in some cases it will be true only once during the multiple-of-4 second. And the moments the function is executed will drift, since the interval duration is not guaranteed to be exact. This would lead to some strange behavior. I suppose you may want this behavior, but I'm doubtful. Instead, I suspect what you're going for is for the image and link to advance once every 4 seconds. You can achieve this by removing the entire time test and just setting the interval to 4 seconds, that is, 4000 milliseconds.
Hence, we have:
var imageSpecs = [
{imageURL:'https://www.gravatar.com/avatar/8062178f34c7107a67ef00b681921287?s=328&d=identicon&r=PG&f=1',linkRef:'#1',innerHTML:'one' },
{imageURL:'https://www.gravatar.com/avatar/b57bf879dbb25c837c2e2ae730cab2cc?s=328&d=identicon&r=PG&f=1',linkRef:'#2',innerHTML:'two' },
{imageURL:'https://www.gravatar.com/avatar/166ed38dafa219c53980bb06cfce40b6?s=328&d=identicon&r=PG&f=1',linkRef:'#3',innerHTML:'three'},
{imageURL:'https://www.gravatar.com/avatar/0c8ea1549ebeff7bab9a282c4b965fa4?s=328&d=identicon&r=PG', linkRef:'#4',innerHTML:'four' },
];
// preload all images
for (let imageSpec in imageSpecs) {
let img = new Image();
img.src = imageSpec.imageURL;
} // end for
var nextImageSpecIndex = 0;
function advanceImageSpec() {
let imageSpec = imageSpecs[nextImageSpecIndex];
let imgElem = document.getElementById('img1');
imgElem.setAttribute('src',imageSpec.imageURL);
let linkElem = document.getElementById('link1');
linkElem.setAttribute('href',imageSpec.linkRef);
linkElem.innerHTML = imageSpec.innerHTML;
nextImageSpecIndex = (nextImageSpecIndex+1)%imageSpecs.length;
} // end advanceImageSpec()
var timerId = setInterval(advanceImageSpec,4000);
advanceImageSpec(); // immediate call to display first image immediately
#img1 { width:100px; height:100px; }
<div>
<img id="img1"/><br/>
<a id="link1"></a>
</div>
I'm not really sure what you're trying to do, but I assume you want the image to be a link that goes somewhere. Try putting a link tag around the img element with id img1 and giving that link tag the id `link1' like so:
<img id="img1"/>
Then change the script to this:
<script>
var i;
var timerid = 0;
var images = ["img1.jpg",
"img2.jpg",
"img3.jpg"];
var links = ["dhow-cruise-creek-dubai.html",
"dhow-cruise-creek-dubai.html",
"dhow-cruise-creek-dubai.html"];
var countimages = 0;
function startTime()
{
if(timerid)
{
timerid = 0;
}
var tDate = new Date();
if(countimages == images.length)
{
countimages = 0;
}
if(tDate.getSeconds() % 4 == 0)
{
document.getElementById("link1").href = links[countimages];
document.getElementById("img1").src = images[countimages];
}
countimages++;
timerid = setTimeout("startTime()", 800);
}
</script>
There's more that could be improved, but I'm sure you get where I'm going.
There is a code that I found in one of the answers on this website. I would like to know if that code can be written in simple JS or not? Also, if someone can help me understand it in terms of simple Javascript I would really appreciate your help.
The code is to fix the time lost during changing of tabs in chrome for timing functions like setTimeout and setInterval.
The code goes like this -
var div = $('div');
var a = 0;
var delay = (1000 / 30);
var now, before = new Date();
setInterval(function() {
now = new Date();
var elapsedTime = (now.getTime() - before.getTime());
if(elapsedTime > delay)
//Recover the motion lost while inactive.
a += Math.floor(elapsedTime/delay);
else
a++;
div.css("left", a);
before = new Date();
}, delay);
Please note that I am a newbie to this site and therefore with my current reputation I cannot comment on that answer of the question I am referring to.
There are two jquery calls in the OP's question:
$('div')
div.css("left", a)
The first:
$('div') -> [].slice.call(document.querySelectorAll('div'))
Return a collection of matched elements either found in the DOM based on passed argument(s) - jQuery docs
It returns a collection (array) of elements matched by the selector 'div'. That means all div elements on the page.
Lets strip down the plain javascript part:
document.querySelectorAll('div') select all elements on the document with selector 'div'. The problem here is that querySelectorAll returns a NodeList, not an array. It's an array-like object.
[].slice returns a shallow copy of a portion of an array - MDN
It can take an array like object (e.g. the result of querySelectorAll). The result is an actual array
At this point var div contains an array of all div elements on the page.
The second
div.css("left", a)-> div.forEach(function (item) {item.style.left = a + 'px';})
set one or more CSS properties for every matched element - jQuery Docs
It sets a style attribute to an jQuery element. In this case, it sets the css left property to a. a is a number, jQuery appends 'px' to that number to make it a string.
Lets strip down the plain javascript part:
div.forEach() Loop over the div variable, which is now an array. For every item in the array, execute the following function:
function (item) { item.style.left = a + 'px'; } This function takes a parameter (item). This is the a dom element, which is stored in the div array. Every dom element has a styles object with css properties. This function takes the a variable (a number) concats 'px' to it and sets that to the left property.
So basically, this function loops over every item in the div array and sets the styles.left property to the a value.
The complete code would be:
var div = [].slice.call(document.querySelectorAll('div'));
var a = 0;
var delay = (1000 / 30);
var now, before = new Date();
setInterval(function() {
now = new Date();
var elapsedTime = (now.getTime() - before.getTime());
if(elapsedTime > delay)
//Recover the motion lost while inactive.
a += Math.floor(elapsedTime/delay);
else
a++;
div.forEach(function (item) {
item.style.left = a + 'px';
})
before = new Date();
}, delay);
Can't I use getElementById twice in javascript file? I want to use it twice because, I want to set a default value to the element with that particular id and then on calling a function i need to change the default value. Can I do this?
Have a look at my code:
function DefaultValue(){
var default = 10.23
var update = document.getElementById('idSpnRWA');
update.innerHTML = default;
}
function setValue(){
var set = 23.56;
var finalUpdate = document.getElementById('idSpnRWA');
finalUpdate.innerHTML = set;
}
I have given a very basic code to make you understand if this way is possible?
In short: yes, you can call getElementById as many times as you want.
Please note however, that default is a reserved word in JavaScript.
Also, you're forgetting to add ; after each line.
Try this (note I renamed the default variable, and added ; where needed.
HTML
<div id="idSpnRWA"></div>
JavaScript
function DefaultValue() {
var dflt = 10.23;
var update = document.getElementById('idSpnRWA');
update.innerHTML = dflt;
}
function setValue() {
var set = 23.56;
var finalUpdate = document.getElementById('idSpnRWA');
finalUpdate.innerHTML = set;
}
DefaultValue();
setValue();
Working Fiddle: http://jsfiddle.net/9e75vnm3/
Of course you can use document.getElementById many times.
But element with a specific id can be only once at your page.
Yes you can use getElementById as many time as you want.
Problem in your code is that you are adding inner html as 10.23% which is not allowed. '%' is consider as a modulo operator. if you want to display in html than you have to concat it as string
function DefaultValue() {
var update = document.getElementById('idSpnRWA');
update.innerHTML = 10.23 + '%';
}
function setValue() {
var finalUpdate = document.getElementById('idSpnRWA');
finalUpdate.innerHTML = 23.56 + '%';
}
DefaultValue();
<div id='idSpnRWA'></div>
You cannot have the same HTML id attribute more than once on a page, but you can get anything as many times as you want, as long as it's not undefined. Of course, this means you can call document.getElementById('idSpnRWA') as many times as you want. You'll want to put percentages in quotes when assigning to .innerHTML, as % is the modulo operator. Better yet, use HTML entities. Element.innerHTML = '10.23%';
thank you so much for answering my question. I finally found the solution. it is,
update.value= default;
finalUpdate.value = set;
innerHTML can't be used there. If i use .value, the code is actually working fine.
I have the following script where a variable gets its value from an input field, however when I run my function its not working, returns nothing. Im new to JS so im unsure if it needs to be part of a function *even though Ive tried this with no luck) or what...
/////////////////////////////////////////////////////////////////////
// Variables
// Content/SLA
var ContentMinutes = '';
var ContentMinutesSelector; // Switch Case
var ServiceLevel = 5;
var NoOfFrames = 2;
// Render Time (Hairier the Better)
var AvgFrameRenderTime = '';
var AvgFrameRenderTimeSelector = 10; // Switch Case
var CoresInTest = document.getElementById('CoresInTest').value;
// Other
var EstimatedCoreHours = NoOfFrames * CoresInTest * AvgFrameRenderTimeSelector;
// Cost Estimate
var CostEstimate = ServiceLevel * EstimatedCoreHours;
/////////////////////////////////////////////////////////////////////
// Functions
function CalculateEstimate() {
// Estimate Cost
parseInt(document.getElementById("PriceEstimate").innerHTML=CostEstimate.toFixed(2));
// Estimate Core Hours
parseInt(document.getElementById("EstimatedCoreHours").innerHTML=EstimatedCoreHours.toFixed( 2));
}
my PriceEstimate and EstimatedCoreHours fields are both just empty divs, <div id="EstimatedCoreHours"></div>, My calculations work if i define a value for the variable as opposed to document.getElementById so I believe I must need to run a function or something to update all the vartiables?
But if I set...
var CoresInTest = document.getElementById('CoresInTest').value;
to
var CoresInTest = 10;
Then it works fine...
Its not actually my return, the problem is my variables arent calling, IF i define them with a number then it works.
I guess you need to do something like this, if you are looking to get calculated data in your div.
document.getElementById("PriceEstimate").innerHTML=parseInt(CostEstimate.toFixed(2));
// Estimate Core Hours
document.getElementById("EstimatedCoreHours").innerHTML=parseInt(EstimatedCoreHours.toFixed(2));
If var CoresInTest = 10; works fine, then your code is placed wrong.
What element is CoresInTest? is it a text field? and if so is this script placed or called before the element renders? then you will have to reinitialize that variable.
If PriceEstimate and EstimatedCoreHours are elements you should use the value property
this might work for you:
document.getElementById("PriceEstimate").value=parseInt(CostEstimate.toFixed(2),10);
document.getElementById("EstimatedCoreHours").value=parseInt(EstimatedCoreHours.toFixed(2),10);
If var CoresInTest = 10; makes it work fine, then it must be something to do with document.getElementById('CoresInTest').value - so why isn't that working? Is it a drop down list? Instead of us guessing, tell us.