Setting Keyboard Focus to YouTube Embed - javascript

I’m trying to find a way to get the keyboard to focus on the YouTube player in my page. This could, for example, make it easy to use the space bar to play/pause the video.
Here’s an example: Testing Embed Keyboard Focus (CodePen)
As it is, I’m having to click on the player for it to be able to accept keyboard shortcuts. Because this is not ideal, I’m hoping for a workaround using Javascript or jQuery to set the focus on the video.
I’m aware that – as an alternative – I could use the spacebar key to call the player object's playVideo or pauseVideo methods, but that still wouldn’t get me access to the full list of the YouTube player’s keyboard controls.
And if this is simply impossible, I’ll understand. But it will be nice to know. Thanks!

You can do something like this to implement whatever hotkeys you want to enable for the player at any rate.
http://codepen.io/anon/pen/jbgeYo
Basically you create an input (can style it so that it blends in, you can't do display:none as that won't let you assign focus), and then attach a keypress event to that input. You then can call functions on the "player" API object which allows you to play/pause etc.
var dummy=document.getElementById("dummyFocus");
dummy.focus();
dummy.addEventListener("keypress",function(event){
if(event.keyCode== 32){
if(player.getPlayerState() == 1){
player.pauseVideo();
}
else{
player.playVideo();
}
}
});
Insert that after you create your player object, and add an input (I used type="button") to the page with id="dummyFocus"
Edit as needed, but that's a workaround anyway.

In order to achieve this you would have to focus() document embedded in the Youtube's iframe. This is restricted by Same-origin policy for security reasons.
Here's a piece of code for completeness
function onPlayerReady(event) {
document.querySelector('#player').contentDocument.body.focus();
}
And it would throw
Uncaught SecurityError: Failed to read the 'contentDocument' property
from 'HTMLIFrameElement':

Related

How to i stop clients using firefox's search box showing up when playing my HTML5 game with WASD?

