JavaScript preventDefault also block flash scroll event in Chrome - javascript

My colleague who is responsible for Flash asks me help him block document scroll default action.
And I add the following code to help him.
<script type="text/javascript">
(function (document) {
var cancelscroll = function (e){
e.preventDefault();
};
if ('onmousewheel' in document) {
document.getElementById('container').onmousewheel = cancelscroll;
} else {
document.getElementById('container').addEventListener('DOMMouseScroll', cancelscroll, false);
}
})(document);
</script>
It works well in IE9 and Firefox, but it also blocks Flash scroll event in Chrome.
I think it is weird, the snippet should only block JavaScript event, why it also blocks Flash event.
My colleague said he registers scroll event by this snippet:
stage.addEventListener(MouseEvent.MOUSE_WHEEL, mask_wheel);
He only get the delta value in the callback, without doing other task.
I'm not familiar with Flash, and my colleague isn't familiar with JavaScript...
Anyone has this problem, too? How to fix it? Thanks.

After three days of brainstorm I finally found the solution (this problem was of utmost importance for me)
I created a small lib that helps you to take care of this "bug" in chrome browser:
Github repo
It's almost just like MouseWheelTrap, you have to call .init() function, which now requires one additional parameter - your flashObject id or name. See repo README for more info.
So here's my solution:
We listen to the scroll event in our browser and when it happens AND we have chrome browser, we call an internal function in flash which imitates user scroll (we manually dispatch an event right onto the stage) BEFORE we call event.preventDefault() function in our JS script. If we have a different browser it just calls event.preventDefault() (or returnValue = false for IE) to prevent double event lag in flash.
Cheers!

Related

document.body.addEventListener is not working

