Sorry for my English, I'm not native English speaker.
I have problem with my code. I have on page something like this:
$('#hook label').on('click', function() {
console.log('ok');
icon = $(this).next('input').val();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="hook">
<label><input> <img src="http://placehold.it/35x35" ></label>
<label><input> <img src="http://placehold.it/35x35" ></label>
<label><input> <img src="http://placehold.it/35x35" ></label>
<label><input> <img src="http://placehold.it/35x35" ></label>
</div>
And this code is running twice if I click on image, but only one when I click on input or label element. How can I prevent to running this twice?
Here is example: http://jsfiddle.net/00akgoe7/2/
It's because of the default behavior of label. To stop that, you need to tell to the event object to stop is default behavior like this:
$('#hook label').on('click', function(ev) {
ev.preventDefault();
console.log('ok');
icon = $(this).next('input').val();
});
Clicking on a label associeted with the for attribute or inside the label, focus the input with a "fake" click event. This is why you get the event twice since by extension, if you click the input, you click the label (the parent) also.
It's two times because when you click on the label it send a click event also to the input and the new event bubbles back to the label. It's tricky :)
It's in all browsers for a better form usability.
So the another possible solution is:
$('label').click(function(e) {
if (e.target.tagName === "LABEL") {
alert("!! here")
}
});
Try it live: http://jsfiddle.net/8qffhwm3/2/
You just need to add a preventDefault().
$('#hook label').on('click', function(e) {
e.preventDefault();
console.log('ok');
});
I expect that it help you.
If you want prevent from the event being fired twice, you can use the 'mousedown' event handler. It will just be triggered once, as it is not triggered by standard by clicking the label.
Related
To move focus on the end of inputs when user click the input box,
I use something like this,
$(function() {
$('#test-input').on('click', function(evt) {
$target = $(evt.target);
var val = $target.val();
$target.val('').val(val);
});
}())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="test" id="test-input" value="abcdefgh" />
But if I change the 'click' to 'focus', it doesn't work.
$(function() {
$('#test-input').on('focus', function(evt) {
$target = $(evt.target);
var val = $target.val();
$target.val('').val(val);
});
}())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="test" id="test-input" value="abcdefgh" />
How different onClick and onFocus actions in that case?
There's some differences:
onClick: This event is fired whenever the user clicks in an object, like a button, an image, an input... After the click, then comes the:
onFocus: This event is fired when an element is selected, it doesn't need to be clicked, it can be done programmatically, calling .focus() or using the Tab key, for example. Also, using onfocus instead of onclick, can help to avoid bubbling.
To finish, use the snippet below (I added more inputs, cycle through it with TAB (or click too), you'll see the caret going to end on all of then.
Why I added a timeout?
Chrome Browser has an odd quirk where the focus event fires before the cursor is moved into the field, so, the event must wait to the cursor to get there before moving it to the end.;
$(function() {
$('.test-input').on('focus', function(evt) {
that = this;
setTimeout(function() {
that.selectionStart = that.selectionEnd = 10000;
}, 1);
});
}())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="test" class="test-input" value="abcdefgh" />
<input type="text" name="test" class="test-input" value="a1b2c3" />
<input type="text" name="test" class="test-input" value="abcdefghijklmnop" />
Extra:
If you are programming just for mobiles, will be nice to take a look at touchEvents (https://developer.mozilla.org/pt-BR/docs/Web/Events/touchstart)
This should be working just fine the first time you click on the textbox. This is when the focus event is triggered, since you're actually 'focusing on' the item. From then on, until you click anywhere outside the element, your item will already have the focus and therefore will not execute the onfocus event.
The main difference is focus event call any time when you will focus on input field like if you use tab button and focused on input field but in case of click you need to click on input field.
I think that it has to do with the fact that the code executed at the click is executed before focusing on the input and affecting a position to the cursor.
On the other hand, when you listen to the focus event, the cursor has already a position and stays at this position.
That's pure personal theory. However, if you want to make it work, I found a great solution that works in Chrome on this question: Use JavaScript to place cursor at end of text in text input element
You need to clear the value of the input, wait for one millisecond, and reapply the value:
$(function() {
$('#test-input').on('focus', function(evt) {
$target = $(evt.target);
var val = $target.val();
$target.val('');
setTimeout(() => {
$target.val(val)
},1)
});
})
I'm trying to make a zoomable image block in an HTML page using javascript.
Now zooming in is finished by capturing Doubleclick event and some simple functions.
Problem is here that I have some elements (div tags like tile) and want to have a function called when right clicked on some of them.
How can I do this?
You can use the contextmenu event:
<div oncontextmenu="javascript:alert('Right Click Performed!');return false;">
Right click on me!
</div>
And then add a listener:
el.addEventListener('contextmenu', function(ev) {
ev.preventDefault();
alert('Right Click Performed!');
return false;
}, false);
javascripts event.button function will give you the mouse button you clicked.
<img onMouseDown="alert(event.button)" src="yourimage" />
right click should return 2 but best check each browser
I am handling mousedown & oncontextmenu events to prevent text & image selection, right click and drag. The code is as follows -
<body oncontextmenu="return false;" onmousedown="event.preventDefault ? event.preventDefault() : event.returnValue = false">
<input type="text" name="testInput" id="testInput">
</body>
I guess the problem is it is also preventing the focus on input elements, as I am preventing default & returning false for onmousedown event, so it is not letting control switch to input focus, so I cant type any thing inside it. I tried to debug it by following code.
<script type="text/javascript">
$(function(){
$( "#testInput" ).on("focus",function(){
console.log("input focused");
});
});
</script>
When I removed the onmousedown attribute from body, it is giving me the desired message on cosole.
any help... Thanks in advance.
You can check if the mousedown/contextmenu event is happening on any inside element and allow the default action if so and if not prevent the default action by using below
document.getElementsByTagName("div")[0].addEventListener("mousedown",function(e){
if(e.target.id=="testInput"){
} else{
e.preventDefault();
}
});
document.getElementsByTagName("div")[0].addEventListener("contextmenu",function(e){
if(e.target.id=="testInput"){
} else{
e.preventDefault();
}
});
Check the Fiddle
There are two elements in play:
$('#myInput') // an input field for search
$('#myList') // a list to display search results
I want to hide the list when the input no longer has focus, like so:
$('#myInput').blur(function() {
$('#myList').hide();
});
This works great, except when a list item is clicked, because the blur event fires and hides the list before the click is registered. The goal is for the list to stay visible when any part of the list is clicked, even though this will cause the input to blur.
How can I do this? Thanks!
You can accomplish this by keeping a global variable, and setTimouts, to wait a delay of 200ms and then check if one of the 2 elements have focus.
var keepFocus = false;
function hideList(){
if(!keepFocus){
$('#myList').hide();
}
}
$('#myInput').blur(function() {
keepFocus = false;
window.setTimeout(hideList, 200);
}).focus(function(){
keepFocus = true;
});
$('#myList').blur(function() {
keepFocus = false;
window.setTimeout(hideList, 200);
}).focus(function(){
keepFocus = true;
});
I've faced with the exact same problem, so this is how I solved it.
I came up with the fact that blur() fires earlier than click().
So I've tried to change click() to mousedown() and found out that mousedown() fires before blur().
And to imitate click() you'll have to fire mousedown() and then mouseup()
So in your case I would do something like this:
var click_in_process = false; // global
$('#myList').mousedown(function() {
click_in_process = true;
});
$('#myList').mouseup(function() {
click_in_process = false;
$('#myInput').focus();
// a code of $('#myList') clicking event
});
$('#myInput').blur(function() {
if(!click_in_process) {
$('#myList').hide();
// a code of what you want to happen after you really left $('#myInput')
}
});
Demo / example: http://jsfiddle.net/bbrh4/
Hope it helps!
You need to be able to say "do this blur() unless the list gains focus at the same time".
This question says how to detect if an element has focus: Using jQuery to test if an input has focus
Then all you need to do is:
$("#myInput").blur(function () {
if (!$("#myList").is(":focus")) {
$("#myList").hide();
}
});
Pigalev Pavel's answer above works great.
However, If you want an even simplier solution, you can just "prevent default" in the "mousedown" of an element to prevent the blur event from taking place. (since preventing default actually means that in the end, the input never looses focus in the first place!)
Of course, this is only if you're alright with preventing default in the div. It does have some side-effects, like the text is no longer selectable. As long as that's not an issue, this will work.
I suppose if you hold the mouse down over the div, move the mouse outside of the div, and then release the mouse, it also doesn't fire the "blur" event. But in my case, I wasn't too worried about that either, since the click started in the target div.
$("input").focus(function(){
$(this).val("");
});
$("input").blur(function(){
$(this).val("blur event fired!");
});
$("div").mousedown(function(e){
e.preventDefault();
})
div{
height: 200px;
width: 200px;
background: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input>
<div>
Click here to prevent blur event!
</div>
The best way to do this is to attach an event handler to the body element, then another handler to the list that stops event propagation:
$(body).click(function () {
$("#myList").hide();
});
$("#myList").click(function (e) {
e.stopImmediatePropagation();
});
This listens for a click outside of #myInput and hides #myList. At the same time, the second function listens for a click on #myList and if it occurs, it prevents the hide() from firing.
I want my (ExtJS) toolbar buttons not to grab the focus on the web page when they are clicked, but to do their "thing" while leaving the focus unchanged by the click. How do I do that?
Cancelling the default behavior of onmousedown prevents an element from getting the focus:
// Prevent capturing focus by the button.
$('button').on('mousedown',
/** #param {!jQuery.Event} event */
function(event) {
event.preventDefault();
}
);
document.activeElement stores the currently focussed element.
So on your toolbar, you can add a "mousedown" handler to this function :
function preventFocus() {
var ae = document.activeElement;
setTimeout(function() { ae.focus() }, 1);
}
Try this example :
<html>
<head>
<script>
function preventFocus() {
var ae = document.activeElement;
setTimeout(function() { ae.focus() }, 1);
}
</script>
</head>
<body>
<input type="text"/>
<input type="button" onmousedown="preventFocus()" onclick="alert('clicked')" value="Toolbar" />
</body>
</html>
This usually does the trick for me:
<button
tabindex="-1"
onclick="javascript:console.log('do your thing')"
>My Button</button>
From https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex:
A negative value (usually tabindex="-1") means that the element should be focusable, but should not be reachable via sequential keyboard navigation. It's mostly useful to create accessible widgets with JavaScript.
I don't think there's an easy way to do what you want to do because it's the browser's default behaviour.
You could of course blur() the button as soon as it is clicked, but that would simply unselect everything. To have the previously active object regain focus, you'd have to create a "memory" of sorts by adding a blur handler for every element to keep track of which element had/lost focus last (store the id of the element in a global and update it when an element loses focus).
The top-voted answer is technically correct, but depends on jQuery...
Here's a simpler example:
<span onclick="document.execCommand('bold', false);" onmousedown="event.preventDefault();"></span>
My solution is to replace <button /> with <div /> and style it as a button.
Looks like Div doesn't take a focus on it when you click it.
Because the toolbar buttons are just styled ordinary HTML button elements then this is an actual browser behavior, and you should think twice before changing it. But nevertheless...
You should be able to prevent the botton from receiving focus by just returning false from its onclick handler.
Maybe you should try to use stateful and state change properties for form fields or whatever to get focus back?
I would attach one blur event listener to all fields. This listener should save the field, that lost the focus, in a global variable.
Then all the toolbar button should get one focus event listener. This listener should focus the field, that was saved as described above.
This code should work, although it didn't test it
<script>
function focusor(){
document.getElementById('focus').focus;
}
document.onkeydown = focusor;
document.onclick = focusor;
</script>
<div style="width: 0px; height: 0px; overflow: hiddden;">
<button id="focus"></button>
</div>
What I have found, is you will have to make a dummy element, I found buttons to work best in this situation. put the button in a div and make the div 0px.
[do not make the div display none, some browsers will just ignore it]
Basically any click or button presses, it will focus on this dummy button.
I had a project very similar and whenever they pressed the down key it selected the first button on the page, this just focuses on the button over and over again.
Sort of jacked up, but it works.
All these answers are wack. Here's a very excellent trick that only uses CSS
<button type="submit" disabled>
<span>Submit</span> <!-- the <span> is the secret -->
</button>
Now in your css:
button[disabled] > * {
pointer-events: none;
}
The trick is the inner span has to be used, otherwise the button will still steal focus away from inputs.