Focus event with dispatchEvent - javascript

When I trigger a focus event with dispatchEvent on an input box, its onfocus is called, but on the UI the input box is not focused.
Is there any reason for this behavior?
var test = document.getElementById("test");
test.onfocus = function(event) {
console.log('focused');
}
var e = document.createEvent('Event');
e.initEvent("focus", true, true);
test.dispatchEvent(e);
On the other hand this works as expected.
var test = document.getElementById("test");
test.focus();
The reason i'm investigating this is that I use ZeptoJS to trigger events and it uses dispatchEvent.

The element you fire an event on does not have to be listening for that event, since potentially, the parent element may also be listening for that event.
Note that manually firing an event does not generate the default action associated with that event. For example, manually firing a focus event does not cause the element to receive focus (you must use its focus() method for that), manually firing a submit event does not submit a form (use the submit() method), manually firing a key event does not cause that letter to appear in a focused text input, and manually firing a click event on a link does not cause the link to be activated, etc. In the case of UI events, this is important for security reasons, as it prevents scripts from simulating user actions that interact with the browser itself.
Also note that you should use fireEvent(), if you are working on IE. Also, the main difference between the dispatchEvent and fireEvent methods is that the dispatchEvent method invokes the default action of the event, the fireEvent method does not.
so for the solution please try this
test.onfocus = function(event) {
console.log('focused');
if( ! test.hasFocus() ) {
test.focus();
}
}

Related

efficient way to dynamically attach blur/focusout event to existing and any new input fields [duplicate]

I'm writing a form validation script and would like to validate a given field when its onblur event fires. I would also like to use event bubbling so i don't have to attach an onblur event to each individual form field. Unfortunately, the onblur event doesn't bubble. Just wondering if anyone knows of an elegant solution that can produce the same effect.
You're going to need to use event capturing (as opposed to bubbling) for standards-compliant browsers and focusout for IE:
if (myForm.addEventListener) {
// Standards browsers can use event Capturing. NOTE: capturing
// is triggered by virtue of setting the last parameter to true
myForm.addEventListener('blur', validationFunction, true);
}
else {
// IE can use its proprietary focusout event, which
// bubbles in the way you wish blur to:
myForm.onfocusout = validationFunction;
}
// And of course detect the element that blurred in your handler:
function validationFunction(e) {
var target = e ? e.target : window.event.srcElement;
// ...
}
See http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html for the juicy details
use 'Focusout' event as it has Bubble up effect..thanks.
ppk has a technique for this, including the necessary workarounds for IE: http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
aa, you can simply add the onblur event on the form, and will call the validation every time you change focus on any of the elements inside it

How to prevent default functionality of paste event in monaco editor