I'm working on a screen reader project and I needed to get the paragraph under the cursor. To do that in Firefox, I wrote an extension, to which my screen reader connects through sockets and gets the text. I needed to get the current element under the cursor and the function worked fine in a sample html page written by myself (So there is no problem with the function).
But when I try to attach the function to my JS file in the extension, It seems that the function which is called by "document.body.addEventListener('mouseover',myfunc(mEvent),false);" is never called.
But if I call
document.body.addEventListener('mouseover',function(mEvent){...},true);
myfunc is called.
I'm new to javascript, so excuse me if it's a stupid question, But why the
document.body.addEventListener('mouseover',function(mEvent){...},true);
is not working?
I always appreciated your nice helps and ideas. :)
While this isn't a direct answer to your question, I hope that it is helpful nevertheless. Using an extension for a screen reader is unnecessary, in particular you might not want to update that extension regularly as the browser's user interface changes. Firefox supports a number of accessibility APIs which you can use directly from your application. These APIs have the advantage of being stable, once your implementation is done it should continue working (as far as I remember there was only one occasion where Mozilla broke compatibility with existing screen readers).
As to the actual question: you didn't tell anything about the context in which this code is executing. Normally, extensions run code in their XUL overlay meaning that the context is the browser window, not the web page. Which would explain why your code isn't working (it's a XUL document, no document.body there). What you probably mean is attaching an event listener to the <tabbrowser> element where the web pages are loaded: gBrowser.addEventListener(...). Side-note: If you really wanted to catch all events on a XUL document you should register an event listener on document or document.documentElement.
Btw, you can see error messages related to extensions in the Error Console (the article I link to explains how to enable it in the current Firefox versions).
There may be other issues here, but the syntax of your addEventListener call is incorrect and could be causing the issue you are seeing:
document.body.addEventListener('mouseover',myfunc(mEvent),false); is actually invoking "myfunc" at the same time you are invoking addEventListener and passing it as the second parameter.
You should instead be calling it this way:
document.body.addEventListener('mouseover',function() { myfunc(mEvent) },false);
Add height to a body element.
<html>
<style>
.vh {
height: 100vh;
}
</style>
<body class="vh">
<script>
document.body.addEventListener('click', () => {
console.log('mouse click');
});
</script>
</body>
</html>
I suspect that the document is not yet ready, so there is nothing to bind to. Try adding an onload="addMyEventListener();" to your <body> and see if that fixes things up. I don't know the proper way to time things, so maybe someone else can chime in with the best way to handle this.
following Wladimir Palant's advise, the follow is working:
document.addEventListener('click', function() { ... }, false);
I also had the same problem and now solved it. After closing tag, try adding an document.body.addEventListener. Parser didn't recognize DOM object of the "addEventListener" event because HTML tag of DOM object is not closed.
Refer to following. It works well.
<html>
<body>
...
</body>
<script type="text/javascript">
document.body.addEventListener('click', function() { ... });
</script>
</html>

"SCRIPT28: Out of stack space" on website using IE9

I am having an issue where all link button controls on my page do not work once we deploy our website to our production server. Here are a few details:
We have 3 environments upon which we develop: Our local Machine, which uses local IIS7 to run for development; test environment which is an actual webserver behind our firewall(IIS6); Production which is our live webserver(IIS6). The website works fine on local machines and test server but once we click a link button on production server it hangs.
The problem does not exist in Chrome, or FireFox it only exists in IE9. It does not exist when you put IE9 in compatibility mode.
If I use the IE9 Developer tool bar and watch the scripts, as soon as you click one of the link buttons the console shows this error:
SCRIPT28: Out of stack space
, line 340 character 9
I am using quite a bit of JQuery and am wondering if this is causing an issue: However, I see no javascript errors.
Any thoughts?
Thanks for any suggestions.
As people said in comments: it means that infinite recursion takes place. Whether it is simple recursion or some devious path across code like a serpent biting its tail - unknown, it seems IE gives out no stacktrace, or does?
I've reproduced this issue when I'm doing the following code:
HTML
<span class="search-icon"><input title="search" type="submit" value=""></span>
JS
(function($) {
$('.search-icon').on('click', function(e) {
// The click event will call $('.search-icon').on('click', function(e) { .. } for every time
// which make an infinte loop in click event as long as there are no stop condition added here.
$(this).find('input').click();
});
})(jQuery);
I've solve this problem by changing my JS code to be:
(function($) {
$('.search-icon').on('click', function(e) {
$(this).closest('form').submit();
});
})(jQuery);
I hope this answer will be helpfull for you.
Can you post the code / a link to the code, or close this issue?
Common problems: you might have a closure problem in the html, thus different browsers interpret the html hierarchy differently, or you might be looping through a for(x in y) where x contains a backreference to y.
Check out the msdn page for info on this error. In my case, the error was caused by:
Your code triggered an event cascade.
An event cascade is caused by triggering an event that calls an event procedure that's already on the stack. ...
Basically, I was trying to trigger a click event (using jQuery) on a file upload control using the control's click event. Seems like it would cause infinite recursion. Perhaps you may be having a similar problems with your buttons.

How to ignore certain script files / lines when debugging?

I'm trying to debug some JavaScript, I want to find out what code gets executed when I hover over a certain div element (I've got no idea which bit of code, because there's no direct 'onmouseover' - I think there's a jQuery selector in place somewhere?).
Usually I'd use the "Break All" / "Break On Next" facility provided by Developer Tools / Firebug, but my problem is that other code (tickers, mouse movement listeners etc.) immediately gets caught instead.
What I'd like to do is tell the debugger to ignore certain JavaScript files or individual lines, so that it won't stop on code I'm not interested in or have ruled out. Is there any way to achieve that in IE (spit, spit!) - or could you suggest a better approach?
In FireFox this feature is called "Black boxing" and will be available with FireFox 25. It let's do exactly what you where looking for.
This feature was also introduced to Chrome (v30+) although it's tougher to find/configure. It's called "skip through sources with particular names" and Collin Miller did an excellent job in describing how to configure it.
Normally I'm for putting answers and howtos here instead of links but it would just end in me copying Collin's post.
Looks like you're looking for Visual Event.
You might want to take a look at Paul Irish's Re-Introduction to the Chrome Developer Tools, in particular the Timeline section (starts around 15 minutes into the video.)
You can start recording all javascript events - function executions (with source lines etc) and debug based on what events fired. There are other really handy debugging tools hiding in that google IO talk that can help you solve this problem as well.
If you're pretty sure it's a jQuery event handler you can try to poke around with the jQuery events.
This will overwrite all the click handlers (replace with the type you're interested in) and log out something before each event handler is called:
var elem = document.body; // replace with your div
// wrap all click events:
$.each($._data(elem).events.click, function(i, v) {
var h = v.handler;
v.handler = function() {
// or use 'alert' or something here if no Dev Tools
console.log('calling event: '+ i);
console.log('event handler src: '+ h.toString());
h.apply(h, arguments);
};
})
Then try calling the event type directly through jQuery to rule out that type:
$('#your_div').click()
You can use JavaScript Deobfuscator extension in Firefox: https://addons.mozilla.org/addon/javascript-deobfuscator/. It uses the same debugging API as Firebug but presents the results differently.
In the "Executed scripts" tab it will show you all code that is running. If some unrelated code is executing as well it is usually easy enough to skip. But you can also tweak the default filters to limit the amount of code being displayed.
If using are using IE 7.0 onwards, you should have developer toolbar from where you can debug. Just use breakpoint where you need, rest of the code will not stop.
Alternatavely you can define other applications like Interdev/ Visual Studio.net for debugging purpose too.

Browser-independant workaround for onload event -- making sense?

I have recently found myself playing around with events, and as there is no standard for the event indicating that a page has been loaded (like onload vs. pageshow) I wondered whether something speaks against simply putting some JavaScript at the end of the page. This code would then be executed when the page is loaded.
In this example I would add a keyUp listener to the (input) element identified by iText and assign it to the function updateText(event) (the event object will be passed on to this function).
<html><head></head><body>
<!-- content -->
<script type="text/javascript">
document.getElementById('iText').onkeyup = updateText;
</script>
</body>
</html>
Sample page here:
http://kb.granjow.net/JavaScript/onload.html
Tested in Firefox 3.5, Opera 10.10, IE 6, IE 8, working everywhere.
So, is this good or did I miss something?
Looking forward to your answers.
This would be fine for basic pages. However, if your script dealt with images that hadn't finished downloading or results from ajax requests you might run into trouble. If you're handcoding things, something like this should work:
function registerEvent(el, event, func, bCapture)
{
if (el.attachEvent)
el.attachEvent('on'+event, func);
else if (el.addEventListener)
el.addEventListener(event, func, bCapture);
}
Otherwise, the various JS libraries each have their own implementation such as jQuery's $(document).ready().
That sounds good. There's no reason to not do it that way, as long as your script is at the end of the page. As a matter of fact, ASP.NET uses this method to load it's scripts.

Event listeners on plugin in document.onload events in Opera

I am trying to understand an issue where event-listener registration on plugins doesn't work in Opera unless I delay them.
In particular, this doesn't work:
document.onload = function() {
plugin.addEventListener("foo", function() { alert('onFoo'); }, false);
}
while delaying the addEventListener() call somewhat through e.g. an alert() does:
document.onload = function() {
alert('onload()');
plugin.addEventListener("foo", function() { alert('onFoo'); }, false);
}
It seems that plugins are only loaded after document.onload.
As a non-web-developer, am I missing something simple here? Or is this a known Opera problem with a common work-around?
in general the timing of plugin initialisation, script execution and document event handling isn't well specified, meaning browsers are likely to do different things.
In this case it sounds like you need to make sure the plugin is initialised before you add the listener. One way to do that would be to check for a property the plugin will define (for example, if it was a Flash plugin you could check if PercentLoaded was defined to see if it is ready for scripting.) If not ready for scripting, you could use a timeout to try again a little bit later.
At Opera we've been trying to align with the majority of the other browsers in this area recently, and Opera 10.50 may be working better for you. I'm not sure if we have things fully under control yet though - it would be interesting to hear from you whether behaviour changed in 10.50.
We have further improved handling of this in Opera 10.60, so that behavior is much closer to the other browsers wrt. plug-in initialization and script readyness. I believe the original approach should work now.
I don't know much about Opera but have you tried using jquery's ready function? It's purpose is to add a function you want executed once the DOM is fully loaded and it should work cross browser.
$(document).ready(function() {
plugin.addEventListener("foo", function() { alert('onFoo'); }, false);
});
More info about the ready function can be found here

Categories

Resources