I'm attempting to create a Greasemonkey script that can submit a tweet when a user hits the 'enter' key. I've gotten this to work fine on a simple HTML page (with the help of a few excellent tips on this site). However, when I try to use the code on my twitter page, the alert only fires if a tweet is not currently being authored.
document.onkeyup = function(event){
var keyCode;
if (window.event) // IE/Safari/Chrome/Firefox(?)
{
keyCode = event.keyCode;
}
else if (event.which) // Netscape/Firefox/Opera
{
keyCode = event.which;
}
if (keyCode == 13){
alert("Enter pressed");
}
}
My next thought was to test for a more specific keypress event. So I tried testing for a key event within the new tweet textarea:
document.getElementsByClassName("twitter-anywhere-tweet-box-editor")[0].onkeyup = function(event)
...but this event never seems to fire. I also tried grabbing the element by tag:
document.getElementsByTagName("textarea")[0].onkeyup = function(event)
...but not dice there either. I wonder if this has to do with the fact that the new tweet window is not loaded from the get-go at window.onload(). Thoughts?
I got it thanks to this post. I've also posted the full Greasemonkey script here.
setInterval (function() { checkForTweetbox (); }, 500);
function checkForTweetbox () {
var tweetbox = document.querySelector ('div.tweet-box textarea'); //check for new tweet window
if (tweetbox) {
if (! tweetbox.weHaveProcessed) {
tweetbox.weHaveProcessed = true;
// alert ('New tweet-box found!');
}
}
tweetbox.onkeydown = function(event){
if(event.keyCode == 13){ //13 = Enter keycode
document.querySelector ('a.primary-btn').click(); //there must be at least one character in the textarea
}
}
}
Related
This is a complete revision of my initial question, all unnecessary resources and references were deleted
I am tying the same event listener to 2 different elements: a button and Enter key, and it looks like the following:
var funcelement = function(){
//function code
};
$('#buttonID').click(funcelement);
$('#inputID').keyup(function () {
if (event.which == 13) {
$('#buttonID').trigger('click');
}
})
What I am trying to do is to prevent propagation of the enter key press if focus is on the submit button(#buttonID) by using preventDefault().
So I tried various combinations to make it work. The following is the latest result on my attempts
$('#inputID').keyup(function () {
var hasfocus = $('#buttonID').is(':focus') || false;
if (event.which == 13) {
if (!hasfocus) {
event.preventDefault();
$('#buttonID').trigger('click');
//hasfocus = true;
}
else {
//event.preventDefault();
//$('#buttonID').trigger('click');
}
}
})
After I enter a text into an input box and press Enter key, a confirmation window with yes/cancel buttons pops up with focus on yes button. Once I press Enter again, another window confirming that changes were made pops up with Ok button focused on it. Once I press Enter again, everything I need is being made.
However, there is one problem: after the last step is done, I am going back to the if (!hasfocus) line.
How do I prevent that from happening? Once the stuff I need is done - I don't want to go into that line again.
You can pass a parameter to into the function and stop the propagation there like so:
var funcelement = function(event, wasTriggeredByEnterKey){
if (wasTriggeredByEnterKey && $('#buttonID').is(':focus')) {
event.stopPropagation;
}
//function code
};
$('#buttonID').click(funcelement);
$('#inputID').keyup(function () {
if (event.which == 13) {
$('#buttonID').trigger('click', [true]);
}
}
)
UPDATE
In order to answer your revised issue, you should use the "keydown" event rather than "keyup" when working with alerts. This is because alerts close with the "keydown" event but then you are still triggering the "keyup" event when you release the enter key. Simply change the one word like this:
$('#inputID').keydown(function () {
var hasfocus = $('#buttonID').is(':focus') || false;
if (event.which == 13) {
if (!hasfocus) {
event.preventDefault();
$('#buttonID').trigger('click');
//hasfocus = true;
}
else {
//event.preventDefault();
//$('#buttonID').trigger('click');
}
}
})
My code works well, but I do not need this "beforeunload warning" when reloadind same page (reload button ou F5 key) , or when a click in the "back" button...
My original working code:
<script>
window.onbeforeunload = function (e) {
var msg = '\n\n\nARE YOU SURE?\n\n\n';
e = e || window.event;
if (e)
e.returnValue = msg;
//some extra conditions
document.getElementById("popUpOut").style.display = 'block';
return msg;
}
</script>
So, this is my question: How to disable beforeunload in these situations ("back button" and "reload page)?
You can't do that. A page refresh is like navigating away and unloading the DOM so the onbeforeunload event will always be called but you can prevent it using jquery for keys pressed for Ctrl + R or F5 and Backspace.
For Ctrl + R use this:
$(document).keydown(function (e) {
if (e.keyCode == 65 && e.ctrlKey) {
e.preventDefault();
}
});
For F5 use this:
$(document).keydown(function (e) {
if (e.which || e.keyCode) == 116) {
e.preventDefault();
}
});
First of all, let me say that, ""I do not want"" stop reloading the page! BUT controll the beforeunload message!
So if you allow me, I will try to explain:
A) I just want do DECIDE in that event I show (or not) the "warning
exit message"
As far everyone say to me that, "it is impossible" do control UnbeforeUnload event, I make some tests and depending of the browser it is perfecty possible, BUT this is a "working progress rechearch"
So I know this:
1) listening the keyboard it's very easy to "chose the event" and,
what I want do show in the "warning mewssage" for each one.
2) Listening the history I can chose what happends on "Navigator's
Back button", dand do the same.
3) The code below works fine in chome...
And to control the keyboard, I have this, very simple code in JS:
document.onkeydown = KeyCheck;
function KeyCheck(e) {
var key = (window.event) ? event.keyCode : e.keyCode;
if(key==116) {flag_beforeunload=false;}
if(key==8) {flag_beforeunload=false;}
if (e.keyCode == 82 && e.ctrlKey) {flag_beforeunload=false;}
document.getElementById("container").innerHTML = "key = "+key + " - " + flag_beforeunload;
}
window.onbeforeunload = function(e){
var msg = 'You are sure to exit?';
e = e || window.event;
if(e)
if (flag_beforeunload == true) {
return msg;
}
}
Following, here (dotnsf site) is where I get the code for control the browser's "back button and"... I can even disable it.
but it is en Jquery, following is my code, but in JS:
window.onpopstate = function(event) {
window.history.back(-1)
if( !event.state ){
//the to lines below, disable the back button
// history.pushState( "nohb", null, "" );
// return;
// the following line iIcan use to control the envent, in UnBeforeUnload
// flag_beforeunload=false;
}
}
}
And finaly, this is my question:
I apreciate more help, and solutions for others navigators than Chrome!
Thanks a lot !
We've been busy with upgrading TinyMCE from 3.x to 4.2.5 and can not prevent the default ENTER action from happening.
Our goal is to submit the form when CTRL + enter is pressed, and important is that the submit should happen before the newline is added to TinyMCE. The 3.x branch allowed us to add the event to the top of the queue:
// Important: inject new eventHandler via addToTop to prevent other events
tinymce.get('tinymce_instance').onKeyDown.addToTop(function(editor, event) {
if (event.ctrlKey && event.keyCode == 13) {
$("form").submit();
return false;
}
});
Unfortunately we can not figure out how to add it to the top of the events again.
event.preventDefault() and event.stopPropagation() do not have the expected effect because the enter is already there. The weird thing is that it does work on other keys, the alphanumeric keys can be prevented. http://jsfiddle.net/zgdcg0cj/
The event can be added using the following snippet:
tinymce.get('tinymce_instance').on('keydown', function(event) {
if (event.ctrlKey && event.keyCode == 13) {
$("form").submit();
return false;
}
});
Problem: the newline is added to the TinyMCE content earlier as our event handler is called, so an unwanted enter is stored. How can I add the event to the top in the 4.x branch, or prevent the newline from happening?
event.preventDefault() works when you attach the keydown event via the setup on the init function.
tinymce.init({
selector:'textarea',
setup: function (ed) {
ed.on('keydown',function(e) {
if(e.ctrlKey && e.keyCode == 13){
alert("CTRL + ENTER PRESSED");
e.preventDefault();
}
});
}
});
This does block the carriage return from happening. JsFiddle
Edit:
Above is one way of doing it, I have found another way of achieving the result which doesn't require the init at all. Instead we create a new Editor instance and bind to our textarea given it has an id.
HTML
<form>
<!--Select by ID this time -->
<textarea id='editor_instance_1'>A different way</textarea>
</form>
JS
var ed = new tinymce.Editor('editor_instance_1', {
settings: "blah blah"
}, tinymce.EditorManager);
//attach keydown event to the editor
ed.on('keydown', function(e){
if(e.ctrlKey && e.keyCode == 13){
alert("CTRL + ENTER");
e.preventDefault();
}
});
//render the editor on screen
ed.render();
var init {
...,
setup: function (ed) {
ed.on('keydown', function (e) {
if (e.ctrlKey && 13 === e.keyCode) {
e.preventDefault();
$("form").submit();
}
});
};
tinymce.init(init);
Works for tinyMCE 4.x
Maybe I'm late, but this answer is for those who cannot(or don't want to) change init setup for tinymce. I found following method:
var frame = document.getElementById('id_of_editor_iframe');
var iframeDocument = fr.contentWindow.document;
iframeDocument.addEventListener('keydown', function(e) {
if (
[38, 40, 13].indexOf(e.keyCode) > -1 //Enter and up/down arrows or whatever you want
) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
// your code here
return false;
}
}, true);
It helped me to prevent new line in editor
I have a textarea, and on each enter i want it to get blank if something has written. but my problem is; on the first enter it line breaks, and you continue to write from the second line. it only happens at the first enter. there is no problem with emptying the textarea, you just continue to write from the second line, which is the problem.
onkeydown= if(event.keyCode == 13){
sendMessage();
}
function sendMessage(user){
var message = $('#textarea').val();
$('#textarea').val('');
}
if(event.keyCode == 13) {
sendMessage();
if (event.preventDefault) event.preventDefault();
return false;
}
keydown happens before the character is entered in the textarea, so you just have to call preventDefault on the event so it doesn't enter a line break after you've called your function that clears the text-area. return false alone should be enough too if the code above is inline in the HTML, which isn't really recommended. See updated solution below:
For unobtrusiveness and back-compat, I'd recommend doing it all with jQuery:
$('#textarea_ID').keydown(function(e) {
if (e.which == 13) {
e.preventDefault();
var message = $(this).val();
$(this).val('');
//rest of your function using `message` here
}
});
Fiddle
In jQuery use the which property for the code. Then return false with e.preventDefault();
var field = $('.classname');
field.keydown(function(e){
if(e.which==13){
sendMessage();
e.preventDefault();
}
});
Simply add return false; to your keydown function. This prevents the default action of the key (a newline in this case) from being executed.
You may also want to include code to handle Internet Explorer's way of getting keycodes. Your new function would be:
onkeydown = function (e) {
// Gets keycode cross browser
e = window.event ? window.event : e;
var keycode = e.keyCode !== null ? e.keyCode : e.charCode;
// Checks if it was the enter key that was pressed (enter = keycode 13)
if (keycode === 13) {
// Calls function to do stuff
sendMessage();
// Cancels the default action of the (enter) key
return false;
}
}
I want to detect a tab/window close event (excluding F5 refreshing and link-click event and so on) and then show a overlay. I found some answer online which is like this:
endSession: function() {
//customized overlay goes here
},
wireUpEvents: function() {
var self = this;
self.validNavigation = false;
window.onbeforeunload = function() {
if (!self.validNavigation) {
self.endSession();
return "bye"; // Chrome needs a returned string to fire the event
}
}
$('html').bind('keypress', function(e){
if (e.keyCode == 116) {
self.validNavigation = true;
}
});
$('a').bind("click", function(){
self.validNavigation = true;
});
$('form').bind('click', function(){
self.validNavigation = true;
});
$('input[type=submit]').bind('click',function(){
self.validNavigation = true;
});
}
$(document).ready(function() {
wireUpEvents();
});
But I just found two weird things:
The F5 keypress event cannot be detected, it can only detect those number and character keypress event. And what surprised me the most is that it is the character t instead of F5 which has keyCode == 116! (it seems that 116 is the ascii code for lowercase t)
As Chrome needs a returned string to fire the event, it always shows a default popup with the string in it when it fires, which means I cannot create my customized popup with jqueryui or something. How to fix this?