I have a question thats semi-related to this question, except for instead of it being from the end-user perspective i need it from the content providers perspective.
I would be surprised if the mozilla foundation would have introduced this semi-intrusive feature with no way of it being disabled for selected content.
I have a web page that consists of nothing but a canvas element which is drawn to via javascript creating a game for the user to play. When a user uses the control keys (W, A, S & D) FireFox sees the user is not in some form of input box and decides they must be wanting to search for something of the page (opening the ctrl+f search box), forcing the user to lose focus on the game and their following key-presses to go unregistered. This will pose a problem for non-technical users who do not know where the setting to turn this off is, and in turn they will probably blame it on the content itself rather than it being the browser. Other than creating a input off the page that the user is force-focused to, is there a way of disabling this while FireFox users are visiting my page?
After your event is handled just terminate it.
Example:
function handleDirectionalKeys(ev) {
// .. Your WASD code
ev.preventDefault();
ev.stopPropagation(); // May not be needed, test it yourself
return false;
}
Optionally you can cancel the event when it reaches the top level of the DOM hierachy:
$(window).keypress(function(e)
{
// At this point you need to make sure that the key press
// was already handled by your code
e.preventDefault();
}

preventing clickjacking attack by javascript

Clickjacking is when people trick users into clicking a button they're not supposed to, making them perform a malicious action.
I'm working on a product which, as an option for merchants, provides an iFrame component that can be embedded into a website to make a payment. Signed in users will see a button in the iframe that they can click to perform an important action. This action should only be called when the click is genuinely theirs.
i use this code to prevent clickjacking :
if (top == self || parent != top || document.location.hostname != document.domain) { top.location.replace("https:\/\/www.mysite.com\/?404");}
can someone break into my code ?
note: i don't want to use x-frame-option
thanks
From an Iframe you cannot really control clicks from the parent, if they click inside the Iframe but another event is watching it, you cannot really prevent it being from a different domain.
But all is not lost, the Iframe itself cannot stop it, but it can be wrapped with something like this. This is assuming jquery, might be best to translate to a native version for your application, in the interest of showing an example I will use jQuery.
<div id="i_wrap"><iframe src="SRC"></iframe></div>
<script>
$('#i_wrap').on('click',function(event){
event.stopPropagation();
});
</script>
Of course this is not a cure-all, there are still ways around this. You could also use a portion of the new HTML 5 cross document messaging read here on it to do some validation and possible warn the user on an unsafe site (if your iframe gets no message, then you show no button).
Though I have no experience in the cross document messaging methods, and I am sure they probably don't allow different domains (though there may be ways around that, to an extent).
Though this question is not totally clear and I may not be understanding it perfectly, if you update your question with more details I will update my answer to suit.

Flash not responding via javascript API on IE10 on WIN8

I'm trying to achieve the following:
I have a javascript object that fetches two flash objects.
The two flash objects are then added to the page, the first one I set with play=true and
the second one I set with play=false.
I'm presenting the one with play=true right after download, and placing the other with play=false in an hidden container.
When I press the first one it interacts with my javacsript and in turn the js code
hides the first flash div container and changes the second flash (the hidden one)
div container to be shown.
With that being done I also change the play attribute of this flash from false to true so it will start playing.
The two actions, changing DOM visibility and changing the play attribute to true, are done
in two different setTimeout functions (design constraint!).
The issue I have is that on IE10 on WIN8 the flash object doesn't adhere to the play command.
To be more exact with my actions, I'm fetching the flash obj using:
var myObj = document.getElementById("MY_OBJ_ID"), and then I try to set the play to true by doing myObj.Play(); using the standard Play() method flash exposes.
Off course I check that the object exist before excuting the Play().
In addition, after I press the first flash that suppose to set all of the above in motion,
and nothing happens... If I write the same lines manually in the console:
var myObj = document.getElementById("MY_OBJ_ID");
myObj.Play();
Then the movie plays and everything works.
And I'll mention again, this happens only on IE10 on WIN8.
I'll appreciate any assistance with this issue, I'm breaking my back over this and can't figure it out.
Update - 30/06:
I think I figured out the issues somewhat, the play is not occurring indeed.
In IE 10 you can query the flash obj with flashObj.Playing attribute and I see that it's returning false.
In that case I just call the function with setTimeout and every time and check the attribute status until it's true.
But I see that this attribute is not valid in other browser, and in all browsers there's another API function - flashObj.IsPlaying().
Is there a cross-browser implementation that will let me check if a flash object is in playing state or not?
Let's say something like this:
flashObj.TGetPropertyAsNumber("/", 4) >= 1) || flashObj["IsPlaying"]()
It will check if the first frame or even more has already been played, or check if the "IsPlaying" is returning true?
Update - 01/07:
Well, the above method proved to work correctly on all browsers, so my issue is somewhat resolved.
In order to know if the flash player has loaded I need to preform the above check and if the flash isn't loaded I call the function I use to set play again with setTimeout.
But I'm still perplexed from IE10 on WIN8 behavior.
I don't understand why the flashObj.Play() works first time on all browsers first time I call it and in IE10 I need to do setTimeout for this to work.

Best way to capture all key events for a web application?

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.

Active X Control JavaScript

My coworker and I have encountered a nasty situation where we have to use an active X control to manipulate a web camera on a page.
Is it possible to assign a javascript event handler to a button in the active x control so that it would fire an action on the page when clicked, or do we have to create a button on the html page itself that manipulates the Active X Control and then can fire any necessary actions on the page?
Please just use an existing ActiveX control. Like Flash or Silverlight. Flash has built-in webcam support and is controllable via JavaScript. Silverlight doesn't have built-in camera support, but it's JavaScript integration is fantastic.
If you must write your own then fret not, it is trivial to get it to interact with JavaScript. You just have to expose the IDispatch interface.
For events, you need to learn about Connection Points.
Yes! You can throw events in C++/ActiveX land which makes the JavaScript code run an event handler function. I was even able to make an entire invisible ActiveX control (same color as page background) with no buttons or visual feedback that did all of its GUI work through JavaScript and CSS.
edit: Frank's advice is right on. Here's the link on scripting events.
My strategy was to call a C++ function called MyUpdate (which implements IConnectionPoint) when I wanted to force updates in the browser.
(Also, I made sure to pump Windows messages in the Fire_MyUpdate method because sometimes JavaScript code would call back into C++ land by calling methods on the ActiveX control; this avoids freezing up the browser and ensures that the JavaScript GUI stays responsive, e.g. for a Cancel button.)
On the browser side, the JavaScript code has the global variable referencing the object, followed by "::", followed by the method name:
function Uploader::MyUpdate()
{
// ... code to fetch the current state of various
// properties from the Uploader object and do something with it
// for example check Uploader.IsActive and show or hide an HTML div
}

Categories

Resources