I have the following code that checks if there is a gyroscope available for the user to interact with. I do this in the following way:
function check_user_hardware(){
window.addEventListener("devicemotion", function(event){
if(event.rotationRate.alpha || event.rotationRate.beta || event.rotationRate.gamma){
if (!gyroscope) {
gyroscope = true;
current_interaction_mode = 'gyroscope_option';
set_user_ui_elements();
}
}else{
followMouse = true;
current_interaction_mode = 'followMouse_option';
console.log("checked for motion");
set_user_ui_elements();
window.addEventListener('mousemove', get_user_mouse_pos);
}
calculate_rotation_mesh_pos(event.rotationRate.beta, event.rotationRate.gamma);
}, function(){
console.log("generate_scene???");
generate_scene();
});
}
the problem i am having is that after this check some scene is generated.
But this scene requires a var to be set first first in the check. But the check takes to long so i added a callback after the check is completed.
But this callback never fires... Why? In other words generate_scene??? is never logged and generate_scene(); is never run.
Why is this happening? and what would be the proper way to do this?
if anything is unclear please let me know so i can clarify :)
Your problem is next: the third parameter in your .addEventListener method is function, it shouldn't be, because in documentation third parameter is Boolean if exactly "useCapture".
Try to declare generate_scene function out of check_user_hardware() and then just call it after
calculate_rotation_mesh_pos(event.rotationRate.beta,event.rotationRate.gamma);
generate_scene();
It might work.
Related
In javascript we have addEventlister, this listens to an even and calls a function called a listener function. Is an alternate approach possible where we increment the value of a "let variable" without using a function to do this in case of event being triggered?
Instead of this
let clickVar = 0;
x.addEventListener("click", RespondClick);
function RespondClick() {
clickVar++;
}
Sample Alternate implementation
x.addEventListner(click);
if (event == true){ clickVar++; }
======Edit======
Responding to the comment
The more I read this, the more it seems like an XY problem - is there something else you are trying to solve?`
In my view, the second approach is more intuitive. i.e. why create a function unless it's absolutely necessary.
Responding to the comment
There is no logic to how the second approach. The code you write will be executed once. If you want to run code more than once, you have to call a function. In order to run a function when an event happens, you need an event listener.
This simple amendment should take care of the one-time calling problem.
x.addEventListner(click);
if (event == true){ clickVar++; event=false; }
But the point I am trying to make is function could have been avoided, the code could be easy enough to speak, not only write.
Your second sample doesn't work. That simply isn't how event listeners work. You must use a callback function. If you think the first sample is too verbose, you can use an anonymous function:
let clickVar = 0;
x.addEventListener("click", function() {
clickVar++;
});
Or an arrow function in more modern versions of Javascript
x.addEventListener("click", () => {
clickVar++;
});
UPDATE turns out the code is actually working see my answer below
I'm having some troubles here. I thought I found my answer in the .one method, but apparently, .one means ONLY ONCE PER PAGE PER ANYTHING EVER which isn't exactly what I was going for. Here's what my intention was:
$("#someID").one('mouseover', function() {
//do some stuff
});
$("#someOtherID").one('mouseover', function() {
//do some stuff
});
My expectation was that once that first one fired, that mouseover event would no longer fire for THAT ELEMENT.
The problem with this is that once the first one fires, the second one will not fire either. So the .one method appears to be disabling ALL mouseover events for ALL elements after that first one fires.
I did not expect this, I expected the .one to only apply to that first element. Is this just a flaw in my understanding of the .one method or am I coding wrong?
If it's just a flaw in my understanding, could someone point me in the right direction to correct my code?
Thank you in advance!
This is embarassing, I hope I don't get dinged for this and blocked again from stackoverflow (the easiest thing ever to get blocked from and the hardest to get unblocked).
First, #CertainPerformance, thanks for taking the time to look at my question. My real code didn't have the two mistakes you mentioned, I updated my post to reflect the correct syntax.
I'll be honest, my code is working now, and I have no idea why. I suspect I've been dealing with some crazy caching issues which frustrates me because I'm using inMotionHosting which has really great reviews, and I have caching disabled in cPanel.
If anything, maybe this thread will benefit somebody searching "how to make event fire only once in javascript".
You could make the callback run once like this:
// Extend the function prototype
Function.prototype.once = function() {
// Variables
var func = this, // Current function
result;
// Returns the function
return function() {
// If function is set
if(func) {
// Executes the function
result = func.apply(this, arguments);
// Unset the function, so it will not be called again
func = null;
}
// (:
return result;
};
};
// Bind the event to the function you will use as a callback
$("#someID").on('mouseover', function() {
console.log('just once');
}.once());
I've been stuck at watching a boolean variable. On my program I am setting the value of mutexSelect "true". Whenever the value is true, makeIntoSelect function must be called like below;
(here I want to declare to watch muteSelect value continuously){
if (mutexSelect == true) {
mutexSelect = false;
makeIntoSelect(newSelectedItem);
}
});
How can I check the value of mutexSelect continuously?
Thanks!
Well this solution is like using duct tape to fix something that really needs a replacement piece. The best solution would be to trigger a message when the variable is updated. Not seeing how the varaible gets updated, I can not give you a good solution here. But MDN Docs can show you how to trigger a custom event.
So what is your only other choice? Using an interval and checking to see if it has been flipped.
window.setInterval( function(){
if (mutexSelect == true) {
mutexSelect = false;
makeIntoSelect(newSelectedItem);
}
},10)
You can use jQuery setInterval function. This function will trigger continuously at given interval so that you can place your code inside that function.
jQuery SetInterval
setInterval(function(){
if (mutexSelect == true) {
mutexSelect = false;
makeIntoSelect(newSelectedItem);
}
}, 1000);
Update the call back time as you wish to get this function to trigger more frequently. (i.e) Change the value from 1000 to your desired value.
I am trying to make a simple game using the Phaser engine, but I keep getting the above error.
var mainState = {
...
playerJump: function(){
yVelocity = -jumpPower;
},
spacePressed: function(){
if(started)
{
return;
}
started = true;
this.playerJump();
},
...
updatePlayer: function(){
if(player.body.x < game.world.centerX)
{
player.body.x += xVelocity;
}
player.body.y += yVelocity;
yVelocity += gravity;
if(player.body.y + player.body.height > floor)
{
this.playerJump();
}
},
...}
As you can see I have defined the function playerJump. All variables you see in the sample are properly defined and working. When I call the function "playerJump" from "updatePlayer" I get no error. However, if I try to call it from "spacePressed" I get the "undefined is not a function exception.
The engine I am using is Phaser and all of my code is in one file, if that makes any difference. The function "spacePressed" is invoked from a callback function when the key is pressed. The "updatePlayer" on is called from the main Update loop of the game.
Do you have any ideas why this might be happening? Why am does it work when I call it from one function but not from the other? Happy to provide more code and details if necessary.
When you use a object method as an event handler or a callback function,
this will no longer refer to the object.
The simplest way to solve this:
var mainState = { ... };
element.addEventListener(type, mainState.spacePressed.bind(mainState), false);
This method might not be supported with every browser / version so you can use this instead:
var mainState = { ... };
element.addEventListener(type, function() {
mainState.spacePressed.call(mainState);
}, false);
I assume you have created an input handler to detect if space is pressed.
This is the code to detect a mouse click on a button (for example). Just pass in "this" to the second parameter so that the callback will receive the mainState context, so that you can invoke this.playerJump()later on.
spaceButton.events.onInputDown.add(this.spacePressed,this)
will solve your problem when you call this.playerJump() inside the spacePressed() method.
I want to to check if the s.t() or page load has already been called on a site. I control when it gets called, but I want a very generic way to ask if it has already been called. The main purpose is to either call s.t() or s.tl() depending on what has previously happened.
This will return true if the SiteCatalyst code has fired.
(function(){for(w_m in window)if(w_m.substring(0,4)=='s_i_'&&window[w_m].src)if(window[w_m].src.indexOf('/b/ss/')>=0)return!0;})()
Unfortunately I do not know when this was introduced to AppMeasurement and I did not find any documentation about it but I accidentially found the following two callback functions that we use successfully to identify the moment shortly before and after the tracking request.
s.registerPreTrackCallback(function() {
console.log('Pre-Track');
});
s.registerPostTrackCallback(function() {
console.log('Post-Track');
});
This answer gives the concept behind it- before firing either function, check if the other was already fired. For example:
s.pageName="page";
s.eVar1="value";
if(!linkFired) {
var pageFired=true;
s.t();
}
if(!pageFired) {
var linkFired=true;
s.tl(this,'o','custom link');
}
I'm not sure this will actually give you any answers but you could also overwrite the s.t function with something like:
s.AltSt = s.t;
s.t = function (vo) {
s.AltSt(vo);
console.log("Do your own stuff!");
}
Haven't 100% tested this but on first observation this should work..
you could wait to see if s is called
setTimeout(function checkIfsLoad() {
if (typeof s == 'object') {
doYourStuff();
} else {
setTimeout(checkIfsLoad,150);
}
}, 150);