I`m using SWFObject for flash player on my webpage.
Player as usual has buttons like Play, Stop, Pause etc.
I need to catch moment, when my user click on any button and i need to execute some JS-function in this time.
Sorry for my english and thanks a lot in advance.
P.S. I dont have sources of my swf file.
AFAIK, this is done via the getURL() function. You need to define the following in the action script of the flash file:
this.onClick = function(){
getURL("javascript:yourFunctionName();");
};
This means you can't just take any flash file and make it call JS functions, it must be defined within the flash file itself.
If I am wrong, I'd love to hear how this can be done more generically without editing the flash itself.
Calling a javascript function from flash can also be achieved using ExternalInterface.
You can use the method onPress.
Example
[button_name].onPress = function(){
//right here the stuff you wanna do
}
Hmm...
At the risk of going out on a limb, I actually don't think there's any way, within the confines of cross-browser Javascript proper, to hook into specific Flash player activity like that. In fact I'd be very surprised indeed if there were -- although I'd love to hear otherwise from someone more knowledgeable than me. :)
Assuming that's true, other than by some combination of listening (in the Javascript running in the context of your page) for focus and click events raised by the ActiveX/plug-in object itself (which probably wouldn't be very specific or dependable -- I don't even think click events get raised ), I doubt you'd have much luck.
From what brief testing I've done so far:
window.onload = function()
{
document.onclick = function()
{
alert("Clicked the page!");
}
document.getElementById("mySWFObjectID").onfocus = function()
{
alert("Focused the player!");
}
document.getElementById("mySWFObjectID").onclick = function()
{
alert("Clicked the player!");
}
}
... the player doesn't seem to be bubbling click events up to the page; in IE, the focus event fires, but not in Firefox, and only once, when the control gains focus. So aside from writing, maybe, a browser plug-in of some kind, to get you some lower-level access than what's exposed at the Javascript level, you might be out of luck on this one.
But again, if there's anyone out there who knows otherwise...
Related
I am binding event to an element.
How to prevent new JavaScript event to be bound to it?
I want to prevent unknown scripts to play with my elements.
You cannot block an unknown script from attaching an event listener to your object. The browser does not offer that feature. The browser does block scripts that are running from other domains (other windows, tab, or frames) from messing with your DOM, but if a script is in the same domain or even in the same page, it is free to do whatever it wants to the DOM in that page.
If you have problems with unknown scripts doing bad things, then you're probably better off backing way, way up and describing what you're really trying to protect against because trying to block an event listener is like trying to keep someone out of one drawer when they're already roaming free through your house. You probably need to secure things at a much higher level.
If you want to get into the realm of "hacking" to try to block specific types of code, there are some options. These aren't foolproof if the 3rd party code wants to get around them. In other words, these would be more useful if you can see what the 3rd party code does and it won't adapt itself to try to get around you:
Firstly, you can replace elem.addEventListener() after you've installed your event handler which will prevent other code from using elem.addEventListener() on that object again.
var item = document.getElementById("test");
item.addEventListener("click", function() {
log("original event handler");
});
// install "do nothing" override method
item.oldAddEventListener = item.addEventListener;
item.addEventListener = function() {};
// this one will do nothing because addEventListener has been replaced
item.addEventListener("click", function() {
log("2nd event handler");
});
Demo: http://jsfiddle.net/jfriend00/C5rzN/
This isn't foolproof as there are other ways to still install an event handler calling the method directly from the prototype or using the onclick property.
Here's the plot, which is a True Story (a problem that exists for a real person, that is - me):
You are working on a large enterprise site, which includes a lot of JavaScript and specifically jQuery code you don't have any control of, and can't possibly change (good luck even finding out who wrote it, or why). Layers of authentication and authority are involved, so just pretend it's written in stone and you can't touch it.
Somewhere in this code, there is an event that scrolls the document to the top of the page after it has loaded. "OK, that sounds harmless" one might think - but it is now your task to scroll the page to a specific item based on a query string or anchor.
Everything works fine generally, but when you click a link that goes to example.com/list#item11, the browser works as expected and you go directly down to the item you want to link to...and then, whammo, the page instantly jumps back to the top of the page.
Now, you might say "well, that's what document.ready() is for!" ...to your horror, you find that the rogue event comes along anyway.
After Stack Overflow searching for an even later event to tie into, you find this gem:
$(document).ready(function(e) {
$(window).load(function(e){ });
}
And surely, this will definitely work! Only, it does not. You try return false and e.preventDefault(), but that does nothing for you here.
All you can be sure of is that this rogue scrolling event occurs after your code runs, after the DOM is ready, and definitely after the window.load() event. You are sure of nothing else.
Can you assassinate this rogue event? Is there some mechanism to intercept scroll events and prevent them from occurring? Can you link into some event later event, like "the DOM is ready, the window is loaded, the page is settled, the children are in bed, and all other events are done being handled.... event()`"?
The only solutions I can imagine now are "give up - scrolling behavior on page load isn't going to work in your scenario", "use a timer and wait! then commit seppuku for being such a dirty hack!", and "ninja-assassination mission!" (since I don't know who wrote the offending code, I'd have to settle for killing their code instead of them - and I'm sure they had their reasons, or have already been assassinated... or at least waiting for the code to pass and do my thing).
Is there some Better Way, some hard to find function, some last resort that invokes the arcane Dark Lords of Reflection, or is it time to give up and solve the problem another way?
TLDR;
How do you stop a disruptive scripted event - like scrolling - from occurring when you can't change the code that is causing it? Acceptable answers include how to make certain your code runs after - without using a timer hack! - and/or if your code always runs first how do you prevent the later code from messing up yours?
It might be helpful to find out how the event is defined, and what events are firing, but I feel that this is a separate question and may not necessarily be required to fix the situation. For illustration purposes, assume there are thousands of active events and listeners spread out across dozens of minified script files. It may just be so hard to narrow down what exactly is happening as to be too much trouble to even try.
The best solution will be to edit the source code where the ready event is declare.
if you can't, you can copy this code somewhere else and edit it.
if its totally not possible, then
you cannot unbind the ready event because that can cause problem.
you can override the window.scrollTop() function by its prototype
window.prototype.scrollTo2 = window.prototype.scrollTo;
window.prototype.scrollTo = function(){
/*Look in the url if you have an hash tab*/
// if yes return false
//if not
window.prototype.scrollTo2()
};
Smack them with a timer if everything else fails:
$(document).ready(function() {
window.setTimeout(function() {
document.location = "#bottom";
}, 200);
});
Live test case.
Ugly, but working.
I would hook into the window.scrollTo prototype to try and catch the burglar in the act. If you know how it's done, it's easier to get rid of it.
If this rogue call is not embedded in too huge a pile of JQuery goo, it could even allow to trace the call to the original culprit, who would soon be smitten with great vengeance and furious anger.
Buttons are slow on mobiles (at least 300ms delay in most browsers due to drag detection among other things). Google wrote some javascript to fix this:
http://code.google.com/mobile/articles/fast_buttons.html
The Mobile HTML5 Boilerplate people integrated this into their package:
https://github.com/h5bp/mobile-boilerplate/blob/master/js/mylibs/helper.js#L86
I want to figure out how I can easily use this with backbone. Something like:
events: {
"fastbutton button.save": "save"
}
Where fastbutton replaces click or mousedown with the fast button code. I expect that I will need to rewrite the MPB.fastbutton code a bit. Has anybody done this?
Instead of creating 'fastbuttons' everywhere, it's probably saner to use a library like FastClick that will transparently convert touches to click events on the touched element and get rid of that 300ms delay.
It's as easy as new FastClick(document.body) and you're ready to go.
The advantage of that approach is that if or when the behaviour of touch events changes on mobile devices so that there's no delay on elements with a click event registered, you can just change one line of code to drop the library instead of changing all your code to convert 'fastbuttons' to regular buttons. Maintainability is always good.
I'm pretty sure, this won't work the way you'd like it to. Instead of having an additional event, like say "fastclick", you have to define an element as beeing a fastButton. You actually have to create an instance of fastbutton on which you pass the element and the code like this:
new MBP.fastButton($("button.save"), function() { this.save(); }.bind(this));
In case of backbone, you can easily do this in the initialize() function instead of the events object.
// sorry, just read that you are not really looking for this :)
I'm a little distraught at the current state of key capturing for web applications. It works great as long as you know your user is going to be typing in a specific place (e.g. an input field), but as soon as you want to do global shortcuts for an entire "application", it seems to fall apart.
I'm trying to find out if there is a better way to capture all the key events for a web page than the method I am currently using.
My current method is to use the JQuery Hotkeys plugin, bound to the document element, i.e.:
$(document).bind("keyup", "delete", function() {});
That works great for most purposes, but for example on Firefox, if the user happens to absentmindedly move their mouse over the navigation bar, the delete key will sometimes result in the user going "back", and the key is never received by the handler so that I can stop propagation.
Is there a different element I should be binding to? Is there a better plugin out there for this? Should I just avoid using any keys that are bound to things in common web browsers?
As more and more web applications look to mimic their desktop counterparts, it seems like this is a basic feature that web developers will increasingly require.
EDIT: I should point out that I am already using e.stopPropagation() and e.preventDefault(). The main problem seems to be that sometimes the event is never even passed to the bound function. I am basically wondering if anyone has figured out a "higher" element to bind to other than document. Or is there an alternative I have never even thought of? Embedding an invisible Flash element on the page and then passing all keys from that to JavaScript, for example (I don't think this would work).
I think, at this point, I am doing things the "standard, well-known way." I am trying to see if there is an outside-the-box way that isn't widely known that maybe someone on Stack Overflow knows about :-).
If you are making a sophisticated web-app with customized keyboard controls, the first thing you should do is alert the user that you are making a sophisticated web-app with customized keyboard controls. After that, tell them what the controls are and what they do.
Binding the keypress and keydown listeners to the document is the correct way to do it, but you have to remember to preventDefault and/or stopPropogation for keypresses that you want to override. Even if there is no default behavior, you will need to prevent them from cascading in case the user has rebound their default keyboard shortcuts.
Also, you will only be able to receive keyboard input when the page has focus.
When you say Delete I assume you mean the Backspace key as Delete generally referrs to the key next to Insert, Home, End, Page Up and Page Down.
Edit to add:
Be very careful about which keys you choose to override. If you're making an app to be used by people other than yourself, you have to worry about usability and accessibility. Overriding the Tab, Space and Enter keys is risky, especially for people using screen-readers. Make sure to test the site blind and fix any issues that may arise with traversing the page via the keyboard.
maybe you can use html-attribute ACCESSKEY and react onfocus.
i.e.:
<input type="text" size="40" value="somefield" accesskey="F">
i think u might need to add a tabindex to tags like <div>
<div id="foo" tabindex="1" accesskey="F">
You can't bind to events that happen where you have no control - e.g. the window chrome. The way most webapps deal with this is asking the user to confirm their decision to leave the page, using the onbeforeunload event:
window.onbeforeunload = function (e) {
var str = 'Are you sure you want to leave this page?';
e = e || window.event;
if (userHasSomeUnsavedWork) {
e.returnValue = str;
return str;
}
}
onbeforeunload - MDC
Absolutly non-tested but... try it on 'window' element.
I want to find out what triggered an event. Namely, the notification bar on this site stackoverflow.com (the bar that tells you when someone has posted an answer to a question you're writing an answer on. It scrolls down slowly from the top and provides a really nice UI for user notifications. I've seen it work on just about ever page.
I imagine it working something (I need to find its name):
special_notification( message );
In the abstract, how do I go about finding out what the call (function name and arguments) looks like that generates that effect when all of the javascript is minified, and I have no idea what include provided it.
Download and install firebug in Firefox.
Go to the URL you're interested in, and open firebug. You might need to reload the page.
Now click on the little arrow icon on the top right hand side of firebug. This will let you highlight any element on the page and provide the corresponding HTML to that element.
Now that you have the id of the element, you should be able to find it in the javascript code. Even if it's minified, the name needs to correspond the DOM name.
To read minified js, you can use a tool like http://jsbeautifier.org.
Regarding your other concern, you want to listen to all the events on a page and know what triggered them and what is the code executed? is that correct?
Update:
There is no way to listen to all the events. If you really need to, you can set up listeners for every event, but you will still miss the custom events, which i guess are what you are after.
I'd suggest you inspect the code using Firebug to learn how the events are used in each case.
You can also listen to all the DOM Events, in jQuery you will do:
$('body').bind('DOMSubtreeModified', function(e){
console.log('DOMSubtreeModified triggered');
console.log(e); //Firebug console.
});
Where e will hold the event information.
Hope that makes sense.