In my latest code, I have an event handler for a focus on a textarea. When the user clicks on the textarea, that event-handler is triggered which sets some other DOM states based on the selected textarea. However, elsewhere in my program I want to programmatically set the focus of the textarea without triggering that event handler. I know Backbone, for instance, has a way to silently perform an action.
My only pseudo-solution is to temporarily set a variable:
var silence = true;
And then, in my event handler, only perform the logic if silence is false. The handler is still triggered, but the logic doesn't run.
Does anyone else know of better strategies for this?
You could temporarily unbind() the event, like this:
You have the following scenario where you handle the focus event:
function focus_handler() {
//focus handler code
...
...
}
$('#yourelement').bind('focus', focus_handler);
And now on the part of the code where you want to programmatically focus the element without triggering the event handler:
$('#yourelement').unbind('focus');
$('#yourelement').focus();
$('#yourelement').bind('focus', focus_handler);
<input type="text" name="input" id="input" value="0">
<input type="text" name="input" id="input2" value="0">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" type="text/javascript"></script>
<script>
$(function() {
$('#input').focus(function(a,b) {
if (b) alert('forced');
});
$('#input').trigger('focus', jQuery.Event("focus"));
});
</script>
When b argument of the event handler is present, the event is triggered by invoking $('#input').trigger('focus', jQuery.Event("focus"));. So you can make you handler function execute depending on normal focus or forced focus.
In jQuery, trigger() can take an event namespace. Only events bound with this namespace, and default behaviour, will be triggered.
So for example:
$('#yourelement').trigger('focus.anyOldNonsense');
should do the trick (provided no-one has used "anyOldNonsense" as an event namespace).
Edit: This works in 1.7.2 and 1.8.3, but there is a known bug in 1.9 onwards for adding data and namespaces to a "focus" event.
Since you can't prevent the event from happening, you need some kind of intermediary that decides whether or not to emit the event. So you would have the intermediary listen for all focus events and you'd have to tell that intermediary whether or not to re-emit the event. Then you'd listen on that intermediary rather than the dom node directly.
click here
try this hack to set onClick functions with params without firing them on instantiation.
Related
I am trying to make it so that if I press enter key or if element loses focus then it hides the element and shows a message. But the problem is that when I press the enter key and the element hides then it also triggers the blur event. It should only execute one of them.
Also how could I avoid having to repeat myself twice by calling the hideField() function. Can I call it only once (bur or key.enter)?
<input id="name" v-on:blur="hideField('name')" v-on:keyup.enter="hideField('name')">
Here is a fiddle.
http://jsfiddle.net/dag5ch26/3/
You should call the blur method on the keyup.enter event. This results in the blur event being triggered indirectly.
<input id="name" v-on:blur="hideField('name')" v-on:keyup.enter="$event.target.blur()">
Given the limitations of your example, I don't think it is necessary to fire the event on enter like you have it. As you see, the keyup.enter event also fires the blurs event, so why not rely on the blur exclusively? I understand you may have simplified your use case, but I don't see a reason for the keyup.enter here.
As a side note, instead of selecting the element by ID, you can just use
event.target for the element reference. E.g. #v-on:blur="hideField". The event is passed to hideField() automatically. Alternatively, you could do #v-on:blur="hideField($event.target)" which would just pass the element itself to the method. This simplifies your call(s) and reduces unnecessary lookups.
I've updated the fiddle here: http://jsfiddle.net/dag5ch26/7/
I don’t believe there is a way to do this currently, although a v-on-many would be nice in future.
You could bind the event handlers yourself in JavaScript during the created life cycle handler.
Something like the below (although IMo this may be worse than your current implementation):
Component code {
...
created() {
window.addEventListener(‘click keyup’, function() {
this.myComponentMethod(); }
} }
In the following example https://jsfiddle.net/anu4nits/449d5j8e/
<input type="text" id="in" />
<input type="button" value="click" id="button" />
$('#in').change(function () {
console.log('change event');
dialog.dialog("open");
});
$('#button').on('click', function (e) {
console.log('click event');
});
I have attached two events one is onchange event on text and other is click event on button. If I write something in textbox and clicks on button then handler of change event and handler of click event should get executed respectively. But as I am invoking the modal-dialog in the handler of change event, handler of click event is not getting executed, which is expected as modal- dialog won't allow any background activity. But this is only with Chrome and Mozilla. In IE handler for both the events are getting executed.
I want consistent behaviour for all browsers preferably I don't want click handler execution in IE. I also don't want to put some flag at global level for condition checking. Also I can't detach the event from button as in my application button ID and its handler are generating at runtime. Is there any other way I can stop the execution of click event from the handler of change event.
Click and Change both are separate events and they have their own stack. So you can't stop propagation of one from another as their target element are also different.
What you can do is to attach event at their common parent so that you have a common handler for them. There you can set flag and perform what you want.
I needed to prevent from immediate execution of a next function defined in the same onchange, e.g.:
<input onchange="Dont(this);Work()">link</input>
Here I needed the Dont() to conditionally stop all further functions like the Work(). I simply threw an exception, because anything else didn't work.
function Dont(button){
if($(button).data("somecondition")){
throw "NeedToStopEveryFurtherCodeExecution!";
}
}
The event.stopImmediatePropagation(); didn't help. I'm not sure why but I think there is an issue when using an external .js file.
I think this is simpler than to workaround this using conditions in every function that may be passed in the onchange. I hope this is not a really bad/deprecated way.
use stopPropagation, but easier solution is to go with a flag
$('#in').change(function(e) {
console.log('change event');
dialog.dialog("open");
e.stopPropagation();
});
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', ...)?
What's the best way to execute a function exactly once every time a button is clicked, regardless of click speed and browser?
Simply binding a "click" handler works perfectly in all browsers except IE.
In IE, when the user clicks too fast, only "dblclick" fires, so the "click" handler is never executed. Other browsers trigger both events so it's not a problem for them.
The obvious solution/hack (to me at least) is to attach a dblclick handler in IE that triggers my click handler twice. Another idea is to track clicks myself with mousedown/mouseup, which seems pretty primitive and probably belongs in a framework rather than my application.
So, what's the best/usual/right way of handling this? (pure Javascript or jQuery preferred)
Depending on your situation you can use different approaches, but I would suggest using namespaced event handlers with jQuery like this:
function eventHandler(event) {
// your handler code here
doSomeMagic();
}
var element = $('#element');
element.one('click.someNameSpace', function(event){
// first we unbind all other event handlers with this namespace
element.unbind('.someNameSpace');
// then we execute our eventHandler
eventHandler();
}).one('dblclick.someNameSpace', function(event){
// If this fires first, we also unbind all event handlers
element.unbind('.someNameSpace');
// and then execute our eventHandler
eventHandler();
});
I'm not sure this will work the way you want it, but it's a start, I guess.
Mousedown and mouseup works just like the click functions, unfortunately so much that when IE omits a click because of a doubleclick it will also omit the mousedown and mouseup. In any case, you can add both click and dblclick to the same object and feed the clicks through a function that sort out any click happening too close to the last.
<div onclick="clk()" ondblclick="clk()"></div>
lastclicktime=0
function clk(){
var time=new Date().getTime()
if(time>lastclicktime+50){
lastclicktime=time
//Handle click
}
}
I by the way just found out that, at least in Firefox the dblclick event is not given an event time, therefore I had to resolve to the Date method.
I'd like to invoke default keydown event handler from javascript. Is it possible?
If the event has an explicit event handler you can just invoke it directly:
// Precondition - the element has an explicit handler registered
element.onkeydown();
Otherwise, there's no way to explicitly tell the browser to do "what it would have done anyway". The only way to get this to happen is to not stop the event from bubbling - which can be a real pain if you want to set a timeout and then allow the event to continue, it's essentially not possible.
In most cases, though, you can invoke your own code on an event handler and let the keyDown event continue to the browser. And if this isn't possibel for whatever reason, you can usually write your own method that will simulate the effects of the event (e.g. change the content of an input field, submit the form, etc.)
There is no default keydown event. The keydown event occurs when the key is pressed on any form elements, followed immediately by the keypress event, and possibly the textInput event on text box when you enter a value. Then the keyup event is generated when the key is released
The following example shows the use of the onKeyDown event handler to display a message in the text box.
<body><form action="" method="POST" id="myForm"><input type="text" name="myText" onKeyDown="changeVal()"><script type="text/javascript" language="JavaScript">s1 = new String(myForm.myText.value)function changeVal() { s1 = "You pressed a key"
myForm.myText.value = s1.toUpperCase() }</script></form></body>