Variable in Jquery not defined in javascript - javascript

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.

Related

Make variable change after a certain amount of time HTML 5/JavaScript

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>

Why Parameter Stops Function When Added

I have a code which I am trying to execute using a parameter in the function, i.e -
function startFadeEffect(elem){ };
I have made the elem equal to a variable b in the global scope, where b is an array of images. Meaning -
var elem = b[imgNumb];
imgNumb is a variable which is globally "0" and inside a function is defined as
imgNumb = imgNumb + count;
Now, my current code "without" the parameter works perfect -
function startFadeEffect(){
var opacSetting = noOpac / 10;
b[imgNumb].style.opacity = opacSetting;
b[imgNumb].style.display = "block";
noOpac++;
if(noOpac < 0){
opacSetting = 0;
}
if(opacSetting == 1){
clearTimeout(timer);
b[imgNumb].style.opacity = 1;
noOpac = 0;
return false;
}
var timer = setTimeout(startFadeEffect, 75);
}
However, when I use the parameter like this it does not work for me :(
function startFadeEffect(elem){
var opacSetting = noOpac / 10;
elem.style.opacity = opacSetting;
elem.style.display = "block";
noOpac++;
if(noOpac < 0){
opacSetting = 0;
}
if(opacSetting == 1){
clearTimeout(timer);
elem.style.opacity = 1;
noOpac = 0;
return false;
}
var timer = setTimeout(startFadeEffect(elem), 75);
}
Please note I have already defined the elem variable in the global scope of the file. Also, I am only looking for a JS solution no library like JQuery! Thanks
This part is incorrect:
setTimeout(startFadeEffect(elem), 75);
It should be:
setTimeout(function () {
startFadeEffect(elem);
}, 75);
setTimeout expects a function as it's first argument. startFadeEffect(elem) is executed immediately (and doesn't return a function). So what happens is that startFadeEffect calls itself recursively until opacSetting == 1 which breaks the recursion.

How do I change div text using array values with Javascript?

I am building a website and the homepage will basically have 2 div's containing text. I want one of the divs to change every 2 seconds with values I've placed in an array
var skills = ["text1","text2","text3","text4"];
var counter = 0;
var previousSkill = document.getElementById("myGreetingSkills");
var arraylength = skills.length - 1;
function display_skills() {
if(counter === arraylength){
counter = 0;
}
else {
counter++;
}
}
previousSkill.innerHTML = skills[counter];
setTimeout(display_skills, 2000);
innerHTML is evil, use jQuery! (assuming because you have it selected as a tag)
Working fiddle
(function($) {
$(function() {
var skills = ["text1","text2","text3","text4"],
counter = skills.length - 1,
previousSkill = $("#myGreetingSkills"),
arraylength = skills.length - 1;
function display_skills() {
if (counter === arraylength) {
counter = 0;
}
else {
counter++;
}
previousSkill.html(skills[counter]);
}
display_skills();
setInterval(function() {
display_skills();
}, 2000);
});
})(jQuery);
You need to wrap display_skills inside a function in your setTimeout() and use setInterval() instead.
var myInterval = setInterval(function(){display_skills()}, 2000);
And make sure you call previousSkill.innerHTML = skills[counter]; inside your interval'd function - else it will run just once.
You can terminate your interval with window.clearInterval(myInterval);
Use array.join().
The syntax of this function is array.join(string), where3 string is the joining character.
Example:
[1, 2, 3].join(" & ") will return "1 & 2 & 3".
Hope this helps,
Awesomeness01

Javascript Closure functions

