I feel like this is a pretty basic thing, but I cant seem to find the solution. Im trying to increment a value after the loading of an IFRAME.
the code looks like this:
var x=0;
$(document).ready(function() {
$('#iframe-2').load(function() {
var x=x+1;
});
$('#iframe-3').load(function() {
var x=x+1;
});
$('#iframe-4').load(function() {
var x=x+1;
});
$('#iframe-5').load(function() {
var x=x+1;
});
});
What I want to do is give a number of loaded iframes that updates when an iframe completes its loading. The output code is like this currently:
<script language="javascript">
document.write(x + " Results");
</script>
thanks a ton in advance for any help!
You should change
var x = x+1;
to
x = x+1
Because the var keyword is creating a new variable every time in your every load so global variable x is not getting updated/incremented.
You declare local variable in the load callback function, so it will not increase the global x, you could declare var x inside of dom ready callback function, and use it in load callback function.
$(document).ready(function() {
var x = 0;
$('#iframe-2').load(function() {
x++;
});
$('#iframe-3').load(function() {
x++;
});
$('#iframe-4').load(function() {
x++;
});
$('#iframe-5').load(function() {
x++;
});
});
Edit:
After this, document.write(x + " Results"); still won't work, because it executes before the iframe has been loaded. You need to do a check asynchronously.
Here is the live demo.
$(document).ready(function() {
var x = 0;
$('iframe').load(function() {
x++;
});
var time_id = setInterval(function() {
$('#count').text(x);
if (x === $('iframe').length) {
clearInterval(time_id);
}
}, 200);
});
The html:
<iframe src="http://www.w3schools.com"></iframe>
<iframe src="http://www.w3schools.com"></iframe>
<iframe src="http://www.w3schools.com"></iframe>
<iframe src="http://www.w3schools.com"></iframe>
<hr>
Loaded iframe count: <span id="count">0<span>
I finally came up with a very simple solution:
var x=0;
$(document).ready(function() {
$('#iframe-2').load(function() {
$("#t2").css("display","inline");
x++;
document.getElementById("tabs-1").innerHTML=x + " Results";
});
$('#iframe-3').load(function() {
$("#t3").css("display","inline");
x++;
document.getElementById("tabs-1").innerHTML=x + " Results";
});
$('#iframe-4').load(function() {
$("#t4").css("display","inline");
x++;
document.getElementById("tabs-1").innerHTML=x + " Results";
});
$('#iframe-5').load(function() {
$("#t5").css("display","inline");
x++;
document.getElementById("tabs-1").innerHTML=x + " Results";
});
});
Javascript has "function scope" - variables exist only within the function they were created in. So it is possible to have several different variables named x, if and only if they are in different functions (which is the case here).
Variables are created with the var keyword and accessed without a keyword. So, var x = 10; creates a variable named x, and x = 10; modifies an existing variable named x.
In your code every function calls var x = 10;. Since the previously defined x was defined in an outer function, that line is valid and created a new variable named x, scoped to the function it is being called in. If you were to omit the var statement, the interpreter would first look at the current function's namespace and not find x. Then it would move up to the global scope and find the x that you already declared, and use that.
In short, omit the word var in every line except line 1:
var x = 0;
$(document).ready(function () {
$('#iframe-2').load(function () {
x = x + 1;
});
$('#iframe-3').load(function () {
x = x + 1;
});
$('#iframe-4').load(function () {
x = x + 1;
});
$('#iframe-5').load(function () {
x = x + 1;
});
});
Another alter solution for above query using jQuery is here...
HTML:
<div id="top"></div>
<iframe src="http://jquery.com/"></iframe>
<iframe src="http://jquery.com/"></iframe>
<iframe src="http://jquery.com/"></iframe>
<iframe src="http://jquery.com/"></iframe>
<div id="bottom"></div>
JQuery:
var x = 0;
$(function() {
$('iframe:eq(0)').load(function() {
x = x + 1;
result(x);
});
$('iframe:eq(1)').load(function() {
x = x + 1;
result(x);
});
$('iframe:eq(2)').load(function() {
x = x + 1;
result(x);
});
$('iframe:eq(3)').load(function() {
x = x + 1;
result(x);
});
});
function result(x) {
if (x == null || typeof(x) == "undefined") x = 0;
$("#top").html("<div>Loaded iframe count: " + x + "</div><hr/>");
$("#bottom").html("<hr/><div>Loaded iframe count: " + x + "</div>");
}
Try on codebins too http://codebins.com/codes/home/4ldqpbk
Related
I am very new to web development so I'm sorry if I sound stupid.
I am trying to make variable change after a certain amount of time with HTML 5/JavaScript.
This is the code i was using
var myVar = setInterval(OnScreenVariables, 100);
var myVar = setInterval(Interval, 1000);
function Interval() {
if (x == 1) {
i++;
if (i > 3) {
var i = 1;
var x = 0;
}
}
}
function OnScreenVariables() {
document.getElementById("i").innerHTML = i;
document.getElementById("x").innerHTML = x;
}
<p id="x">hi</p>
<p id="i">hi</p>
<div style="backgound-color:blue;" onclick="x=1;">press me</div>
But it is not working. Could you tell me why it's not working and if there is a better way to do this.
Several problems.
https://www.w3schools.com/js/js_hoisting.asp
https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
var i and var x are being hoisted, so this:
function Interval() {
if (x == 1) {
i++;
if (i > 3) {
var i = 1;
var x = 0;
}
}
}
behaves like
function Interval() {
var i;
var x; // x is always undefined
if (x == 1) {
i++; // undefined++ = NaN
if (i > 3) {
i = 1;
x = 0;
}
}
}
And after fixing that, i and x are not declared when the script is run, so they are instead using the DOM elements with id i and x. DOMElement++ = NaN, and DOMElement.toString() is equal to a string representing the DOM element's internal name.
I would recommend using let and const (which have better scoping and less chances for unexpected behavior, and can be scoped inside for loop closures for example) instead of var, and getting in the habit of making sure you use var, let, const and plan to keep your variables deliberately scoped and declared wherever you use them.
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body>
<p id="x">hi</p>
<p id="i">hi</p>
<div style="backgound-color:blue;" onclick="x=1;">press me</div>
<script>
var myVar = setInterval(OnScreenVariables, 100);
var myVar = setInterval(Interval, 1000);
var i = 1, x = 0;
function Interval() {
console.log(i,x)
if (x == 1) {
i++;
if (i > 3) {
i = 1;
x = 0;
}
}
}
function OnScreenVariables() {
document.getElementById("i").innerHTML = i;
document.getElementById("x").innerHTML = x;
}
</script>
</body>
</html>
I have 2 pieces of code, one jQuery which checks the value of an input field and then takes this value a manipulates the CSS relatively. I have some vanilla Javascript and I was looking to use my jQuery to manipulate the JS as the jQuery is outside code block. How would I able to use the variables inside the jQuery in my vanilla Javascript?
$(document).ready(function() {
$('input').change(function() {
var val = $(this).val();
var inputNo = (10 / val);
if (val > 0) {
$(".orb").addClass("rotating");
$('.rotating').css("animation", "rotating " + inputNo + "s linear infinite");
} else {
$(".orb").removeClass("rotating");
}
console.log(inputNo);
});
});
function init() {
ctx.shadowColor = "#57e0c1";
ctx.shadowBlur = inputNo;
for (var i = 0; i <= totalTentacles - 1; i++) {
lines[lines.length] = new Line();
}
animate();
}
init();
The variable is scoped within the $('input').change function. This essentially means it disappears when the function ends. If you want it to be accessible to multiple function, you need to initialize it outside the function.
Eg.
var inputNo = 0; // declared outside function block
$(document).ready(function() {
$('input').change(function(){
var val = $(this).val();
inputNo = (10 / val);
if (val > 0) {
$(".orb").addClass("rotating");
$('.rotating').css("animation","rotating "+ inputNo +"s linear infinite");
}
else {
$(".orb").removeClass("rotating");
}
console.log(inputNo);
});
});
function init() {
ctx.shadowColor = "#57e0c1";
ctx.shadowBlur = inputNo;
for (var i = 0; i <= totalTentacles - 1; i++) {
lines[lines.length] = new Line();
}
animate();
}
init();
Note, there are deeper issues in your code however than simple variable scoping. For example, your init function will need to be called again within the change function if you want to update the shadow-blur on change as well.. so replace console.log(inputNo); with another init(); call.
I asked a question yesterday here about having a cursor that changes regularly using javascript, to make it look animated. I got a great answer (Thank you Shiva!). I've now been trying to get two different 'animated' cursors, one for the 'auto' cursor, and a different one for the 'pointer' cursor.
I tried it lots of different ways, but just can't work it out (I must admit, I'm completely new to this - trying to improve). Here's one of the ways I tried to do it:
<!DOCTYPE html>
<html>
<head>
<script type = "text/javascript">
var images = [
'assets/shared/cursors/drum1.cur',
'assets/shared/cursors/drum2.cur',
'assets/shared/cursors/drum3.cur',
'assets/shared/cursors/drum4.cur'
];
var x = 0;
function displayNextImage() {
x = (x === images.length - 1) ? 0 : x + 1;
document.body.style.cursor = 'url("' + images[x] + '"), default';
}
setInterval(displayNextImage, 250);
</script>
<script type = "text/javascript">
var images = [
'assets/shared/cursors/point1.cur',
'assets/shared/cursors/point2.cur',
'assets/shared/cursors/point3.cur',
'assets/shared/cursors/point4.cur'
];
var x = 0;
function displayNextImage() {
x = (x === images.length - 1) ? 0 : x + 1;
document.body.style.cursor:pointer = 'url("' + images[x] + '"), default';
}
setInterval(displayNextImage, 250);
</script>
<body>
<div style="height: 1000vh; width: 1000vw;"></div>
</body>
</html>
</head>
</html>
If possible I'd like to do it without jQuery.
Again, any help is really appreciated.
Thanks! :)
You can try using jQuery for this :
var images = [
'assets/shared/cursors/point1.cur',
'assets/shared/cursors/point2.cur',
'assets/shared/cursors/point3.cur',
'assets/shared/cursors/point4.cur'
];
var x = 0;
function changeLinkCursorHoverBinding(){
$("a").hover(function(){/*this is the mouseenter triggered function*/
$(this).css("cursor",'url("' + images[x] + '"), default');
}, function(){
//handle mouseleave here if needed
});
x = (x === images.length - 1) ? 0 : x + 1;//put at the end to start at 0
setTimeout(changeLinkCursorHoverBinding, 250);
}
$(document).ready(changeLinkCursorHoverBinding);//initial call of the function
EDIT
Or without jQuery :
var images = [
'assets/shared/cursors/point1.cur',
'assets/shared/cursors/point2.cur',
'assets/shared/cursors/point3.cur',
'assets/shared/cursors/point4.cur'
];
var x = 0;
function changeLinkCursorHoverBinding(){
var elems = document.querySelectorAll("a");
elems.removeEventListener("mouseenter", onHover);
elems.removeEventListener("mouseleave", offHover);
elems.addEventListener("mouseenter", onHover);
elems.addEventListener("mouseleave", offHover);
x = (x === images.length - 1) ? 0 : x+1;
setTimeout(changeLinkCursorHoverBinding, 250);
}
function onHover(){
var elems = document.querySelectorAll("a");
for(e in elems){
e.style.cursor = "url('" + images[x] + "'), default";
}//you can use the regular for loop here if you wanna
}
function offHover(){
var elems = document.querySelectorAll("a");
for(e in elems){
/*handle mouseleave here*/
}
}
I had to name EH functions (and remove EH each call) because I wasn't sure that addEventListener overrides same handler if called again.
EDIT
for non jQuery way, you need to add onload="changeLinkCursorHoverBinding()" on your <body> tag this way :
<body onload="changeLinkCursorHoverBinding()"> (the initial call after page's load).
function moveDoi(n) {
var delay = -1;
var left = document.getElementById("One");
var currentLeft = parseInt(getComputedStyle(left).left, 10);
setTimeout(move, delay);
function move(){
if (currentLeft <= n ) {
currentLeft+=3;
left.style.left = currentLeft + "px";
setTimeout(move, delay);
}
}
};
In this code I have n as a parameter of the function, that is used in the if conditional statement.
For this function i need to have one more parameter x that will change the "One" so i need to obtain something like this: document.getElementById(""+x+"") . However, this is not working?
How can I add one more parameter to the function that needs to be in quotes (" ") in function?
First, you need to pass x into the function. Then, you simply need to reference it when calling document.getElementById. There are is no need to append/prepend quotes, since x is already a string.
function moveDoi(n, x) {
var delay = -1;
var left = document.getElementById(x);
var currentLeft = parseInt(getComputedStyle(left).left, 10);
setTimeout(move, delay);
function move(){
if (currentLeft <= n ) {
currentLeft+=3;
left.style.left = currentLeft + "px";
setTimeout(move, delay);
}
}
};
A friend of mine (who is much more skilled with javascript than I am) was helping me optimise some code recently, and one of the things that he mentioned might help was to call an external function instead of using a scoped function. However, it appears that this actually doesn't appear to have much if any impact on performance. Would anyone who is more familiar with the inner workings of javascript mind explaining why this is the case? Is there any any reason to use one method over another?
What I mean is, this:
function showI(e) {
var iVal = $(e).attr('iteration');
var iValx99 = iVal * 99;
var iValx999 = iVal * 999;
alert(iVal + ' // ' + iValx99 + ' // ' + iValx999);
}
var element;
for (var i = 0; i < 50; i++) {
element = $('<div />', {
'class': 'iteration',
'iteration': i
});
element.on('click', function() {
showI(element);
});
element.appendTo('body');
}
versus:
var element;
for (var i = 0; i < 50; i++) {
(function() {
var j = i;
element = $('<div />', {
'class': 'iteration'
});
element.on('click', function() {
var iVal = j;
var iValx99 = iVal * 99;
var iValx999 = iVal * 999;
alert(iVal + ' // ' + iValx99 + ' // ' + iValx999);
});
element.appendTo('body');
})();
}
jsperf benchmark example:
http://jsperf.com/function-click-on-every-element-vs-calling-a-function/2
Well, you are throwing away the performance gains from using a static function by defining a new function everytime anyway.
What he probably meant was to use this:
element.on('click', showI ); //Just passing an already created function is cheaper than creating a new function object everytime
You don't even need to bind it 50 times:
$("body").on("click", ".iteration", showI );
And modify showI:
function showI(e) {
var iVal = $(this).attr('iteration');
var iValx99 = iVal * 99;
var iValx999 = iVal * 999;
alert(iVal + ' // ' + iValx99 + ' // ' + iValx999);
}
This is much faster in the modifed jsperf http://jsperf.com/function-click-on-every-element-vs-calling-a-function/3
jsfiddle: http://jsfiddle.net/RgU5z/
If you declare the function outside the loop, you only have to declare it once. Theoretically that would be more effecient. But within the loop now you declare an anonymous function within each iteration. That is not necessary, you can use a reference to the function: element.on('click', showI) and reference the element within showI as this (or $(this), so var iVal = $(this).attr('iteration');).