I want to use focusout on a textarea, stash the value of the clicked button which caused the focusout, and click it later, after some processing. My solution works well on all devices except iPhone and iPads. Can anyone explain why the event.relatedTarget is null on touch screens? Or is it the browser? What else is there to use?
I have tried e.currentTarget and document.activeElement (returns the whole HTML body) as well as trying setTimeout around my use of e.currentTarget. I can't seem to get the ID of the clicked button inside my focusout, on iPads and iPhones.
Here's a sample:
<div id="resultPage">
<textarea id="txtAnswer0" class="txtAnswer"></textarea>
<button id="goNow">
GO
</button>
</div>
$(document).ready(function() {
$("#resultPage").on("focusout", ".txtAnswer:not(input[type=radio], input[type=checkbox])", function(e) {
var targetCtrl = e.relatedTarget;
alert(targetCtrl);
});
});
Here is my fiddle:
https://jsfiddle.net/awebster28/6q6ok4re/25/
In my research I learned relatedTarget is only supposed to be on mouse events. If relatedTarget isn't null in a non-mouse event then the browser isn't following standards.
You'll probably have to temporarily store the button, and/or button value in a variable on click so it can be used later with the second click.
Related
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("p").on("click", function(event){
console.log("print originalEvent name", event.originalEvent.constructor.name)
});
});
</script>
<p>Click this paragraph.</p>
I recently found that when using mouse click on Safari, "event.pointerType" is undefined where as in chrome it is coming as "mouse" .
I need to do a similar check in safari browser to pass my condition.
I tried couple of things, like using pointerDown eventListener but due to some limitations(like my pointerDown listner code is inside a different jQuery.On listener and due to that it is not triggering on first click and also only either of those listeners are executing skipping the other which should not happen in my case. As i do not have control on jQuery listener trigger i am not able use all eventListener options for this approach to work).
So after some debugging I found on Safari Browser for mouse click events the value of below is coming as "MouseEvent" which works for my requirement. But can i rely on this value for this and is it ok to use the constructor name here.
$(document).on("click", ".my-btn-class", function(evtParam){
if(evtParam.originalEvent && evtParam.originalEvent.constructor &&
evtParam.originalEvent.constructor.name === "MouseEvent"){
//do my logic
}
})
I am using coveo Framework and i used facets inside a dropdown button i wrote a window.onclick function so that when clicked outside dropdown button the dropdown should be closed.
everything seems to be working fine but when i clicked facets checkbox the dropdown was closing and when i talked to coveo team they said the query was triggered when coveo checkbox was clicked thats the reason the dropdown was closing when clicked.
To fix this i used event.stopPropogation and that was working fine in desktop mode but when it comes to IPAD Mode this is not working any help
Here is my code
// Prevent event bubble up to window.
document.getElementById('dropdown').addEventListener('click', function(event) {
event.stopImmediatePropagation();
});
function close() {
document.getElementById('dropdown').classList.remove('show');
}
window.onclick = function(event) {
if (!navigator.userAgent.match(/Android|webOS|iPhone|iPod|Blackberry/i)) {
if ((!event.target.matches('.dropdown-backdrop')) && event.target.closest('#dropdown') === null) {
close();
}
}
};
I believe the issue is on a touch screen device, you actually get touch events possibly in addition to mouse events. I suspect if you attached another listener to touchstart that does the same thing as click you will see the same results on the tablet.
In theory you should see no click events on a tablet (a user cannot click without a mouse) but in practice the browser emulates click events. However, when those events are generated the browser may fire both touch events and mouse events in response to the same user input. If both events are fired you're successfully stopping the click event from propagating but not the touch event.
Update
You haven't given enough detail to fully give an example, but the change happens in the listeners you attach to your dropdown element.
// Note instead of using the same anonymous function twice,
// I've defined a function to stop propigation
function stopProp(e) {e.stopImmediatePropagation();}
document.getElementById('dropdown').addEventListener('click',stopProp);
document.getElementById('dropdown').addEventListener('touchstart',stopProp);
I have a <select id="myselect" name="myselect" onChange="(myfunction();)">...</select> which works perfect in IE and Opera. The word "perfect" means the event fired when you change the values from the drop-list by mouse or by any of "Up", "Down", "PageUp"(not for Opera), "PageDown"(not for Opera), "Home" and "End" keys when select menu is active (blue). The problem appears when you test it using Firefox, 3.6.Xv. Nothing happens when you use "Up" and "Down", but for mouse it still works.
Do you recommend to use onkeyup event? I've tried it, it "catches" up and down, but, IE appears to have both onChange and onkeyup event. But I need just one event.
How do people solve this issue?
Thank you.
I recommend that you keep using the change event. The Firefox implementation makes lots of sense for keyboard users. If you tab to the select element and choose an entry using Up and Down keys (and you have to press them a lot for a lengthy list) you don't want to trigger tons of actions on the web page. It is ok to have the action executed once you've selected the correct entry and moved on to something else.
This is a pretty dirty hack, but you can force the the change event to fire by doing this:
element.addEventListener('keyup', function(evt){
evt.target.blur();
evt.target.focus();
}, false);
So you'd register an event listener for change as well, and that function would get called when the user presses a key on the <select> via the code above.
You may want to scope this only to Firefox, but AFAIK you'd have to use UA sniffing for that so it's up to you if that's acceptable.
Source
You could be clever and make your own handler for the keyup event which tests the keycode to see if it was an up arrow or down arrow, and fires the change event accordingly.
My own js isn't good enough to write you an example but I could show some example jQuery to do that:
$('yourSelect').keyup(function(e)
{
if (e.keyCode===38)
{
//this is an up arrow press
//trigger the change event
$('yourSelect').change();
}
else if (e.keyCode===40)
{
//down arrow has pressed
//trigger the change event
$('yourSelect').change();
}
});
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");
}
})
I have designed a website with a menu that is initially invisible. When the user clicks on a button, the menu becomes visible. There are two ways for the user to hide the now visible menu:
Click the button that caused the menu to become visible
Click anywhere on the web page that isn't the menu
The way I have coded the second option is to tie an onclick event to the window element, and have it compare where the user clicked to the menu's position to determine if the menu should be hidden. This works great in Firefox and Safari, but it fails in Mobile Safari.
I noticed that the window onclick event only fires when I click on another element with an onclick event already assigned. If I click on an element with no event(s) assigned, the window's onclick event never fires. If I click on the button which displays the menu, it fires along with the event tied to the button.
Is it possible to assign events to the window element in Mobile Safari?
I'v been encountering this same problem. Here is what worked for me. (Note: I am working within a Modernizr and jQuery context)
First, I add a custom Modernizr class using Modernizr's addTest Plugin API to test for iOS, which will add the class appleios or no-appleios accordingly.
Because in my research the body seems to fire events on it's own agenda, I am taking a little precaution by wrapping all the document's content with an element in an iOS context. Then I add an event handler to this element.
$(".appleios body").wrapInner('<div id="appleios-helper" />');
$("#appleios-helper").bind("mouseup", function(){return;});
What was suggested earlier in this thread is using void(0). I did some quick testing, and found that void(0) as the event just wasn't causing touches on the body to be recognized. When I plugged in my own "empty" function in the form of function(){return;} things started working.
This all hinges on the fact that no events are fired in Mobile Safari unless the element explicitly has events to fire (Safari Web Content Guide.) By inserting this empty event on the wrapper, things will bubble up to the body.
If you're doing strait JavaScript with none of these libraries, the same effect could be achieved in the HTML markup
<html>
...
<body>
<div id="appleios-helper" onmouseup="function(){return;}">
...
</div>
</body>
</html>
This worked for me to hide tooltips when touching anywhere on the document's body. Your mileage may vary.
Simply adding the dummy onclick handler to the html body works for me:
<body onclick="void(0)">
Note that I am using usual live event handlers as shown below:
function liveHandler( event ) {
var target = event.target; ...}
window.addEventListener(evtype, liveHandler, true);
// evtype such as 'mousedown' or 'click'
// we use the capturing mode here (third parameter true)
This is an old question, but I struggled with the same thing today.
I found that using touchstart event works.
I solved it like this:
var isTouchDevice = 'ontouchstart' in document.documentElement;
if (isTouchDevice) {
// Do touch related stuff
$(document).on('touchstart', function (event) {
// Do stuff
});
} else {
// Do non-touch related stuff
$(document).on('click', function () {
// Do stuff
});
}
You could just add onclick="void(0);" to some <div> that covers the whole page so that no matter what, you are always clicking on an element that has an onclick event. Not a great solution, though.
I'd prefer not having the onclick event be tied to the window. Why don't you create a container <div> that has that event on it. Then handle it just like you currently are.
You can also:
$('body').css('cursor', 'pointer');
No idea what those "engineers" at Apple are doing. LOL.
This has problems though. You wouldn't want to do this on every touch device. Only touch devices that don't also have a pointing device (Laptops with Touch Screens, for example).
Source: http://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
The conclusion of the article is this:
So I don’t understand why all this is the case, but it most certainly is the case. If you’re having bubbling problems, just add an empty-function event handler anywhere between the body and the element, and you’re set to go. But it shouldn’t be necessary.