问题
I would like to prevent the default event from a focusOut
(or blur
) event and keep the focus set to the specific input field.
This is what I have already tried:
using
event.preventDefault()
at the beginning and at the end of the function (for test purposes, not for style)return false;
to prevent propagationsetting the focus back to the element directly in the element (but I found that the focus still switches because the focus switch is executed after the
.on()
function executes. I know I could usesetTimeout
, but I’d like to avoid it and figure out the heart of the issue.)using
blur
instead offocusOut
My code is this:
_triggerEventHide: function(inst, eventType) {
inst.$target.on(eventType, function(event) {
event.preventDefault();
if (!$.suggestBox.$divCont.hasClass($.suggestBox.mouseOverClassName)) {
$.suggestBox.$divCont.css({display: 'none'}); //reposition Suggestbox
} else {
inst.target.focus();
}
event.preventDefault();
return false;
});
}
Note that $target
represents the jQuery-wrapped element and target
represents the native DOM element.
I’ve done some research and have found already a few articles relating to my question, but none of them answer this exact question.
preventDefault does not work on focus event – Here, the answer given is an alternate route to using any kind of event manipulation.
Focus back textbox on focus out if does not have required value – Here, the solution was to use
setTimeout()
to set the focus back to the original element, which is all right, but I’d like to understand the heart of the issue, whypreventDefault()
is not working here.jQuery preventDefault() not working – I tried some possible solutions from this thread, such as using
event.stopImmediatePropagation()
andevent.stop()
, but all for naught.
I appreciate any time, knowledge and solutions (including attempts) contributed in this matter. I would really like to learn…
Here is a jsFiddle to show you the problem… feel free to play around with it and try different solutions.
回答1:
After some more research I've found out that only certain events are 'cancelable'.
Quoted from http://help.dottoro.com/ljwolcsp.php
You can check whether an event can be canceled with the cancelable property in all browsers except in Internet Explorer before version 9. Although the cancelable property exists in Firefox, it always returns true, regardless of the cancelable state of the event. There is no way to determine whether an event can be canceled in Internet Explorer before version 9.
Note that the use of the preventDefault method and the returnValue property on a non-cancelable event does not cause an error. When an event handler returns false, the event will be canceled. You can use it instead of the preventDefault method and the returnValue property. See Example 2 below.
Each event in Javascript has a cancelable property that is defined as 'true' if the event can be prevented or 'false' if the event cannot be cancelled. Ref: http://help.dottoro.com/ljeosnqv.php
An example script from http://help.dottoro.com/ljeosnqv.php demonstrating this property can be found here on jsFiddle (to save space). Note the comments in the code about how Firefox always returns true for the cancelable property in the event object.
The general principal being:
$('selector').on(eventType, function (event) {
alert(('cancelable' in event)); //will return true
alert(event.cancelable); //will return true if event can be cancelled
//NOTE: Firefox mistakenly always returns true
});
Events have a preset order of occuring depending on the situation. For example if a mouse button is clicked the order of eventTriggers would be: mousedown, mouseup, and click. Ref: www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-initMouseEvent
Quoted from http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-flow-cancelation
A 'cancelable event' is an event associated with a default action which is allowed to be canceled during the DOM event flow. At any phase during the event flow, the triggered event listeners have the option of canceling the default action or allowing the default action to proceed. In the case of the hyperlink in the browser, canceling the action would have the result of not activating the hyperlink. Not all events defined in this specification are cancelable events.
Sometimes the sequence of events has it that the DOM default action will occur before the event you are looking to cancel even shows up, in these cases, you cannot cancel the default action because it has already taken place. That is to say the default action occurs before the dispatch of the event.
MY SOLUTION:
That being said I did manage to find a solution to my problem and more/less this problem. Essentially I had an eventListener with an element for focusin already and I wanted this element to keep focus.
<div id='display'></div>
$('#idBox').on('focusin', function () {
$('#div').append('focused');
//do something
}
Initially I tried using a setTimeout event when I clicked off, but I found that wasn't good because it triggered my focusin event again. So what we need is an event that is dispatched before the DOM's default action of switching focus. I did find that there is an event that meets this requirement, but is only available to IE... typical. For your information it is: "onbeforedeactivate" and it is cancelable. However since cross browser compatibility is important, we should not use this eventTrigger. Rather I found that the event mousedown occurs before the DOM starts its focus-changing behaviours.
So what we could do is:
$(document).on('mousedown', function(event) {
target = event.target; // the element clicked on
myTarget = document.getElementById("idBox"); // the element to keep focus
if (target !== myTarget) {
event.preventDefault(); //prevent default DOM action
event.stopPropagation(); //stop bubbling
return false; // return
}
});
There are many other ways of going about it. I personally don't like setting an eventListener to the entire document, but to demonstrate the basics it serves its purpose.
Footnote: A great article to read to learn more about event handling in Javascript is http://help.dottoro.com/ljtdqwlx.php An amazing resource I stumbled across.
回答2:
We know that it is the click function that cause the issue. So in the normal explorer like chrome, you can detact the mousedown event and then preventDefault.
But this doesn't work in ie, but we can use the beforedeactivate event instead http://msdn.microsoft.com/en-us/library/windows/apps/jj569321.aspx. It can be deteact in ie when the focus is changing. so just prevent it.
code would like this:
$inp.on('blur', function(){
self.hide();
});
isIE && $inp.on('beforedeactivate', function(evt){
mousedown && evt.preventDefault();
});
$holder.on('mousedown', function(evt){
evt.preventDefault();
mousedown = 1;
});
回答3:
inst.$target.on("blur", function() {
if (!$.suggestBox.$divCont.hasClass($.suggestBox.mouseOverClassName)) {
$.suggestBox.$divCont.css({'display': 'none'}); //reposition Suggestbox
return true;
}
inst.target.focus();
return false;
});
need to see your html. I don't think you are calling things correctly EX:
$.suggestBox
I think should be $(".suggestBox")
, but i cant tell without seeing your htnl
来源:https://stackoverflow.com/questions/14613804/is-there-a-way-to-use-event-preventdefault-with-focusout-if-not-why