So I'm new to javascript and I am looking for a way to count how many times a function is executed. The code randomly generates a square or circle and displays from the shape is shown to when you click it (reactionTime). That works fine and dandy.
But I'm looking for a way to keep track of the number of times a shape is clicked and then eventually the cumulative time to calculate average time per click. If it helps, I come from a pretty good C++ background.
To count number of clicks, I was thinking of adding a closure function.
From here: How do I find out how many times a function is called with javascript/jquery?
myFunction = (function(){
var count = 0;
return function(){
count++
alert( "I have been called " + count + " times");
}
})();
And from here: Function count calls
var increment = function() {
var i = 0;
return function() { return i += 1; };
};
var ob = increment();
But I tried a global variable and several variations of closure functions to no avail (look for the comments). I tried putting the closure function in other functions. And I also tried something like:
var increment = makeBox();
I'm wondering if anyone can guide me in the right direction. It would be much appreciated!
var clickedTime; var createdTime; var reactionTime;
var clicked; var avg = 0;
avg = (avg + reactionTime) / clicked;
document.getElementById("clicked").innerHTML = clicked;
document.getElementById("avg").innerHTML = avg;
function getRandomColor() {
....
}
function makeBox() { // This is the long function that makes box
createdTime = Date.now();
var time = Math.random();
time = time * 3000;
///////// var increment = function () {
var i = 0;
//return function() { return i += 1; };
i++;
return i;
///////// };
// clicked++; /////////// global variable returns NaN
// console.log(clicked);
// alert("Clicked: "+clicked);
setTimeout(function() {
if (Math.random() > 0.5) {
document.getElementById("box").style.borderRadius="75px"; }
else {
document.getElementById("box").style.borderRadius="0px"; }
var top = Math.random(); top = top * 300;
var left = Math.random(); left = left * 500;
document.getElementById("box").style.top = top+"px";
document.getElementById("box").style.left = left+"px";
document.getElementById("box").style.backgroundColor = getRandomColor();
document.getElementById("box").style.display = "block";
createdTime = Date.now();
}, time);
}
ob = increment(); //////////////////////// I think this gives me 1 every time
alert("Increment: "+ob); //////////////////
document.getElementById("box").onclick = function() {
clickedTime = Date.now();
reactionTime= (clickedTime - createdTime)/1000;
document.getElementById("time").innerHTML = reactionTime;
this.style.display = "none";
makeBox();
}
makeBox();
You have a few problems but to answer your question:
You're not defining clicked as a number (or any other type) so trying to perform an operation on undefined returns NaN...because well, it's not a number.
Your second attempt var i = 0; won't work because i is re-defined on each function call.
You should be able to use your gobal variable clicked as long as you set it to zero.
Here is an example that shows how a closure can count calls to a function:
function add5(y) {
//A totally normal function
return y + 5;
}
var counter = 0, /*a counter scoped outside of the function counter function*/
trackedAdd5 = (function (func) {
/*This anonymous function is incrementing a counter and then calling the function it is passed*/
return function () {
counter++;
/*The trick is this function returns the output of calling the passed in function (not that it is applying it by passing in the arguments)*/
return func.apply(this, arguments);
}
})(add5); /*calling this tracking function by passing the function to track*/
document.getElementById('run').addEventListener('click', function () {
/*Here we are treating this new trackedAdd5 as a normal function*/
var y = document.getElementById('y');
y.value = trackedAdd5(parseInt(y.value, 10));
/*Except the outer counter variable now represents the number of times this function has been called*/
document.getElementById('counter').value = counter;
});
<label> <code>y = </code>
<input id='y' value='0' />
<button id='run'>add5</button>
</label>
<br/>
<label><code>add5()</code> was called
<input readonly id='counter' value='0' />times</label>
makeBox.click = 0; // define the function's counter outside the function
makeBox.click++; // replace the `i` usage with this inside the function
About ob = increment();: it is used erroneously (redefines ob many times);
var ob = increment(); // define it once
ob(); // increments the counter
// another way to define `increment`:
var increment = (function () {
var i = 0;
return function () {
return i += 1;
};
})();
ob = increment(); // ob becomes 1 initially
ob = increment(); // ob becomes 2, etc.

get interval ID from else statement when set in IF

I am attempting to create a responsive slider, that will change to a simple set of dot points when in mobile mode (< 940).
The issue I am facing is in my else statement I am unable to clearintervals that were made in the if statement, because t comes up as undefined. I have resorted to using
for (var i = 1; i < 99999; i++) window.clearInterval(i); to clear the interval which works, but I don't like it because it's ugly and cumbersome, is there another way of accomplishing this?
$(document).ready(function() {
function rePosition() {
//get responsive width
var container_width = $('.container').width();
//Slider for desktops only
if(container_width >= 940) {
//get variables
var slide_width = $('.slider_container').width();
var number_of_slides = $('.slider_container .slide').length;
var slider_width = slide_width*number_of_slides;
//set element dimensions
$('.slide').width(slide_width);
$('.slider').width(slider_width);
var n = 1;
var t = 0;
$('.slider_container').hover(function() {
clearInterval(t);
}, function() {
t = setInterval(sliderLoop,6000);
});
var marginSize = i = 1;
//Called in Doc Load
function sliderLoop(trans_speed) {
if (trans_speed) {
var trans_speed = trans_speed;
}
else
{
var trans_speed = 3000;
}
if (i < number_of_slides) {
marginSize = -(slide_width * i++);
}
else
{
marginSize = i = 1;
}
$('.slider').animate({ marginLeft: marginSize }, trans_speed);
}
t = setInterval(sliderLoop,6000);
$('.items li').hover(function() {
$('.slider').stop();
clearInterval(t);
var item_numb = $(this).index();
i = item_numb;
sliderLoop(500);
}, function() {
t = setInterval(sliderLoop,6000);
});
}
else
{
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
$('.slider').stop(true, true);
$('.slider').css('margin-left', '0px');
//rearrange content
if($('.slider .slide .slide_title').length < 1) {
$('.items ul li').each(function() {
var item_numb = $(this).index();
var content = $(this).text();
$('.slider .slide:eq(' + item_numb + ')').prepend('<div class="title slide_title">' + content + '</div>')
});
}
}
}
rePosition();
$(window).resize(function() {
rePosition();
});
});
Teemu's comment is correct. I'll expand on it. Make an array available to all of the relevant code (just remember that globals are bad).
$(document).ready(function() {
var myIntervalArray = [];
Now, whenever you create an interval you will need to reference later, do this:
var t = setInterval();//etc
myIntervalArray.push(t); //or just put the interval directly in.
Then to clear them, just loop the array and clear each interval.
for (var i=0; i<myIntervalArray.length; i++)
clearInterval(myIntervalArray[i]);
}
Umm, wouldn't t only be defined when the if part ran... as far as I can tell, this is going to run and be done... the scope will be destroyed. If you need to maintain the scope across calls, you'll need to move your var statements outside of reposition(), like so:
$(document).ready(function() {
var t = 0;
...
function rePosition() { ... }
});

Categories

Resources