Check if scroll is triggered or not - javascript

I am building a website and in this website I have an event on my mousewheel. The problem is that when you scroll your mouse on a mac (with a magic mouse) the scroll event is called so many times that at one moment the scroll function will totally freak out and isn't smooth anymore.
Does anyone know how you can tackle this problem?
I already tried to check the e.orginalEvent but it always returns DOMMouseWheel.
Also on a PC you don't have this problem and with an other mouse then the magic mouse it works great.
Thanks

Sounds like you need the debounce/throttle plugin here http://benalman.com/projects/jquery-throttle-debounce-plugin/ .
It allows you set up events to fire only after a certain period like 1 second. This way your page Isn't flooded with mousewheel events or if someone thinks clicking the submit button of a form a MILLION times will make it submit faster...

Try using something like underscore.js's throttle function.
From the documentation:
Returns a throttled version of the function, that, when invoked repeatedly, will only actually call the wrapped function at most once per every wait milliseconds. Useful for rate-limiting events that occur faster than you can keep up with.

Related

EaselJS Perfromance Issue/Frame rate drops

I am working on the project below initially stages animation works fine but after 2nd level the Frame rate drops drastically, below is the link of the game can anyone look into and help me, please!
http://fbapps.ae/mfc/game-demo/
thanks
mustafa
Currently can not get passed level 1. The _animalClicked method shows that the _questions variable is undefined, so you get wrong answers indefinitely.
I would say if you can in fact get past this, and are seeing a frame drop, then it is likely your not properly cleaning up your stage or events.
A few other notes:
Get rid of all the stage.update() calls you have everywhere. Once you call handleComplete, you no longer need to update the stage, because there is a Ticker event which updates the stage constantly. You might want to consider just adding a ticker event initially, rather than waiting for the content to load.
Note that removeEventListener can not be called with no handler argument. Unlike jQuery, this does not mean "remove all events of this type". You are using anonymous handlers, so you will have to hang on to a reference to that function, and pass it to removeEventListener instead. Alternatively, you could use removeAllEventListeners(). Looks like you do that elsewhere.

Is there any way to dynamically pause all eventListeners of an element?

