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(); }
} }
Related
How would i replace internally triggered events of medium-editor with my custom ones or simply change internally designed behaviour?
In this hierarchy
<div>
<textarea class='editable'></textarea>
</div>
I bind a click handler to the div and do e.stopPropagation() and e.preventDefault().
I also try adding after the instantiating of medium-editor.
var editor = new MediumEditor('.editable')
.subscribe("editableClick", function(e){
e.preventDefault();
});
Every way i try textarea gets focused and cursor starts to blink.
For example intial click event adds an element to the dom with a class .medium-editor-element should i dive to source to modify this behaviour?
Or maybe i would like it to work with not a click but a double click.
Anyone familiar with the internal workings of medium-editor?
After trial and error and the help of dev tools i found the way to do what i want.
But i think this question is still answerable because i did it by modifying the source of medium-editor.
So, in medium-editor.js in line 2725 there is setupListener function.
There are 3 main events attached there to case 'externalInteraction': 2731th line.
mousedown,click,focus.
Starting from 2959th line there are the attached handlers for those events.
handleBodyClick,handleBodyFocus,handleBodyMousedown
The mousedown is important for my case because it is the first one that fires and should be prevented and accepted in different cases.
In the end i added a dblclick and handleBodyDblClick to source then put some logic in handleBodyMousedown to prevent the default behaviour of mousedown event in some cases.
Anyway, from the source as i can understand there are no override methods or hooks to modify medium-editor internal events.
It would be nice to have that feature.
Or if i am wrong i would like to know if there is a better way to do all these.
Wondering if someone out there can shed some light on how to properly use element.triggerHandler() for the paste and keypress events inside of an angularjs unit test.
I have two directives, one for limiting the ability of a user to continue firing keypress events in an element once a length limit has been reached. The second is to prevent the user from pasting text into an element if the length of the text would exceed a limit.
See the following plunker for a full example including my failing tests: https://plnkr.co/edit/5Yyv2cnn3dRKzsj2Lj61?p=preview
For the paste test I know I'm not using the correct syntax but have been unable to find how to properly do this. Any suggestions?
element.triggerHandler('paste', 'astring')
For the keypress test, I believe I'm firing the event correctly but it doesn't seem to be updating the value of the element (retrieved using element.val())
Been stuck on this for a bit, any help would be greatly appreciated. Thanks!
Let's us start with a short breakdown of what might happen (really up to the browser implementation) when a user presses and releases the 1 key with the focus on an input:
Event keydown is fired
Event keypress is fired
Value of input is changed to 1 and event input is fired
Event keyup is fired
There is no way in JS to actually simulate a user pressing a key. What you can simulate are the things that (usually) happen when a user does so, for example the steps above.
The triggerHandler function executes all handlers bound with jQuery for the specified event type on the specific element.
So using triggerHandler with keypress will not simulate a user pressing a key, it will only fire the event, like step 2 above. The value will not be changed, since that happens in another step.
Now, one would think that in your tests for the limitKeypressLength directive, you can simply simulate the first part of step 3 above yourself (just setting the value manually):
for (var i = 0; i < 10; i++) {
element.triggerHandler({type: 'keypress', keyCode: 49});
element.val(element.val() + '1');
}
expect(element.val()).toBe('1111111111');
element.triggerHandler('keypress', {which: 49});
element.val(element.val() + '1');
expect(element.val()).toBe('1111111111');
This will not work however, since even if the eleventh keypress event is caught in your directive, the code below will still execute and update the value.
The basic functionality of the limitKeypressLength directive is to listen on the keypress event and either call event.preventDefault or not based. This is what you want to test.
For example:
// Set value to something longer than allowed
element.val('123456789123456789');
// Create the event
var e = jQuery.Event('keypress', {
keyCode: 49
});
// Create a spy
spyOn(e, 'preventDefault');
// preventDefault should not have been called yet
expect(e.preventDefault).not.toHaveBeenCalled();
// Trigger the event
element.triggerHandler(e);
// Assert that preventDefault has been called
expect(e.preventDefault).toHaveBeenCalled();
Demo: https://plnkr.co/edit/ktmcBGSuTdMnvqVRlkeQ?p=preview
Now you can as easily test for when the elements value is set to equal/below the allowed value.
Basically the same goes for the limitPasteLength directive, since its purpose is also to call preventDefault based on a condition, only that there is some additional mocking to do.
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.
What does event binding mean? I always come across this word whenever I search around the internet and whatever I try to look for the meaning, it's still vague to me #_#
A while ago, while reading some blogs regarding JavaScript I see people using this sacred word that I cannot grasp.
Event binding refers to telling the browser that a particular function should be called whenever some 'event' occurs. Events mostly relate to user input, such as clicks.
An example of binding to an event in jQuery can be the following:
$("#elem").bind("click", function() {
alert("Clicked!");
});
This binds a function to click event of DOM object with identifier elem. When user clicks it, an alert (message box) will be shown. Binding is done by invoking the jQuery bind function but there are other means to do that, (e.g. jQuery click function in case of binding to click event).
When you bind something to an event, it will be triggered when the event is fired. It's like gluing a fog horn to the brake pedal on your car.
When you perform an action on a web page, it will trigger an event. This might be something like:
Click a button
Select a value from a drop down
Hover the mouse over an item
These events can be captured in your JavaScript code.
A common (and often misguided) way of capturing events is to do so on the HTML element itself (as shown in the onclick attribute below)
<input id="MyButton" type="button" value="clickme" onclick="Somefunction()" />
So, when the user clicks the button, the SomeFunction function will be executed.
However, it is considered a better approach to adopt a technique called 'late-binding'. This ensures that your HTML and JavaScript are kept completely separate.
So, we can modify the above exmample like so:
document.getElementById("MyButton").onclick = function(){
//functionality here.
}
jQuery makes this even easier:
$("#MyButton").click(function(){
//functionality here.
});
Binding in JS, is to capture some events (like focus, click, onmouseover, etc) and perform some other stuff before the actual process starts.
Detailed explanation:
http://triaslama.wordpress.com/2008/07/22/four-ways-javascript-binding-event-listeners/
http://api.jquery.com/bind/
I have HTML similar to the following in my page
<div id="someDiv">
<img src="foo.gif" class="someImg" />
</div>
The wrapper div is set up such that when it is clicked, it's background-color changes using the following jQuery code.
$("div").click(function(event){
$(this).css("background-color", "blue");
});
I also have some jQuery associated with my img that will do some other function (for the sake of argument I am going to display and alert box) like so:
$("img[class=someImg]").click(function(event){
alert("Image clicked");
});
The issue I have come across is that when I click on the img, the event associated with the div is also triggered. I'm pretty sure that this is due to the way that jQuery (or indeed JavaScript) is handling the two DOM elements - clicking the img would require you to also technically click the div, thus triggering both events.
Two questions then really:
Is my understanding of the
DOM/JavaScript flawed in some way or
is this actually how things are
occurring?
Are there any jQuery methods that
would allow me to perform actions on
a child element without invoking
those associated with its parent?
That is known as event bubbling, you can prevent it with stopPropagation():
$("img[class=someImg]").click(function(event){
alert("Image clicked");
event.stopPropagation();
});
.
Is my understanding of the DOM/JavaScript flawed in some way or
is this actually how things are
occurring?
That is because of what is known event bubbling.
Are there any jQuery methods that would allow me to perform actions
on a child element without invoking
those associated with its parent?
Yes, you need stopPropagation()
No, this is by design. Events bubble up through the entire dom, if you put another handler on body, it would fire too
Yes :) JQuery normalizes the event object, so adding event.stopPropagation() in your img click handler will give you the behavior you expect on all browsers
The problem you just facing is called "event bubbling". That means, if you click on a nested
element, that click event will "bubble up" the DOM tree.
If other elements also are bound to an click event, their listeners will fire aswell.
Solution to prevent this is called:
stopPropagation()
which is used within your event handler
$("img[class=someImg]").click(function(event){
event.stopPropagation();
alert("Image clicked");
});
This is what's called event bubbling, and you can stop it to get the behavior you want with .stopPropagation() (or return false; if you want to stop the event completely, including handlers on the same level), like this:
$("img[class=someImg]").click(function(event){
alert("Image clicked");
event.stopPropagation();
});
You can view a demo here, comment it out and click run again to see the difference.
The short version is that when most event types happen, they happen on the immediate element, then bubble up the DOM, occurring on each parent as they go. This is not jQuery specific at all, native JavaScript does this. If you're more curious, I'd read the linked article, it has a great explanation of what's going on.