Loop binding to find number of loops - javascript

I could not find this in the buzz.js documentation but is there any bindings for the loop event. Something like
soundObject.bind('looping', function(e){
});
I am looking to see how many times the sound object has looped, if anyone with knowledge around this library has a workaround that would also help. I tried to bind to the ended event but that doesn't work?
EDIT:
I am thinking as a hack that i could bind to the playing event and use the getPercent() method to see when i have hit 100 and keep a counter to find number of loops?

Since there are no events that trigger with the loop option, then why not implement your own loop functionality by binding to the ended event and than calling play() again, this way you know when each play has finished.
var loopCount = 0;
var mySound = new buzz.sound("my_cool_sound").bind('ended', function () {
loopCount++;
this.play();
}).play();
Demo fiddle

Edit 1:
True. My older answer doesn't function as I thought it might :). Having read the source, they don't seem to trigger any public events. Though they do seem to bind to some private one, ended.buzzloop. I couldn't find the said event being trigger in code, but maybe it might work for you
As #koala suggested, implementing your own loop might turn out to be a better option.
Old answer - doesn't work!
I haven't used buzz.js before. Reading the docs, I found the playing & paused events.
playing
Sent when the media begins to play (either for the first time, after having been paused, or after ending and then restarting).
My idea is to listen to these two events. If playing is raised without a pause having been raised, then you can increment your count.

Related

How to stop a setInterval Loop in Javascript outside of code without refreshing the browser?

