Apologize if this is answered already. Went through some of the related questions and google, but ultimately failed to see why this isn't working.
My code is as follows
<iframe id="editor"></iframe>
editorWindow = document.getElementById('editor').contentWindow;
isCtrlDown = false;
function loadEditor()
{
editorWindow.document.designMode = "on";
editorWindow.document.onkeyup = function(e) {
if (e.which == 91) isCtrlDown = false;
}
editorWindow.document.onkeydown = handleKeyDown;
}
function handleKeyDown(e)
{
if (e.which == 91) isCtrlDown = true;
if (e.which == 66 && isCtrlDown) editFont('bold');
if (e.which == 73 && isCtrlDown) editFont('italic');
}
function editFont(a,b)
{
editorWindow.document.execCommand(a,false,b);
editorWindow.focus();
}
This code works perfectly in Chrome, but the keyboard shortcuts do not work in Firefox. In fact, in Firefox it does not seem to register the events for keyup/keydown at all.
Am I doing something grossly wrong here that is mucking up Firefox?
For editable documents, you need to use addEventListener to attach key events rather than DOM0 event handler properties:
editorWindow.document.addEventListener("keydown", handleKeyDown, false);
If you care about IE 6-8, you will need to test for the existence addEventListener and add the attachEvent equivalent if it is missing.
Try using:
editorWindow = document.getElementById('editor').frameElement;
I'm not sure this will solve the issue, it may also be:
editorWindow = document.getElementById('editor').contentDocument;
Or even possibly:
editorWindow = document.getElementById('editor').frameElement.contentDocument;
One thing you can do is put the entire string in a try statement to catch any errors and see if the content is being grabbed from within the iframe.
try { editorWindow = document.getElementById('editor').contentWindow; } catch(e) { alert(e) };
The only other thought I have is that you're typing into a textbox which is within an iframe, and you may possibly have to add the onkeydown event to that specific item, such as:
var editorWindow = document.getElementById('editor').contentDocument;
var textbox = editorWindow.getElementById('my_textbox');
function loadEditor()
{
editorWindow.document.designMode = "on";
textbox.onkeydown = function(e) {
alert('hello there');
}
}
I hope one of these is the solution. I often find when it comes to cross-platform functionality it often boils down to a little trial and error.
Good Luck!
Related
I'm trying to learn Javascript before I learn jQuery so I can get the foundation down before moving up.
To learn, I've made a simple guessing game that works in Chrome & Safari, but not Firefox. (I guess that is why people use jQuery!).
I adjusted the code based on this answer. But it is still not working in Firefox. Here's the relevant code. Any ideas?
function reportAnswer(e) {
if(!e) e = window.event;
questionNumber++;
document.getElementById("myCount").innerHTML = (questionNumber + 1);
var x = e.target || e.srcElement;
checkAnswer();
}
function checkAnswer() {
var thisAnswer = questionDatabase[currentQuestion].answer;
if(event.target.id == thisAnswer) {
document.getElementById("answer").innerHTML = ("YES! </br>" + questionDatabase[currentQuestion].photo);
score++;
}
else {
document.getElementById("answer").innerHTML = ("<img src=http://philly.barstoolsports.com/files/2012/11/family-feud-x2.png width='370' height='370'>");
}
}
Your checkAnswer function uses the nonstandard global window.event. You want to do two things:
Add an event or e argument to it like #thesystem suggests.
Make sure to pass that argument in from whatever your event handler is.
I was trying to implement the CTRL+S feature for a browser based application. I made a search and came across two scripts in the following to questions
Best cross-browser method to capture CTRL+S with JQuery?
Ctrl+S preventDefault in Chrome
However, when I tried to implement it, it worked but, I still get the default browser save dialog box/window.
My Code:For shortcut.js:
shortcut.add("Ctrl+S",function() {
alert("Hi there!");
},
{
'type':'keydown',
'propagate':false,
'target':document
});
jQuery hotkeys.js:
$(document).bind('keydown', 'ctrl+s', function(e) {
e.preventDefault();
alert('Ctrl+S');
return false;
});
I believe e.preventDefault(); should do the trick, but for some reason it doesn't work. Where am I going wrong.Sorry if it is simple, still learning jJvascript.
You don't need any of those libraries, just try this:
$(document).on('keydown', function(e){
if(e.ctrlKey && e.which === 83){ // Check for the Ctrl key being pressed, and if the key = [S] (83)
console.log('Ctrl+S!');
e.preventDefault();
return false;
}
});
The problem was that your code halted at the alert(), preventing your function from interrupting the save dialogue.
(Still uses jQuery)
This is to just add a different implementation to the question used by me.
Adapted from a SO answer.Also,works for MAC
document.addEventListener("keydown", function(e) {
if (e.keyCode == 83 && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
e.preventDefault();
//your implementation or function calls
}
}, false);
People are still viewing this it seems, so it's probably worth pointing out that there is no need for jQuery on this one, here:
function keydown (event) {
var isCtrlKeyDown = navigator.platform.indexOf("Mac") > -1 ? event.metaKey : event.ctrlKey,
isSDown = (event.key && event.key === "s") || (event.keyCode || event.which) === 83 // falls back to keycode if no event.key
if (isCtrlKeyDown && isSDown) {
// prevent default event on newer browsers
if (event.preventDefault) {
event.preventDefault()
}
// ... your code here ...
// prevent default event on older browsers
return false
}
}
// register the event
if (document.addEventListener) {
document.addEventListener("keydown", keydown)
} else {
document.onkeydown = keydown
}
That should work in all browsers, this will also work for folks using alternative keyboard layouts from QWERTY on Windows, which reports incorrect key codes (at least on Chrome 56 on Windows 10 in my testing)
However, this looks kind of clunky, and confusing, so if you are only supporting modern browsers, you can do the following instead:
document.addEventListener("keydown", function keydown (event) {
if (navigator.platform === "MacIntel" ? event.metaKey : event.ctrlKey && event.key === "s") {
event.preventDefault()
// ... your code here ...
}
})
As of 2017, instead of using e.keyCode === 83 you should use e.key === 's' as the former is deprecated.
No need to use any plugin, just use below jquery code
$(document).bind('keydown', 'ctrl+s', function (e) {
if (e.ctrlKey && (e.which == 83)) {
e.preventDefault();
//Your method()
return false;
}
});
Since you are using alert, the execution halts at the alert and "return false" is not executed until you close the alertbox, thats the reason you see the default dialog.
If your method is long running better use asyn method method instead.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Keyboard shortcuts with jQuery
I want to display a popover window using a shortcut key instead of clicking the icon on the toolbar.
Do you have any good idea?
Thank you for your help.
Abody97's answer tells you how to determine if a certain key combo has been pressed. If you're not sure how to get that key combo to show the popover, this is what you need. Unfortunately, Safari makes this needlessly complicated.
In the global script, you'll need a function like the following to show a popover, given its ID and the ID of the toolbar item that should show it:
function showPopover(toolbarItemId, popoverId) {
var toolbarItem = safari.extension.toolbarItems.filter(function (button) {
return button.identifier == toolbarItemId && button.browserWindow == safari.application.activeBrowserWindow;
})[0];
var popover = safari.extension.popovers.filter(function (popover) {
return popover.identifier == popoverId;
})[0];
toolbarItem.popover = popover;
toolbarItem.showPopover();
}
You'll also need code to call this function in your global script's message listener, like the following (this sample does not assume you already have a message listener in place):
safari.application.addEventListener('message', function (e) {
if (e.name == 'Show Popover') {
showPopover(e.message.toolbarItemId, e.message.popoverId);
}
}, false);
Finally, in your injected script, the function that listens for the key combo needs to call dispatchMessage, as below:
safari.self.tab.dispatchMessage('Show Popover', {
toolbarItemId : 'my_pretty_toolbar_item',
popoverId : 'my_pretty_popover'
});
(Stick that in place of showPopUp() in Abody97's code sample.)
Note: If you only have one toolbar item and one popover (and never plan to add more), then it becomes much simpler. Assuming you've already assigned the popover to the toolbar item in Extension Builder, you can just use
safari.extension.toolbarItems[0].showPopover();
in place of the call to showPopover in the global message listener, and omit the message value in the call to dispatchMessage in the injected script.
Assuming your shortcut is Ctrl + H for instance, this should do:
var ctrlDown = false;
$(document).keydown(function(e) {
if(e.keyCode == 17) ctrlDown = true;
}).keyup(function(e) {
if(e.keyCode == 17) ctrlDown = false;
});
$(document).keydown(function(e) {
if(ctrlDown && e.keyCode == 72) showPopUp(); //72 is for h
});
Here's a reference for JavaScript keyCodes: little link.
Here's a little demo: little link. (It uses Ctrl + M to avoid browser-hotkey conflicts).
I believe this could help you: http://api.jquery.com/keypress/
In the following example, you check if "return/enter" is pressed (which has the number 13).
$("#whatever").keypress(function(event) {
if( event.which == 13 ) {
alert("Return key was pressed!");
}
});
I'm trying to disable the backspace button on an order page in all cases except when a textarea or text input is an active element to prevent users from accidentally backing out of an order. I have it working fine in most browsers, but in IE (testing in IE9, both regular and compatibility mode) it still allows the user to hit the backspace and go to the previous page.
Here's the code:
$(document).keypress(function(e){
var activeNodeName=document.activeElement.nodeName;
var activeElType=document.activeElement.type;
if (e.keyCode==8 && activeNodeName != 'INPUT' && activeNodeName != 'TEXTAREA'){
return false;
} else {
if (e.keyCode==8 && activeNodeName=='INPUT' && activeElType != 'TEXT' && activeElType != 'text'){
return false;
}
}
});
Any advice on what I'm doing wrong here?
Thanks!
I think you're overcomplicating that. Rather than checking for an active element, find the event target instead. This should give you the information you need. It's also better to use keydown rather than keypress when there is no visible character. Finally, it's better to use e.preventDefault() for better granularity.
$(document).keydown(function(e) {
var nodeName = e.target.nodeName.toLowerCase();
if (e.which === 8) {
if ((nodeName === 'input' && e.target.type === 'text') ||
nodeName === 'textarea') {
// do nothing
} else {
e.preventDefault();
}
}
});
NB I could have done this the other way round, rather than an empty if block and all the code going in the else block, but I think this is more readable.
Instead of keypress, try the keydown function, it will fire before the actual browser based hook. Also, putting in a preventDefault() function will assist in this. IE :
$(document).keydown(function(e){
e.preventDefault();
alert(e.keyCode);
});
Hope this helps.
The most Simple thing you can do is add the following one line in the very first script of you page at very first line
window.history.forward(1);
Most examples seem to be for the JQuery framework - Here an example for ExtJS
(I've been getting a lot of downvotes for this recently as the question now has JQuery tag on it, which it didn't previously. I can remove the answer if you like as isn't for JQuery but it's proven to help others not using that framework).
To use this add this code block to your code base, I recommend adding it inside the applications init function().
/**
* This disables the backspace key in all browsers by listening for it on the keydown press and completely
* preventing any actions if it is not which the event fired from is one of the extjs nodes that it should affect
*/
Ext.EventManager.on(window, 'keydown', function(e, t) {
var nodeName = e.target.nodeName.toLowerCase();
if (e.getKey() == e.BACKSPACE) {
if ((nodeName === 'input' && e.target.type === 'text') ||
nodeName === 'textarea') {
// do nothing
} else {
e.preventDefault();
}
}
});
Use e.which instead of e.keyCode; jQuery normalizes this value across browsers.
http://api.jquery.com/keydown/
To determine which key was pressed,
examine the event object that is
passed to the handler function. While
browsers use differing properties to
store this information, jQuery
normalizes the .which property so you
can reliably use it to retrieve the
key code.
Then, use e.preventDefault(); to prevent the default behaviour of moving to the previous page.
<html>
<head>
<script type="text/javascript">
function stopKey(evt) {
var evt = (evt) ? evt : ((event) ? event : null);
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
if ((evt.keyCode == 8) && (node.type!="text")) {return false;}
}
document.onkeypress = stopKey;
</script>
</head>
<body onkeydown="return stopKey()">
<form>
<input type="TEXTAREA" name="var1" >
<input type="TEXT" name="var2" >
</form>
</body>
</html
I had to add the onDownKey attribute to the body in order to get editing keys to go to the functions.
$(document).keydown(function(e) {
var elid = $(document.activeElement).is('input');
if (e.keyCode === 8 && !elid) {
return false;
}
});
Hope this might help you
Seems like the "backspace" will also act as "navigation back" if you have selected radio buttons, check-boxes and body of document as well. Really annoying for forms - especially when using post. All the form could be lost with one slip of the "backspace" key -_- ...
Honestly... who's idea was it to allow the "backspace as a navigational "back" button!!! really bad idea in my opinion.
I disable the "backspace" default on anything that is not a text area or text field - like this:
$(document).keydown(function(e){
console.log(e.keyCode+"\n");
var typeName = e.target.type;//typeName should end up being things like 'text', 'textarea', 'radio', 'undefined' etc.
console.log(typeName+"\n");
// Prevent Backspace as navigation backbutton
if(e.keyCode == 8 && typeName != "text" && typeName != "textarea"){
console.log("Prevent Backbutton as Navigation Back"+typeName+"\n");
e.preventDefault();
}
//
})
Not sure where else one would want the normal behavior of a back-button other than in these two areas.
document.onkeydown = KeyPress;
function KeyPress(e) {
if (!e.metaKey){
e.preventDefault();
}
}
I'm having troubles getting the attachEvent to work. In all browsers that support the addEventListener handler the code below works like a charm, but in IE is a complete disaster. They have their own (incomplete) variation of it called attachEvent.
Now here's the deal. How do I get the attachEvent to work in the same way addEventListener does?
Here's the code:
function aFunction(idname)
{
document.writeln('<iframe id="'+idname+'"></iframe>');
var Editor = document.getElementById(idname).contentWindow.document;
/* Some other code */
if (Editor.attachEvent)
{
document.writeln('<textarea id="'+this.idname+'" name="' + this.idname + '" style="display:none">'+this.html+'</textarea>');
Editor.attachEvent("onkeyup", KeyBoardHandler);
}
else
{
document.writeln('<textarea id="hdn'+this.idname+'" name="' + this.idname + '" style="display:block">'+this.html+'</textarea>');
Editor.addEventListener("keyup", KeyBoardHandler, true);
}
}
This calls the function KeyBoardHandler that looks like this:
function KeyBoardHandler(Event, keyEventArgs) {
if (Event.keyCode == 13) {
Event.target.ownerDocument.execCommand("inserthtml",false,'<br />');
Event.returnValue = false;
}
/* more code */
}
I don't want to use any frameworks because A) I'm trying to learn and understand something, and B) any framework is just an overload of code I'm nog going to use.
Any help is highly appreciated!
Here's how to make this work cross-browser, just for reference though.
var myFunction=function(){
//do something here
}
var el=document.getElementById('myId');
if (el.addEventListener) {
el.addEventListener('mouseover',myFunction,false);
el.addEventListener('mouseout',myFunction,false);
} else if(el.attachEvent) {
el.attachEvent('onmouseover',myFunction);
el.attachEvent('onmouseout',myFunction);
} else {
el.onmouseover = myFunction;
el.onmouseout = myFunction;
}
ref: http://jquerydojo.blogspot.com/2012/12/javascript-dom-addeventlistener-and.html
The source of your problems is the KeyBoardHandler function. Specifically, in IE Event objects do not have a target property: the equivalent is srcElement. Also, the returnValue property of Event objects is IE-only. You want the preventDefault() method in other browsers.
function KeyBoardHandler(evt, keyEventArgs) {
if (evt.keyCode == 13) {
var target = evt.target || evt.srcElement;
target.ownerDocument.execCommand("inserthtml",false,'<br />');
if (typeof evt.preventDefault != "undefined") {
evt.preventDefault();
} else {
evt.returnValue = false;
}
}
/* more code */
}
Just use a framework like jQuery or prototype. That's what they are there for, this exact reason: being able to do this sort of thing w/out having to worry about cross-browser compatibility. It's super easy to install...just include a .js script and add a line of code...
(edited just for you Crescent Fresh)
With a framework, the code is as simple as...
<script type='text/javascript' src='jquery.js'></script>
$('element').keyup(function() {
// stuff to happen on event here
});
Here is a function I use for both browsers:
function eventListen(t, fn, o) {
o = o || window;
var e = t+Math.round(Math.random()*99999999);
if ( o.attachEvent ) {
o['e'+e] = fn;
o[e] = function(){
o['e'+e]( window.event );
};
o.attachEvent( 'on'+t, o[e] );
}else{
o.addEventListener( t, fn, false );
}
}
And you can use it like:
eventListen('keyup', function(ev){
if (ev.keyCode === 13){
...
}
...
}, Editor)
Different browsers will process events differently. Some browsers have event bubble up throw the controls where as some go top down. For more information on that take a look at this W3C doc: http://www.w3.org/TR/DOM-Level-3-Events/#event-flow
As for this specific issue setting the "userCapture" parameter to false for the addEventListener will make events behave the same as Internet Explorer: https://developer.mozilla.org/en/DOM/element.addEventListener#Internet_Explorer
You might be better off using a JavaScript framework such as MooTools or jQuery of your choice to ease cross-browser support. For details, see also
http://mootools.net/docs/core/Element/Element.Event
http://api.jquery.com/category/events/
MooTools port of parts of your sample code:
var Editor = $(idname).contentWindow.document;
...
$(document.body).grab(new Element('textarea', {
'id' : this.idname,
'name' : this.idname,
'style': 'display:none;',
'html' : this.html
});
Editor.addEvent('keyup', KeyBoardHandler);
By the way, is it on purpose that you use both idname and this.idname in the code above ?