This question already has answers here:
How do I detect a click outside an element?
(91 answers)
Closed 9 years ago.
The problem was that I need a "onClickOut"-Event.
For example:
You have a DIV viewing on hovering (onMouseOver) some Button or what ever.
If you click outside the element it needs to hide, but if you say $("body").click it also will be hidden when you click into the element itself. :/
Now I listen the mouseposition and when mouseleave() I set a var on clicking into my element. In the next step I listen a generelly click-event (body) but I ask if the var was set. If not it has to be a click outside my element, so I can hide my element.
I hope you can use it:
$("#schnellsuche_box").mouseleave(function() {
var inside;
$("#schnellsuche_box").click(function() {
inside = true;
});
$("body").click(function() {
if(!inside) {
$("#schnellsuche_box").hide();
}
});
delete inside;
});
You do that by listening to a click on the document level, and inside the event handler you check if the clicked element was #schnellsuche_box or any element inside #schnellsuche_box by using closest(), like so :
$(document).on('click', function(e) {
if ( ! $(e.target).closest('#schnellsuche_box').length )
$('#schnellsuche_box').hide();
});
FIDDLE
You need to stop the #schnellsuche_box click event from bubbling up to the body click event (that's default event propagation) by doing return false:
$("#schnellsuche_box").click(function() {
inside = true;
return false;
});
Try this:
$("body").click(function(e) {
var $target = $(e.target);
if (!$target.is('#schnellsuche_box') &&
!$target.parents('#schnellsuche_box').length) {
alert('outside');
}
});
$("#schnellsuche_box").on("click",function(event) {
event.preventDefault();
event.stopPropagation();
});
Related
I'm using a hidden input to keybind my app with it but without triggering events when i write on other input-fields
-clicks on element {
-hide element
-creates an input text-field(to edit the element)
-focus the input
- on blur or submit changes the element and remove the input
}
but if you add this new event :
- click anywhere in the container {
-focus the hidden app input (so it can use keybinding)
}
when user clicks on the element it ends firing the blur event without letting the user edit it first because its activating the second block event.
so it's either skipping the focus part of the first block
or the focus of the second block is activating after the focus on the first one
I'm maybe using the wrong approach to solving it
but I don't know why it's behaving that way.
actual code:
$("#hiddenInput").focus()
var elem = $("#nameClip");
function evenConditional(id) {
if ($(id).val() !== "") {
elem.text($(id).val())
storedObj.name = $(id).val();
}
$(id).parent().remove();
elem.show();
}
$("#name").on("click", function() {
elem.hide();
elem.after(
$("<form/>").append(
$("<input/>").addClass("rename")
)
);
$(".rename").focus();
});
$(".rename").blur(function() {
evenConditional(this);
});
$(".rename").closest("form").on("submit", function(e) {
e.preventDefault();
evenConditional(this);
});
/// regaining focus on click
$(".container").on("click", function(e) {
$("#hiddenInput").focus()
});
css:
#hiddenInput {
position:absolute;
top: -2000;
}
Since the #name element is in the .container element, when you click on it, the click event bubbles up to the container, causing the click-event handler for the container to get executed.
One way to fix this would be to stop the click event from bubbling:
$("#name").on("click", function(e) {
e.stopPropagation();
There can be side effects from doing that though. Particularly, there may be other event handlers that will not get executed because of that. Such as handlers that close opened menus.
The other option would be to place conditional logic in the click handler for the container so it does not execute if the click originated with the name element.
$(".container").on("click", function(e) {
var nameElement = $("#name")[0];
if ((e.target != nameElement) and !$.contains(nameElement , e.target)) {
$("#hiddenInput").focus();
}
});
This question already has answers here:
How do I detect a click outside an element?
(91 answers)
Closed 8 years ago.
I have created some code which will hide/unhide a hidden div when a div("button") is clicked. I would also like the div to be hidden when anywhere on the screen is clicked. These pieces of code seem to be conflicting with each other.
$(document).ready(function () {
$(document).on("click", "#help-icon", function () {
console.log('hi');
$("#help-menu").toggle();
});
$(document).mouseup(function (e) {
var hlpcont = $("#help-menu");
if (!hlpcont.is(e.target) &&
hlpcont.has(e.target).length === 0) {
hlpcont.hide();
}
});
});
jsfiddle: http://jsfiddle.net/CEs4c/1/
$(document).click(function (eventObj) {
if (eventObj.target.id != "help-icon") {
$("#help-menu").hide();
} else {
$("#help-menu").toggle();
}
});
EDIT: If you want to click on the div that appears without hiding it again:
$(document).click(function(eventObj)
{
if (eventObj.target.id == "help-icon") {
$("#help-menu").toggle();
} else if($(eventObj.target).hasClass("help-dropdown")) {
$("#help-menu").show();
} else {
$("#help-menu").hide();
}
});
In my test, the mouseup function fires before the click function. The mouseup function checks for the target of the event. When you click on the button, the target of the mouseup event is the button, so the mouseup function hides the div, then the click function fires and toggles the div back to visible.
What I would do instead is just check the target of the event in mouseup and skip the click event:
$(document).mouseup(function (e)
{
var hlpcont = $("#help-menu");
var hlpIcon = $("#help-icon");
if(hlpIcon.is(e.target)){
hlpcont.toggle();
}else
{
hlpcont.hide();
}
});
This question already has answers here:
disable a hyperlink using jQuery
(11 answers)
Closed 8 years ago.
I do have the following click function on a div element. Inside the div element are links. How can I stop the click function on this links? I tried z-index but it doesn't work.
$('.thumb.flip').click(function () {
if ($(this).find('.thumb-wrapper').hasClass('flipIt')) {
$(this).find('.thumb-wrapper').removeClass('flipIt');
} else {
$(this).find('.thumb-wrapper').addClass('flipIt');
}
});
Add code to stop the click from propagating from the links up the DOM to the div:
$('a').click(function(e){e.stopPropagation();})
See http://api.jquery.com/event.stoppropagation/
jsFiddle example
Try e.preventDefault()
$('.thumb.flip').click(function (e) {
e.preventDefault();
if ($(this).find('.thumb-wrapper').hasClass('flipIt')) {
$(this).find('.thumb-wrapper').removeClass('flipIt');
} else {
$(this).find('.thumb-wrapper').addClass('flipIt');
}
});
Capture the event object:
$('.thumb.flip').click(function (evt) {
Test to see what sort of element was clicked:
if (evt.target.tagName.toLowerCase() === "a") {
return true;
}
Use the mouse down event and in your handler call event.stopPropagation() and event.preventDefault();
if click target is an a just return false else do normal stuff...
$('.thumb.flip').click(function (e) {
if ($(e.target).is('a')) {
return false;
}
});
z-index won't do anything, however if you want to prevent clicks from css you can add pointer-events property to links and set the value none. That will disable all kind of events on links.
$('.thumb.flip').click(function (e) {
if (e.target.nodeName==="A") { //if target is an anchor, ignore
return;
}
$(this).find('.thumb-wrapper').toggleClass('flipIt') //toggle class
});
If you can edit markup do this:
<a href="javascript:void(0);" ></a>
I have an editable element inside a div which itself is clickable. Whenever I click the x-editable anchor element, the click bubbles up the DOM and triggers a click on the parent div. How can I prevent that? I know it's possible to stop this with jQuery's stopPropagation() but where would I call this method?
Here's the JSFiddle with the problem: http://jsfiddle.net/4RZvV/ . To replicate click on the editable values and you'll see that the containing div will catch a click event. This also happens when I click anywhere on the x-editable popup and I'd like to prevent that as well.
EDIT after lightswitch05 answer
I have multiple dynamic DIVs which should be selectable so I couldn't use a global variable. I added an attribute to the .editable-click anchors which get's changed instead.
editable-active is used to know if the popup is open or not
editable-activateable is used instead to know if that .editable-click anchor should be treated like it is
$(document).on('shown', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).attr("editable-active", true);
});
$(document).on('hidden', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).removeAttr("editable-active");
});
The check is pretty much like you've described it
$(document).on("click", ".version", function() {
$this = $(this)
// Check that the xeditable popup is not open
if($this.find("a[editable-active]").length === 0) { // means that editable popup is not open so we can do the stuff
// ... do stuff ...
}
})
For the click on the links, simply catch the click event and stop it:
$("a.editable-click").click(function(e){
e.stopPropagation();
});
The clicks within X-editable are a bit trickier. One way is to save a flag on weather the X-editable window is open or not, and only take action if X-editable is closed
var editableActive = false;
$("a.editable-click").on('shown', function(e, reason) {
editableActive = true;
});
$("a.editable-click").on('hidden', function(e, reason) {
editableActive = false;
});
$("div.version").click(function(e) {
var $this;
$this = $(this);
if(editableActive === false){
if ($this.hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
}
});
Fixed Fiddle
It's not pretty, but we solved this problem with something like:
$('.some-class').click(function(event) {
if(event.target.tagName === "A" || event.target.tagName === "INPUT" || event.target.tagName === "BUTTON"){
return;
}
We're still looking for a solution that doesn't require a specific list of tagNames that are okay to click on.
Basically I want user to click on any .editable item, which makes an input appear, copy its styles, and then if they click anywhere else, I want the input to disappear and the changes to save. I'm having difficulty making this work. I've seen a solution using event.stopPropagation, but I don't see how to include it the way I have my code structured:
$(function() {
var editObj = 0;
var editing = false;
$("html").not(editObj).click(function(){
if (editing){
$(editObj).removeAttr("style");
$("#textEdit").hide();
alert("save changes");
}
});
$(".editable").not("video, img, textarea")
.click(function(event) {
editObj = this;
editing = true;
$("#textEdit")
.copyCSS(this)
.offset($(this).offset())
.css("display", "block")
.val($(this).text())
.select();
$(this).css("color", "transparent");
});
}
copyCSS function from here
I need to distinguish between clicks on the editable object, and clicks away from it, even if that click is onto a different editable object (in which case it should call 2 events).
Try this:
$('body').click(function(event) {
var parents = $(event.target).parents().andSelf();
if (parents.filter(function(i,elem) { return $(elem).is('#textEdit'); }).length == 0) {
// click was not on #textEdit or any of its childs
}
});
$(".editable").not("video, img, textarea")
.click(function(event) {
// you need to add this, else the event will propagate to the body and close
e.preventDefault();
http://jsfiddle.net/dDFNM/1/
This works by checking if the clicked element, or any of its parents, is #textEdit.
The event.stopPropagation solution can be implemented this way:
// any click event triggered on #textEdit or any of its childs
// will not propagate to the body
$("#textEdit").click(function(event) {
event.stopPropagation();
});
// any click event that propagates to the body will close the #textEdit
$('body').click(function(event) {
if (editing) {
$("#textEdit").hide();
}
});
http://jsfiddle.net/dDFNM/2/
The problem is that you are not correctly binding to the editObj. Perhaps it will help if you move the binding to inside your .editable click handler, or even better use live() or delegate().
$("html").not(editObj)... is bound once at document ready time, and at that time editObj is false