I’m trying to stop the throttledFunction from running unless the “fly” event listener has been emitted. But I can’t change the “this.ballhit” variable from inside the eventlistener.
I don’t know how to pass variables between functions within the component.
AFRAME.registerComponent('ballflyact', {
init: function () {
var el = this.el;
this.ballhit = '';
el.addEventListener('fly', function () {
this.ballhit = true;
});
},
tick: function (t, dt) {
if (!this.ballhit) { return; }
this.throttledFunction(); // Called once a second.
},
});
When you create a function, this becomes different.
You can use self-binding function el.addEventListener('fly', () => { // ... });
Or like var self = this; el.addEventListener('fly', function () { self.ballHit = true; });
The following works. Thank you. Now the throttle function will only run for ~10,000 milliseconds after the “fly” event, not constantly in the background.
AFRAME.registerComponent('ballflyact', {
init: function () {
var el = this.el;
this.ballhit = '';
var self = this;
el.addEventListener('fly', function () {
self.ballhit = true;
// more code
setTimeout((e)=>{
self.ballhit = '';
}, 10000)
});
},
tick: function (t, dt) {
if (!this.ballhit) { return; }
this.throttledFunction(); // Called once a second.
},
});
Related
I have a problem in regards to using .execute in Nightwatch.
When I run this code in the DOM, it works perfectly. However when I wrap it in an execute command in Nightwatch, it does not even make it to the first click. So probably the execute command is never being executed.
What am I doing wrong?
Thanks in advance
LoopThroughQuestions: function() {
this.waitForElementVisible('.next-button', constants.timeout.medium);
this.api.execute(function() {
var checkQuestion = function() {
var nextButton = document.querySelector('.next-button');
var answers = document.querySelectorAll('.flex-row.key');
answers[0].click();
nextButton.click();
setTimeout(function () {
if (document.querySelector('.next-button')) {
checkQuestion();
} else {
console.log("Exit");
}
}, 2000, "Running")
}
}, []) ;
return this;
},
You have defined the variable checkQuestion as a function, but you never call that function.
Try something like this:
LoopThroughQuestions: function() {
this.waitForElementVisible('.next-button', constants.timeout.medium);
this.api.execute(function() {
var checkQuestion = function() {
var nextButton = document.querySelector('.next-button');
var answers = document.querySelectorAll('.flex-row.key');
answers[0].click();
nextButton.click();
setTimeout(function () {
if (document.querySelector('.next-button')) {
checkQuestion();
} else {
console.log("Exit");
}
}, 2000, "Running")
checkQuestion();
}
}, []) ;
return this;
},
Recall that you can use a self invoking, anonymous function, too.
(function () {
// body of the function
}());
For people who experience the same problem; I fixed it with executeAsync, the script was being executed but the waiting on an element was insufficient
TestLoop: function() {
this.waitForElementVisible('.next-button', constants.timeout.medium);
this.api.executeAsync(function() {
let checkQuestion = function() {
let nextButton = document.querySelectorAll('.next-button');
let answers = document.getElementsByClassName('flex-row');
let blueButton = document.querySelectorAll('.blue-inverse-button').length;
answers[0].click();
nextButton[0].click();
setTimeout(() => {
if (document.querySelectorAll('.next-button')) {
console.log('Answering another question!');
checkQuestion();
}
if (blueButton === 1){
blueButton[0].click()
checkQuestion()
}
else {
console.log("Exiting?");
}
}, 2000);
};
// Initiating the check question function
return checkQuestion();
},[], function(){
console.log('Done?')
});
},
i have a problem accessing variable inside method in OOP.
this is my code :
var slideshow = {
elSet : $(".slideshow"),
next : function() {
},
swipe : function() {
var clear = this.autorun().loop;
onSwipe(function() {
clearInterval(clear); // not working
});
},
autorun : function() {
var self = this;
var loop = setInterval(function() {
self.next();
}, 5000);
},
initial : function() {
this.swipe();
this.autorun();
}
}
slideshow.initial();
i want to clearInterval from variable loop,
on browser console return error TypeError: this.loop(...) is undefined
what's wrong with my code?
Just assign the interval id returned by setInterval to a variable you can access, or like Barmar's answer return it.
var slideshow = {
elSet: $(".slideshow"),
next: function() {
},
swipe: function() {
var self = this;
onSwipe(function() {
//use the interval id to cancel
clearInterval(self.intervalRef);
});
},
// variable to store the interval id
intervalRef: null,
autorun: function() {
var self = this;
//assign the interval id generated by setInterval to a variable you can access
this.intervalRef = setInterval(function() {
self.next();
}, 5000);
},
initial: function() {
this.swipe();
this.autorun();
}
}
slideshow.initial();
Issues:
var clear = this.autorun().loop; Here this will have scope swipe and not object.
var loop = setInterval(function() {}) Here loop will have scope of autorun and will expire after function execution is over.
You can try something like this:
JSFiddle
function SlideShow() {
// self will hold current object reference for all functions
var self = this;
var interval = null;
function next() {
console.log('next');
}
function swipe() {
onSwipe(function() {
console.log("Clearint Interval")
clearInterval(interval);
});
}
// Private function
function onSwipe(callback) {
console.log("On Swipe");
// Check if value is passed and its a function
if (callback && typeof(callback) === 'function')
callback();
}
function loop() {
interval = setInterval(function() {
next();
}, 5000);
}
function init() {
swipe();
loop();
}
// Public properties
return {
elSet: $(".slideshow"),
next: next,
swipe: swipe,
loop: loop,
initial: init,
interval: interval
}
}
// Create a new instance of SlideShow
var slideshow = new SlideShow();
slideshow.initial();
In the swipe function, you have:
var clear = this.autorun().loop;
This expects this.autorun() to return an object, and tries to access the loop property of that object, which should contain the ID of an interval function. But autorun doesn't return anything, let alone an object with a loop property.
Change autorun to:
autorun : function() {
var self = this;
var loop = setInterval(function() {
self.next();
}, 5000);
return loop;
}
Then you can do:
var clear = this.autorun();
You also shouldn't call this.autorun() in the initial function. It's already called by this.swipe(). Running it again will cause two interval functions to run, and the ID of the second one isn't saved anywhere so that you can clear it.
In JavaScript, I have an element (which is an input tag).
This code :
element.addEventListener("focus", function () {
this.parentNode.parentNode.style.outline = this.parentNode.parentNode.dataset.ans_outline;
});
When the input is focused, outline is changed immediately.
My question is : how could I delay this event ?
I've tried :
element.addEventListener("focus", function () {
setTimeout(function(node) {
node.parentNode.parentNode.style.outline = node.parentNode.parentNode.dataset.ans_outline;
}(this), 1000)
});
.. But it doesn't work :(
try this:
element.addEventListener("focus", function () {
var node = this;
setTimeout(function() {
node.parentNode.parentNode.style.outline = node.parentNode.parentNode.dataset.ans_outline;
}, 1000)
});
First argument of setTimeout function is function you want to execute (do not call this function directly).
You can store reference to this in node variable and then use it inside your timed out function (see closures)
Remove the reference to the this and give it this way:
element.addEventListener("focus", function () {
$this = this;
setTimeout(function() {
$this.parentNode.parentNode.style.outline = $this.parentNode.parentNode.dataset.ans_outline;
}, 1000)
});
I am using the following code below and essentially it takes an element as input (i.e.):
$(#someDiv).Calculator();
but the problem is that I want to call this plugin's function within itself, but I don't know how to get an object/handle to itself to call the function. caching off "this" does not have the proper reference.
(function ($) {
jQuery.fn.Calculator = function () {
var selectedObjects = this;
var control = $(selectedObjects[0])[0];
$("#btnCalculate").click(function(){
// this is where calculate needs to be called
someObject.calculate(...);
});
return {
calculate: function (value) {
// do some code
return selectedObjects;
}
};
}
})(jQuery);
Any ideas/direction would be of great help! Thank you all!
Try
(function ($) {
jQuery.fn.Calculator = function () {
var selectedObjects = this;
var control = $(selectedObjects[0])[0];
$("#btnCalculate").click(function(){
// this is where calculate needs to be called
calculator.calculate(...);
});
var calculator = {
calculate: function (value) {
// do some code
return selectedObjects;
}
};
return calculator;
}
})(jQuery);
I have the following HTML page:
<html>
<script>
var global = {};
global.obj = {
// when called this function will cause 'hello' to be output to the
// console every 1 second
repeat: function () {
setInterval(function () {
console.log('hello');
}, 1000);
}
}
global.obj.repeat();
global.obj = [];
// even after we overwrite global.obj, 'hello'
// continues to be output to the console every second
</script>
</html>
I want to write a function similar to repeat, except when global.obj is overwritten, setInterval will stop being called
You'll want to use getters/setters, Mozilla has some good docs on this.
You may have to tweak it a bit:
var intervalRef = null;
var global = {objRef: {}};
global.__defineSetter__("obj", function(o) {
if (intervalRef)
clearInterval(intervalRef);
intervalRef = null;
global.objRef = o;
});
global.__defineGetter__("obj", function() {
return global.objRef;
});
global.obj = {
repeat: function () {
intervalRef = setInterval(function () {
console.log('hello');
}, 1000);
}
}
global.obj.repeat();
setTimeout(function() { //this just demonstrates that you can let it run for 5 secs before clearing the timer.
global.obj = [];
}, 5000);
I tested this and verified that it works.
See this Fiddle:
// html
<p id="stopper">Click</p>
// js
var counter = new Object();
counter.timer = setInterval( function(){
console.log("Hello!");
}, 1000 );
$("#stopper").click(function(){
console.log("Stopping");
clearInterval(counter.timer);
});