How can I prevent default functionality for paste event (when trigger from browser menu option Edit->Paste) for monaco editor?
I am handling paste event in the following way:
editor.getContainerDomNode().addEventListener('paste', (event) => {
event.preventDefault();
event.stopPropagation();
}
I also tried to handle the paste event on the textarea which is the source element in event propagation.
let textarea = editor.getContainerDomNode().querySelectorAll("textarea.inputarea.monaco-mouse-cursor-text")[0];
textarea.addEventListener('paste', (event) => {
event.preventDefault();
event.stopPropagation();
});
But here also seems like preventDefault is not working. It is pasting into editor whatever the text is copied.
Bascially I want to disable paste action when triggered from browser Edit menu. Need to know how this can be achieve in monaco-editor. Am I doing anything wrong here or it is a bug of monaco editor?
Your problem comes from the way an event is handled by listeners, when they are set on different ancestor elements.
An event is generally treated on a target element, then it "bubbles" on its ancestors.
On your case, you are adding a listener on a parent element of the editor. Which means that your listener will be executed after any listener on the actual target (which is actually how monaco handles the paste event).
So you are trying to prevent an action that was already executed.
Luckily, there is a way to achieve what you want! It is called "capturing".
By specifying in the call to addEventListener that you want to capture the event on its way down. This can be done by adding a third argument {capture: true}, or simply true:
editor.getDomNode().addEventListener('paste', (event) => {
event.stopPropagation();
event.preventDefault();
}, true);
This should prevent the editor from actually executing the action.
See Documentation on bubbling and capturing events.

Javascript disable the same event / disable event globally

I have two javascript, booth have the same click event, one for check input fields check, second for do action.
Is it possible to disable the click event of do_action.js from check.js click event? But, without any additional statements in do_action.js click event!
I just want the check.js and do_action.js will work independently of each other.
check.js:
$("button").click
(
function()
{
//if wrong name or email, than globally disable this event now
return false;
}
);
do_action.js:
$("button").click
(
function()
{
//do action
}
);
Is it possible to disable the click event of do_action.js from check.js click event?
Kind of, but not in the way you're trying to do.
Since when the button event in invoked, both of your events will be fired asynchronously in parallel with each other, therefore your check event won't actually affect your do_action event.
The approach you'd need for this is to instead of disabling the event, you would attach the event once your condition is met. However, this doesn't work really well because you'd have to invoke this event twice for it to work.
Instead, try to just fire your do_action method if your check event is valid and only use one event:
$("button").click(function(){
// Have a function that checks for input validity
if(check_valid_input()){
// Valid input, so now you can call your do_action
do_action();
}else{
// Invalid input
}
});

Determining whether focus was received as result of a click event

I have an <input> element that can either have the focus set via code, or as the result of a mouse click.
If the user clicks on the input, then the click event handler will fire - all well and good. If the element receives the focus via some other way (e.g. via code) then I want to manually trigger the click event so that the handler will also fire.
I could do this:
$elem = $('input');
$elem
.on('focus', function() { $(this).trigger('click') })
.on('click', function() { alert('Clicked!') });
However, this will result in click handler being fired twice; once for the click event and once for the focus event.
Is there any way to selectively trigger the click handler only if the focus was not received as the result of a click event?
UPDATE
This is a very simplified version of my problem, so I can't do things like bind both handlers to the focus event etc. I'm trying to merge two third-party pieces of code.
The .trigger() function adds a property isTrigger in the event object to identify that the event was triggered by its usage. Although, it is not documented the property is still present in jQuery 1.8.3 but it seems to only be used internally.
Anyways, you can make use of the extraParameters parameter to add a custom property to the event object. For instance,
$(this).trigger('click', {
isTrigger: true
});
It will keep the compatibility with isTrigger even if it is gone in a future release.
After doing some more research it appears that there is no way of guaranteeing which event will fire first: click or focus. (There doesn't seem to be a standard that dictates the order of events.)
This means that when the focus event fires there's no way to determine if a click event will or will not be triggered by the browser shortly afterwards.
I managed to solve the issue by using setTimeout() to run a test about 100ms after the focus event fired to check if the click event had fired. The third-party code that I was using (bound to the click event) added an extra class to the <input>, so I was able to check for that.
You can tap into the mousedown event which fires before the focus event. When you click a focusable object the order of events is as follows... mousedown, focus, mouseup, click.
You could set a flag in the mousedown event and then check for it in the focus event to see if the focus came from a mouse click. Obviously make sure to clear the flag in the focus event handler. Every application is different, but tapping into the mousedown event allows you to figure out a solution.
Here is a JSFiddle demonstrating the order of events... http://jsfiddle.net/ek7v7/
$elem = $('input');
$elem
.on('focus', function() { alert("Focused!") })
Focus can be fired by focusing the input by using tab, clicking it, or by using .focus()
Is there a reason for on('click', ...)?

Event bubbling and the onblur event

I'm writing a form validation script and would like to validate a given field when its onblur event fires. I would also like to use event bubbling so i don't have to attach an onblur event to each individual form field. Unfortunately, the onblur event doesn't bubble. Just wondering if anyone knows of an elegant solution that can produce the same effect.
You're going to need to use event capturing (as opposed to bubbling) for standards-compliant browsers and focusout for IE:
if (myForm.addEventListener) {
// Standards browsers can use event Capturing. NOTE: capturing
// is triggered by virtue of setting the last parameter to true
myForm.addEventListener('blur', validationFunction, true);
}
else {
// IE can use its proprietary focusout event, which
// bubbles in the way you wish blur to:
myForm.onfocusout = validationFunction;
}
// And of course detect the element that blurred in your handler:
function validationFunction(e) {
var target = e ? e.target : window.event.srcElement;
// ...
}
See http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html for the juicy details
use 'Focusout' event as it has Bubble up effect..thanks.
ppk has a technique for this, including the necessary workarounds for IE: http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
aa, you can simply add the onblur event on the form, and will call the validation every time you change focus on any of the elements inside it

Categories

Resources