Keypress and Keydown generate different behavior - javascript

I am trying to create to popup div when pressing enter key, while the div contains a button (that I script to focus when it fired up) that will close the div when you press enter again. I receive the enter key from binding keypress and keydown, end up having different results.
Binding 'keypress'
Things work properly, with first enter key fires up a popup box and another enter key to dismiss the popup box.
Refer this JSFiddle.
Binding 'keydown'
This doesn't work correctly, as it fires up and dismiss the popup box immediately (which you won't see) with only one enter key.
Refer this JSFiddle.
My question is why would keydown generate odd behavior, it is like firing enter key twice for me, but the truth it wasn't. If I remove the button focus(), it will works correctly. That's puzzled me.
Tested with firefox and chrome.

You're rebinding the click event every single time the popup opens, so each time you click the close button it'll fire it multiple times which will cause unexpected behaviour.
Eg:
var Popup = function(){
$('#ok-button').live('click',function(){
$('#popup').remove();
});
};
This code means every time you create a new Popup instance, every single $('#ok-button') that exists will have another click event bound to it.
As for the reason why it immediately closes when you use keydown vs keypress, that's due to the fact that the moment the popup is opened you've set the focus to the button.
The two key events work differently (firing at slightly different times during the key process). It appears that with keydown, you're changing the focus in the middle of the actual action (pressing the button on the keyboard) which then continues and triggers the focused click.
Removing the focus stops the weird double trigger behaviour because you're no longer binding another click event.
I'd suggest changing your click event:
$('#ok-button').live('click', function(){
$('#popup').remove();
});
var Popup = function(){
// Whatever
};
I'd also suggest looking at jQuery's on event instead of using live.

Related

window.open with _blank opens two tabs in Firefox