This may be a quite naive question but I really need some help.
Prior to writing this post, I was programming on JSBin. Turns out without me realizing, I ran a setInterval loop prompting for userInput and it kept on looping, making me unable to click anywhere to change the code to fix the loop. It kept on repeating and repeating. It got to the point where I had to refresh and lose all my hard-written-code (I was not logged in, so my code was not saved)! I want to avoid that next time.
So, my question is how do I stop any such kind of setInterval Loops, so that I am able to access my code and change it and re-run it. Below is a code that demonstrates my issue, if you try running it on JSBin.com (obviously, it is not the code I wrote before). As you can see, I can not click on my code to change it (or save it) in any way, which means I lose all my code!
This may seem like a useless question, but I really want to know ways to fix it and perhaps fixing it from the developer tools will help me be familiar with the overwhelming set of tools it has :P. So please help me if you know a solution.
Thank you for taking your time to help me! I appreciate it.
setInterval(demo,1);
function demo()
{
var name = prompt("Enter your name: ");
}
Another option is to search the developer tools "Elements" panel for the iframe (this should be doable even if the main document is unresponsive due to prompt's blocking) - then, just right click the iframe element and remove it, no need to type any Javascript. (or, if you want you can select the iframe with querySelector and remove it, eg document.querySelector('iframe').remove())
That's kind of a hack and should only be used in cases like the one exposed in OP but,
About all implementations use integers as timerid that just get incremented at every call.
So what you can do, is to clear all timeouts that were created on the page.
To do so you need to first get to which timerid we are, then call cleatTimeout or clearInterval (they do the same) in a loop until you reach the last call:
function stopAllTimers() {
const timerid = setTimeout(_=>{}); // first grab the current id
let i=0;
while(i < timerid) {
clearTimeout(i); // clear all
i++;
}
};
btn.onclick = stopAllTimers;
// some stoopid orphan intervals
setInterval(()=>console.log('5000'), 5000);
setInterval(()=>console.log('1000'), 1000);
setInterval(()=>console.log('3000'), 3000);
const recursive = () => {
console.log('recursive timeout');
setTimeout(recursive, 5000);
};
recursive();
<button id="btn">stop all timeouts</button>
Assuming the dev tools are closed, hit esc and f12 nearly simultaneously. This should open the dev tools. If it doesn't keep trying until it does.
Once they are open, hit esc and f8. Again, retry til it halts javascript execution at some arbitrary point in the code.
In the "sources" tab locate the generated script for what you wrote (offhand I don't know how it would look like from within JSBin) and literally delete the var name = prompt("Enter your name: "); line. Hitting f8 again will continue execution as if the "new" code is running. This should free you up to copy/paste your code from the site itself before you refresh the page

How can I hold down multiple keys with `keyboard-controls` component in A-frame

I am using the keyboard-controls component in a-frame and I notice that I am unable to hold down multiple keys at the same time.
Please see below a stripped down example using the I and J keys.
Using the following scripts
<script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
<script src="https://cdn.rawgit.com/donmccurdy/aframe-keyboard-controls/a9c513fc/dist/aframe-keyboard-controls.js"></script>
The component;
AFRAME.registerComponent('keytest', {
dependencies: ['keyboard-controls'],
init: function () {
//I Keydown
this.el.addEventListener('keydown:KeyI', (e) => {
console.log("I Key down")
});
//K Jeydown
this.el.addEventListener('keydown:KeyJ', (e) => {
console.log("J Key down")
});
},
});
And then attached to the scene
<a-scene keytest>
</a-scene>
And here is a glitch, open the console and try holding down I and J simultaneously.
The issue is that for example, while holding down I if I then also hold down J it stops hearing the I keydown and vice versa. Is this not possible? or am I doing something wrong? I know this would be possible with a normal keydown event..
To give some context if that helps, I am making a vehicle and using the keybaord controls to power it. As it is, pressing forward/backwards accelerates the car and left/right will turn the car, but as it is, as soon as I start turning in either direction, the accelerator is stopped as it no longer hears the forward keypress.
Any advice much appreciated.
This is not a bug, but a slight misunderstanding of the keydown event on your part... The keydown event behavior can best be described as what you would expect to see when typing in a word processor, or notepad. if you hold down the I key you would see an I typed and then after a small delay, rapid repetition of I. Then additionally holding down J during that would stop the Is from being typed altogether, type a J, then after another small delay, rapid repetition of J.
What you should do instead, is once a single keydown event is being fired, set an internal variable to true, maybe call it something like throttle, steeringLeft, etc... then when a keyup event is fired for that key, set it back to false. have the car maneuver based on the true/false states of those variables.

Greasemonkey, replace every occurence of string every second

i try to figure out a greasemonkey script that replaces every onmousedown on a site with an ondblclick. And i want it to constantly update, like every 1,5 Seconds, because the page refreshes using AJAX.
This is the script i came up with, but it doesn't seem to be working.
window.setInterval(document.body.innerHTML= document.body.innerHTML.replace('onmousedown','ondblclick');,1500);
The page it should work with is internal use only. But a good example would be the google search, where onmousedown is used for the links of the results to swap out the URL before you click it.
I also tried it without the semicolon after the document.body.innerHTML.replace.
I'm really new to JavaScript, but since i'm the only one in the company who can code, this one is stuck with me.
Any help would be appreciated.
Also, a small "side question"
Do i have to use #exclude, or is it enough to only use #include internal.companysite.tld* so it will only work on this site ?
A direct answer: you need to supply a function to setInterval - and it's best to set a variable so that you can later cancel it with clearInterval() if necessary.
function myF(){document.body....;}
var myIntv = setInterval(myF, 1500);
You could also do it using an anonymous function in one line as you're trying to do... do that this way:
var myIntv = setInterval(function(){document.body....;}, 1500);
I wouldn't suggest this as the solution to your problem. What it sounds like you want to do is manipulate the active DOM - not really change the UI. You likely need something like this:
var objs = document.getElementsBy__(); // ById/ByName/etc - depends on which ones you want
for (var i in objs){objs[i].ondblclick = objs[i].onmousedown;objs[i].onmousedown = undefined;} // just an example - but this should convey the basic idea
Even better, if you can use jQuery, then you'll be able to select the proper nodes more easily and manipulate the event handlers in a more manageable way:
$(".class.for.example").each(function(){this.ondblclick = this.onmousedown;this.onmousedown = undefined;}); // just an example - there are multiple ways to set and clear these

touchstart in JavaScript no longer returns TouchList

I ran into a very strange problem. I am binding the touchstart event to an element, and would like to retrieve the X and Y co-ordinates of the event. All documentation online indicates that this is available through one of the following:
e.touches
e.targetTouches
e.changedTouches
However, the following code, called on #test returns undefined for all three supposed arrays when running this from jQuery:
$('#test').bind('touchstart', function(e) {
alert(e.targetTouches);
alert(e.touches);
alert(e.changedTouches);
});
You can see a demo here > http://jsfiddle.net/c7UKV/1/ (you need to view it on a mobile device, or you can go straight to the results here > http://jsfiddle.net/c7UKV/1/embedded/result/).
My question is does anyone know of a work around, or is jQuery normalizing the event in some way that I'm not aware of? The issue exists across all versions of jQuery I tested (1.6+) and also on the iOS Simulator and on physical iDevices.
As an update to the above, calling this using vanilla JavaScript (rather than jQuery) returns the correct result. For example the following code works without a problem:
document.getElementById('test').addEventListener('touchstart', checkCoords, false);
function checkCoords(e)
{
alert(e.targetTouches);
alert(e.touches);
alert(e.changedTouches);
}
So it would appear that this is a jQuery issue, rather than anything else. You can see the above working correctly in this jsFiddle.
As described in the documentation, not every property of the original event is copied to jQuery's normalized event object.
You can still access it using originalEvent object:
$('#test').bind('touchstart', checkCoords );
function checkCoords(e){
alert(e.originalEvent.targetTouches);
alert(e.originalEvent.touches);
alert(e.originalEvent.changedTouches);
}

Javascript test results. can anyone explain them?

I was recently writing a blog post about checking if jquery elements exist before binding event handlers, I did a quick jsfiddle which you can see here
The thing I dont understand, is that the results show (using chrome to measure in microseconds) that test 2 is a lot faster then test 1.
You'll see from the jsfiddle that test 2 checks the existent of the matching before binding a click event
TEST 1 is:
console.time('time_1');
$('.yep').click(function() {
alert('clicked');
});
console.timeEnd('time_1');
test 1 just tried to bind the event
TEST 2:
console.time('time_2');
if ($('.yep').length) {
$('.yep').click(function() {
alert('clicked');
});
}
console.timeEnd('time_2');
test 2 check the element exists before binding.
I am running the two bits of code on some, 87 I think 'section' elemenets, one of which has a class of 'yep'
I cant really see why the second test is faster, as its doing more work.
results:
time_1: 0.856ms
time_2: 0.146ms
Can anyone shed some light and help out a confused developer.
thanks
n.b please dont reply with alternative ways to bind click events in jquery, the .click is just used as a simple test
The primary thing going on here is that the first time you query a selector, the engine has to do more work than subsequent queries, which can sometimes be cached. If you reverse the first two tests, you'll find that whichever one runs first tends to be the slower one.
Despite that, and mostly as a side note, in test 2 you're querying the DOM twice, first to check the length, and then to hook up the handler. If the query is cached it doesn't matter much, but still, just do it once:
console.time('time_x');
var yep = $('.yep');
if (yep.length) {
yep.click(function() {
alert('clicked');
});
}
console.timeEnd('time_x');
Note, though, that calling click on a jQuery set with no elements in it is a harmless no-op (not an error or anything), so there's no need for the length check unless you're also doing something else you haven't shown.

Categories