I'm making the step-by-step-filled form-like page now (hope it was grammatically correct ☺ ).
The main idea here is quite simple: while step one isn't done, step two is unavailable.
I need it to be truly unavailable, not just CSS-hidden (like opacity: 0; or visibility: hidden;).
So, here is the question: in JavaScript is there any way to dynamically pause (and unpause later) all eventListeners of some element?
P.S.: Event is for example onwheel || onmousewheel.
Here is the image (sorry for cyrillic):
(It's about scoresheet-typing.)
You see the <input type="range"> element here. Mouse scrolling on it will change it's value.
The first step of a form isn't done yet; so the second one have to be unavailable, and mouse scrolling on input range element should not work.
But this time I managed to it with opacity: .3;.
So all works fine, but the picture is kinda translucent, that's all.
It is bad.
It shouldn't react on mouse wheel at all (just usual page-scrolling).
And opacity must be full (opacity: 1;).
So, we return to the initial question.
There is no way in JavaScript to even list all event listeners for an element, so to stop them is an even taller order.
In short, the answer to your question is: there's no general way to pause all event listeners.
However, there are some things you may try that could help achieve your intent.
Plan A - HTML / CSS + a little JS: If your intent is simply to prevent the events from reaching the unactivated step, you may try a hack: create a transparent "blocker" element of the exact same dimensions. When you "disable" your step, "enable" your blocker to be right on top of it - probably using absolute positioning, e.g.
// Disable step 2
step2.style.opacity = '0.3'; // could also be a CSS class toggle, or an JS animation
step2_blocker.style.display = 'block'; // make your blocker show up on top of step2
You may use HTML+CSS to create the blocker, provided you know the position/dimensions. If not, you can use JS to create the blocker at run-time after computing step2's position/dimensions.
Plan B - JS only: If for some reason, you can't change HTML or CSS and you need a JS-only solution that doesn't alter the DOM, or if you are truly trying to solve the generic problem of "How can I pause event listeners?", then you probably only have one solution - keep track of your listeners. Essentially, you will be building your own event-binding/tracking library. The API consists of on(), off(), pause(), resume().
on(HTMLElement, eventType, callback): you should push the listener callback into a registry - an array of listener objects, where listener objects contain HTMLElement and its corresponding eventType and event listener callback.
off(HTMLElement, eventType, callback): remove listener object from registry.
pause(HTMLElement, eventType, callback): find listener object from registry and set it to paused state, i.e. stop the actual listener.
resume(HTMLElement, eventType, callback): find listener object from registry and rebind the element to the event listener.
Of course, the API can be made to be flexible/smart enough to accept different number of parameters (simulate function overloading), so that pause(elem) can pause all events on the element, and pause(elem, 'click') can pause all click events on that element.
Then, rather than use addEventListener() in your code, always remember to use on() in the library you created. You may have to refactor all your event binding and listener code.
This plan is slightly elaborate, but is probably the only way to keep track of event listeners. I have done this before, so I know this really works.
P/S: You may try to take a look at the source of some popular libraries out there to see how they keep track of events. I don't think any of them has any kind of support for pause() and resume() (yet), so it'd only be for some code inspiration.
In the context of a problem, I may just addEventListener after correct passing the step one, of course.
It is not the answer though.
You can set the disabled attribute of the inputs to true initially. Then as each input is filled in and/or validated, you can set the disabled attribute of the next one to false, to make it available.
Edit: given the update to the question, this answer doesn't seem to work. Setting disabled on an <input type="range"> does not seem to prevent wheel events from firing, at least in chrome.

Event firing multiple times (or even looping) on PhoneGap - Jquerymobile app

I have an app that was developed using Phonegap and JqueryMobile.
This app has been downloaded around 15.000 times total in iOS, Android and iPhone.
The code is exactly the same on all platforms.
Once in a while the backend server overloads and when I look at the logs I see that one user is sending hundreds of times the same call. (the users are real persons and I have talk to them about the issue, so its not bot or anything like that)
For me it seems that the either the click event is looping or the server call is looping but could not detect the reason why.
This has happen to 3 users out of 15.000 (as far as I know), and the users have used the app many times before the issue happened. The issue happened on Android and iOS so it seems to me that there is an issue on the jquerymobile/javascript side.
Any idea what could have cause this issue?
I'd say first watch out for design issues in your js/DOM generation.
When you bind an event that has already been bound, jquery will bind it again without checking if that event has already been bound. That is fine if you want to attach multiple
event functions to the same event.
Any way, there are several ways to solve this. One is to unbind the event before binding it, with $.off(), eg.
$("#myDiv").off("click").on("click", function(e) {
// ...
})
another is to check inside the event function if the event has already been fired, eg:
$("#myDiv").on("click",function(e) {
if(e.handled !== true) {
alert('Clicked');
e.handled = true;
}
})
You can find more solutions with their pros and cons here
I ended up disabling the button after the first touch and that fixed the issue.
It seems that the main problem was tapping the button twice, but for some reason I could not detect after that, it entered an infinite loop.
do you do event.preventDefault() and event.stopPropagation() in the onclick function? (without that, browsers behaviour may vary a lot)
Other thought, it may be usefull to hide or disable the buttons at the start of the onclick functions to avoid users from doing multiple clicks.
I'm sure you're already doing all this, but just in case...

What is triggering the "Tags" section of Stackoverflow?

Been looking for hours. At https://stackoverflow.com/questions/ask how does the "Tags" section make the blue boxes appear below?
I don't think they are using keyup event trigger, since the blue boxes are not being updated on every keypress.
You can test this by going to https://stackoverflow.com/questions/ask and typing:
"aadfadasdfasdfasdfasdfasfasdfsaf"
As you type, you will notice that the blue box "aadfadasdfasdfasdfasdfasfasdfsaf" will only appear a few seconds AFTER typing. Not during.
They probably call setTimeout and clearTimeout to run their code 1 second after the last keyup event.
It's just a case of autocomplete. There are many ways of accomplishing this.
One way is to store the list of words to autocomplete on the client end. This is very fast and there won't be any delay (unless you program one in).
The other way is to make an AJAX call to the server and have it return a list of autocomplete words. This is how SO does it. Since you don't want to make an ajax call every time the user types in a letter, there is a delay implemented to save bandwidth and improve performance.
If you want to implement a similar feature on your own website, I suggest looking into jQuery plugins to achieve this as there are many freely available ones out there.
EDIT: The trigger is likely a keyup event as you mentioned. However the trigger will likely wait for a second or so using setTimeout() before showing the list of possible autocompletes. clearTimeout() is used if another key has been pressed during the delay to prevent multiple calls from being made.
Check out the source code using Firebug or another web inspector. You'll see that there's a file called full.js. It's minimized, but you can expand the code using a variety of online tools; I go the very lazy approach of copying/pasting the whole thing into the "javascript" box in jsfiddle and hitting "tidy". I'm sure there are better (and faster) ways to do it.
Anyway, in that file, there are a few functions that may interest you: StackExchange.tagPreferences and it's subfunctions, initTagRenderer, and StackExchange.inlineEditing. I think the last function is the one that causes the specific delay you're referring to, but it's pretty hard to tell.

How can I reliably track mouse enter and leave events?

Various experiments I've carried out indicate that there is no foolproof way of responding to a 'mouseleave' event using jQuery. Two actions appear to not trigger any relevant event:
Moving the pointer away from an element very quickly
Moving the pointer off the element via some browser chrome (or out the the window entirely)
The second is by no means a show-stopper, but the first is a big problem. Is there a solution? Tracking document.mousemove and continually checking whether the cursor is over the target element?
i usually use hoverintent instead of hover to solve problems like this.

Categories