When this element is middle clicked:
// Allow middle button click to open client in another tab.
$(document).on('mousedown', '.clientlist-edit', function (event) {
if (event.which === 2) {
event.preventDefault();
var url = $(this).attr('href');
url = url.toLowerCase().replace('/addedit', '/clientindex');
window.open(url, '_blank');
return false;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="clientlist-edit" href="/Clients/Management/AddEdit/4ffac190-72d2-476a-b0be-a9d90097272a">
<i class="glyphicon glyphicon-pencil"></i> <strong class="title">Client Name</strong>
</a>
This handler is called and when it gets to window.open, two tabs are opened. The first is the URL (variable URL) which is desired. The second is the original href set on the anchor element which is undesired. I'm calling preventDefault. What am I missing?
It is reproducible. See the link below. Sometimes it is two middle clicks. It is a middle click. It only happens in Firefox.
https://jsfiddle.net/jsmunroe/eap1b6k7/3/
I'm using Firefox 68.0.2.
I guess your goal here is to intercept the user trying to open a link in a new tab and instead open a different link in a new tab. If I'm correct, then you're going to need to adjust your strategy in a few key ways:
Don't use mousedown
Click events are triggered by a mouse-down followed by a mouse-up event. That means that normally you have to press and release the button before any click-type thing happens, whether that's navigation (left-click), context menu (right-click) or open in new tab (middle-click). If you try to simulate this using mousedown, it's gonna feel weird - the action will happen too soon!
Also, as you've now observed, it won't work correctly: the corresponding click event will still happen after your handler runs, because you're not cancelling the right event. What does your preventDefault() / return false accomplish? Well, try holding the middle button down and dragging: most browser will probably pan around the view as you move your mouse, but if you try this on your "Middle Click Me" element... Nothing happens. Yep, you've only succeeded in making your page slightly more annoying to scroll around on.
DO use the auxclick event.
I'm guessing you went with mousedown in the first place because you observed that nothing fired for a middle click when you captured the click event. A few years ago, click would've worked fine - but now, click only fires for the primary mouse button. This is a good thing! Way too many people inadvertently blocked right- and middle-clicks by capturing click, when they only intended to capture left-clicks. Presumably if you're capturing auxclick, you know what you're doing and can be trusted to handle it properly. (so, y'know... Do be careful)
The w3c actually has rather good documentation on all of this, so I'd be remiss if I didn't link to it and quote the relevant bits here:
The click event should only be fired for the primary pointer button (i.e., when button value is 0, buttons value is 1). Secondary buttons (like the middle or right button on a standard mouse) MUST NOT fire click events. See auxclick for a corresponding event that is associated with the non-primary buttons.
The click event MAY be preceded by the mousedown and mouseup events on the same element, disregarding changes between other node types (e.g., text nodes). Depending upon the environment configuration, the click event MAY be dispatched if one or more of the event types mouseover, mousemove, and mouseout occur between the press and release of the pointing device button. The click event MAY also be followed by the dblclick event.
Finally, here's your snippet with the changes above, for your review (you can't actually test it here, since window.open is blocked in Snippets - but you'll get an error indicating this and not see any tabs open; paste it into your fiddle for a real test):
// Allow middle button click to open client in another tab.
$(document).on('auxclick', '.clientlist-edit', function (event) {
if (event.which === 2) {
event.preventDefault();
var url = $(this).attr('href');
url = url.toLowerCase().replace('/addedit', '/clientindex');
window.open(url, '_blank');
return false;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="clientlist-edit" href="/Clients/Management/AddEdit/4ffac190-72d2-476a-b0be-a9d90097272a">
<i class="glyphicon glyphicon-pencil"></i> <strong class="title">Client Name</strong>
</a>
Yep - the only change is mousedown -> auxclick! Enjoy...
Further reading
Middle button click event
UI Events - event type click - W3C Editor's Draft
Element: auxclick event on MDN

How do I detect if a button was clicked with a keyboard key pressed? (Ctrl-click, Alt-click etc.)

I'm trying to write a UI for an Adobe After Effects script. I want to add a functionality where a user can CTRL click a button instead of just clicking it with no keypresses to get a slightly different behavior.
The problem is, however, I don't to know how to detect if a key was pressed when the button was clicked.
I've managed to detect a keypress with
myPanel.addEventListener("keydown", function (kd) {alert(kd.keyIdentifier); return(kd.keyIdentifier);});
This piece of code adds a listener that alerts me a name of the button when it is being pressed. I also have a button onClick event to control what happens when a button is pressed. However, I can't figure out how to combine those two listeners and get an information about whether a key was pressed during the button click. I tried to place the keydown listener inside the onClick function, but then it doesn't work at all.
I managed to make it work.
The Adobe ScriptUI environment lets you monitor the keyboard status at all times using the Keyboard state object. You can get it from: ScriptUI.environment.keyboardState. It has properties such as altKey, ctrlKey and so on that return a boolean based on whether they key was pressed or not. All you have to do is put the object initiation into the onClick event of the button:
button.onClick = function() {
isCtrlPressed = ScriptUI.environment.keyboardState.ctrlKey;
}
For more information, I refer to p.155 of the Adobe JavaScript Tools Guide
<button onclick="sample(event)">Click Me!</button>
function sample(event){
if (event.ctrlKey){
alert('Button click with ctrlKey pressing.');
}else{
alert('Button click without ctrlKey pressing.');
}
}
Event object has some key press or not. Check that then use it.
Example

Not able to understand how the domEvent works

Scenario:
I have a RadCombobox and I have attached functions to most of the events.
One event of the combobox is OnClientBlur and I am using this to check whether value in Combo is "Unassigned" or not. If it is "Unassigned" I need to cancel the onblur event and keep the focus on to the same combo.
This is the javascript which I has been used to cancel the event.
if (sender.get_text() === "Unassigned") {
eventArgs.get_domEvent().preventDefault();
return false;
}
Problem:
When the user tabs out first time of the ComboBox the event gets cancelled and the focus stays on the same combo box (in this case it is the 3rd Combo).
But when the user hits the tab button again the focus moves to the next control.
When I debugged the code I found that when the user first hits the tab button, following line works
eventArgs.get_domEvent().preventDefault();
I can see the preventDefault function, see following snapshot.
but when the user hits the tab button again I get an error and cannot see preventDefault function, see following snapshot
I am not able to understand what is going wrong here. Anyhelp would be appreciated.
Your problem, revolves around the difference between MouseEvents and KeyEvents. And also the way Telerik implement the OnClientBlur event. As far as it doesn't point to a specific type of browser event, each time it gets triggered
As you see in the first snapshot you got clientX and clientY, which means your OnClientBlur derived from a MouseEvent.
Whereas in the second one you got altKey, altLeft, and also there is no button property, which means that this one is a KeyEvent.
The other point here is as you have these fields in the output:
e.bookmarks
e.behaviorPart
e.behaviorCookie
Means you are using one of the old versions of IE4+ to IE7 or IE8, which they have cancelBubble instead of preventDefault.
Sometimes events are not cancelable, and using event.cancelable you can make sure if the current event is cancelable or not.
At the end to fix you code you can simply do this:
if (sender.get_text() === "Unassigned") {
var domEvent = eventArgs.get_domEvent();
if(domEvent.cancelable){
if(typeof(domEvent.preventDefault)==="function")
domEvent.preventDefault();
else
domEvent.cancelBubble = true;
return false;
}
else{
//you can not cancel the event, do something else to make it manageable
}
}

Capture "done" button click in iPhone's virtual keyboard with JavaScript

I'm wondering if there's a way to capture the iPhone's virtual keyboard's done button event, using JavaScript?
Basically, I just want to be able to call a JS function when the user clicks done.
I was unable to track the 'done' button being clicked. It didn't register any clicks or keypresses. I had to addEventListeners for change, focusout and blur using jquery (because the project already was using jquery).
You need to do some kind of this:
$('someElem').focusout(function(e) {
alert("Done key Pressed!!!!")
});
It worked for me, hope it will help you as well.
After searching and trying this solution
basically is say:
document.addEventListener('focusout', e => {});
tested on IPhone 6s
This question is kinda old, but I've found a hacky way recently to make this working.
The problem with the 'blur', 'focusout' events is that they fire even if user just tapped outside the input/textarea, and did not press the 'Done' button, in my case, UI should behave differently depending on what exactly have happened.
So to implement it, I've done the next thing:
After showing the keyboard (the input received the focus), add click handler on the window via the addEventListener function. When user clicks on the window, remember the timestamp of the click in the variable (let's call it lastClick = Date.now())
In the blur event handler, set a timeout for 10-20 ms to allow other events happening. Then, after the timeout, check if the blur event happened in a time difference lower for example than 50-100 ms than the lastClick (basically Date.now() - lastClick < 50). If yes, then consider it as a 'Done' button click and do corresponding logic. Otherwise, this is a regular 'blur' event.
The key here is that tapping on keyboard controls (including Done button) does not trigger the click event on the window. And the only other way to make keyboard hide is basically tap on other element of the page and make the textarea lose focus. So by checking when the event happened, we can estimate whether that's a done button click or just blur event.
The answer by oron tech using an event listener is the only one that works cross platform.
document.getElementById("myID").addEventListener("focusout", blurFunction);
function blurFunction() { // Do whatever you want, such as run another function
const myValue = document.getElementById("myID").value;
myOtherfunction(myValue);
}
"Change" event works fine
document.querySelector('your-input').addEventListener('change',e=>
console.log('Done button was clicked')
);
attach a blur event to the text box in question. The done fire will fire this event.
The done key is the same as the enter key. So you can listen to a keypress event. I'm writing this using jQuery and i use it in coffee script so I'm trying to convert it back to js in my head. Sorry if there is an error.
$('someElem').bind("keypress", function(e){
// enter key code is 13
if(e.which === 13){
console.log("user pressed done");
}
})

jQuery autocomplete - mouse click result, input does not lose focus

In the autocomplete result list. How do I capture the click event? Currently results are links. When clicked they open a new window with the embedded url but when this happens the autocomplete doesn't lose focus and the result box gets stuck open. It stays open even when the user comes back and clicks anywhere on the page. the only way to make it lose focus is to click inside the input box and then click back out.
It looks like opening the new window loses focus from the input box but does not fire off a blur() event.
I was thinking if I could capture the click event I could just manually trigger a .blur() but I was unsuccessful at my attempts using the class for the list elements $("li") or their css names $(".ui-menu"). I also tried in the autocomplete Select event but that didn't do anything.
This looks like it might be a solution: http://jeremydorn.blogspot.com/2010/04/fixing-jquery-ui-autocomplete.html
But I was hoping for something more elegant.
Thanks
Why don't you give the links a click handler that closes the autocomplete?
For example:
$("a.autocompleteLink").click(function() {
$("input.autocomplete").autocomplete("close");
});

Categories

Resources