Two OnClick events overlap - javascript

I have an element inside an element, when I click the element underneath I want the slider to open. When I click on the outermost element I want the slider to close.
Unfortunately when I click on the outermost it clicks the underneath element as well. Is there a way to click only on the outermost element ignoring the click on the underneath element? The events are triggered on click and executed with javascript.
I tried with z-index but it still captures the underneath element clicked as well, and because the functions are contrary to one another nothing happens.
edit: on a "code is worth 1000 words" tip
var $target = $(this).data('pos', i) //give each li an index #
$target.data('hpaneloffsetw', $target.find('.hpanel:eq(0)').outerWidth()) //get offset width of each .hpanel DIV (config.dimensions.fullw + any DIV padding)
$target[haccordion.ismobile? "click" : "mouseenter"](function(){
haccordion.expandli(config.accordionid, this)
config.$lastexpanded=$(this)
})
if (config.collapsecurrent){ //if previous content should be contracted when expanding current
$('.close').click(function(){
$target.stop().animate({width:config.paneldimensions.peekw}, config.speed) //contract previous content
})
$target.dblclick(function(){
$(this).stop().animate({width:config.paneldimensions.peekw}, config.speed) //contract previous content
})
}
Because the code is borrowed, I don't understand much of it. But basically I want the "click" : "mousteenter" function to work on click, without interfering with the .close().click

It sounds like you need to stop the click event bubbling up the DOM to be caught by parent elements. You can use stopPropagation() to do this:
$('.close').click(function(e) {
e.stopPropagation();
$target.stop().animate({ width: config.paneldimensions.peekw }, config.speed);
})
$target.dblclick(function(e) {
e.stopPropagation();
$(this).stop().animate({ width: config.paneldimensions.peekw }, config.speed);
})

Try the following fiddle
$("#outer").click(function(){alert("outer clicked")});
$("#inner").click(function(e){
alert("inner clicked")
e.stopPropagation();
});

To identify the element you have "really" clicked on, you can try to identify it through accessing the target property of the jquery-event-object.
After you identified the target you clicked on, you could prevent other event handlers from firing.

Use CSS specific jquery to point exact element like below, use > to point exact child
table > tbody > tr > td > input[type='text']
like this.

Related

jQuery - remove element on blur BUT catch click on his children

I have following code:
$('#myEl').blur(function(){
$(this).remove('.children');
});
But the children element have links inside, with another jQuery actions which doesn't trigger because the .children is removed on blur, which I guess is triggered before the click action. Simple example:
Children is visible and #myEl have focus
I click on the children link
#myEl loses his focus
Children element is removed
Children link action is not triggered, because I guess link is not present anymore
How to solve this? I was trying to delay remove:
$(this).delay(100).remove('.children');
With no luck.
If you are working with the delay way, you can't use jQuery .delay() since it only work on queued element (with animation).
You can use setTimeout :
$('#myEl').blur(function(){
var $this = $(this);
setTimeout(function(){
$this.remove('.children');
}, 100)
});
I've tried it with mousedown event and it worked fine. I don't thing adding a delay is always a good option.
<input type="text" id="myEl"></input>
<div class="children" >div child</div>
<script>
$('#myEl').blur(function(e){
$('.children').remove();
});
$(".children").mousedown(function() {
window.open('http://www.google.com')
});
</script>
And if you really want to add the click event for a specific reason then you can try this:-
$('#myEl').blur(function(e){
if(mousedown){
window.open('http://www.google.com');
mousedown = false;
}
$('.children').remove();
});
$('.children').click(function(e){
window.open('http://www.google.com')
});
$(".children").mousedown(function() {
mousedown = true
});
what about simply making the child elements hidden after a click? Or maybe even having the child itself remove all children from its parent container after it has processed the click?
$('#myEl').blur(function(){
$(this).children('.children').hide();
});
$('.children').on("click",function(){
// perform your click-code actions here
alert("I did it!");
// now remove your child elements from the parent
$(this).parent().children('.children').remove();
});

Masonry - deleting elements by clicking on something else, than the element itself

In Masonry, it is possible to delete an element by clicking on it. The catch is, that You have to click directly on that element - so if you use these "bricks" as an image gallery (as long as these photos are included as a background image) You can delete them, by clicking on the element. The problem is, when you use these as some messages/info/other content containers. Then, due to formatting-related stuff the parent element gets "hidden" behind other tags, and You can't actually click on it.
The problem is shown here:
http://jsfiddle.net/dan1410/SfU5T/
You can close red boxes, but not green ones, as they are overlapped by another elements.
I've tried code like:
eventie.bind( container, 'click', function( event ) {
// don't proceed if item was not clicked on
if ( !classie.has( event.target, 'closeable' ) ) {
return;
}
// remove clicked element
msnry.remove( event.target );
// layout remaining item elements
msnry.layout();
});
});
and
var todelete = document.querySelector('.closeable');
eventie.bind( container, 'click', function( event ) {
// remove clicked element
msnry.remove( todelete );
// layout remaining item elements
msnry.layout();
});
});
but You still have to click directly on the element You'd like to close...
My masonry content structure looks like
<div id="masonry" >
<div class="item blue closeable">
<div id="itheader"><h2 class="secsectiontitle">Space available</h2></div>
<div id="itcontent">
some statistics here...<br/>
and here, too
</div>
</div>
Only elements with .closeable class are supposed to be closeable.
So, the question is: how to close an element using a button/a link?
I'm not very familiar with JS, so I'd like to ask You guys for help. Thank You in advance!
Unless there are handlers that stops the propagation of the click event on children elements, the click event should bubble up without any issues.
Also, if you are using jQuery, you should use the jQuery Masonry's API.
Note: I couldn't access your fiddle and couldn't test the solution
var $container = $('#masonry').on('click', '.closeable', function (e) {
$container.masonry('remove', e.currentTarget);
$container.masonry(); //layout
$container.masonry('reloadItems'); //OP said it was also required
});

Div slide up when click in items inside it

I have a div that slides down (opens) when I click a certain input select. Inside this div, I have some other input selects and my objective is to slide up the div when I click on the rest of the page.
My problem:
The div slides up when I select some item in the input selects inside it, and I don't want this to happen.
Is there some way to slide up the div only when I click outside it?
Why are the selects inside the div making it to slide up as well?
This is my javascript to slide up the div:
$(document).mouseup(function (e) {
var container = $('.myDiv');
if (container.has(e.target).length === 0) {
$(container).removeClass('close');
$(container).addClass('open');
$(container).next().slideUp(200);
}
});
The div slides up when I select some item in the input selects inside
it, and I don't want this to happen.
Is there some way to slide up the div only when I click outside it?
Why are the selects inside the div making it to slide up as well?
Use event.stopPropagation() on the child element(s) to prevent the slide event being triggered by them.
event.stopPropagation - Prevents the event from bubbling up the DOM
tree, preventing any parent handlers from being notified of the event.
Here's a simple jsFiddle and the basic example below.
jQuery:
$('div').click(function(){
$('#slideMeUp').slideUp();
});
$('select').click(function(e){
e.stopPropagation();
});
HTML:
<div>Clicking here will trigger it!
<select>
<option>This won't trigger the click event anymore!</option>
</select>
Clicking here will also trigger it!
</div>
<div id="slideMeUp">Only clicking the outer div will slide me up!</div>
you can check you e.target.id with your container id
$(document).mouseup(function (e) {
var container = $('.myDiv');
if(e.target.id==$(this).attr('id'))
{
if (container.has(e.target).length === 0) {
$(container).removeClass('close');
$(container).addClass('open');
$(container).next().slideUp(200);
}
}
});
If it's specific items that are causing problems, perhaps something like this?
On click tell it to to slideUp your div as long as the clicked item is "not" in the list.
('body').click(function(event) {
if (!$(event.target).is('#id_of_item .class_to_ignore')) {
var container = $('.myDiv');
$(container).removeClass('close');
$(container).addClass('open');
$(container).next().slideUp(200);
}
});
I'd suggest binding mousedown rather than mouseup. There are inconsistencies in behaviour between browsers, this may have something to do with your issue.
You should also add some logic to check the clicked element isn't the div itself, clicking just outside of an input, but still inside of the div would currently cause the slideUp to occur.
if (!container.has(e.target).length && !container.is(e.target)) {
...
}
Other than that, it should work fine.
Have a fiddle

Using :not to select all elements except inside box with certain class

I have an overlay that I want to hide on mousedown outside it.
Here is what I tried out but unfortunately :not selector is not working as I expected.
$('body:not(.overlay)').one('mousedown',function(){
//hide overlay here
});
I also tried $('* :not(.overlay)') but same issue.
The overlay gets hidden even when clicking inside the overlay box
$(document).on( "mousedown.hideoverlay", function(e){
if( $(e.target).closest(".overlay").length === 0 ) { //overlay wasn't clicked.
//hide overlay
$(document).off("mousedown.hideoverlay");
}
});
Your selector body:not(.overlay) matches the body element if it doesn't have a class overlay, I'm assuming what you meant was its descendant without the class overlay:
$('body :not(.overlay)'); //note the space - descendant selector
The problem with such an assignment is that it matches too many elements (in particular, parents of selected elements). Tehnically, even clicking on any container div would match the selector, fiddled. This happens because even clicks on elements with overlay class continue propagating up the DOM.
I agree with other suggestions here i.e. it's appropriate to listen to all clicks and do nothing if the selector doesn't match, however preventing event propagation on them could interfere with the rest of the page's logic.
I'd rather advocate an approach where there is an explicit subset of "overlayable" items that could be clicked on - and filter them with :not(.overlay) selector:
$('.some-generic-container-name:not(.overlay)')...
Try the .not() function: http://api.jquery.com/not/ . It specifically removes elements from a selected group which is probably the problem you are getting here. Saves having to do complex if's etc to solve this
$('*').not('.overlay').on('mousedown', function(){
alert("here");
});
Edit
Heh, Didn't read the question fully:
$(document).on('mousedown', function(e){
var target = $(e.target);
if(!target.parents().hasClass('overlay') && !target.hasClass('overlay')){
// hide stuff
}
});
Edit: I prefer to use click here (Dunno why):
$(document).on('click', function(e){
var target = $(e.target);
if(!target.parents().hasClass('overlay') && !target.hasClass('overlay')){
// hide stuff
}
});
It just looks nicer in my opinion, call me weird...

how to make the menu close if it is clicked out

i have an menu with some values and i got someting hidden and while click on more button it shows like google more menu... if it is clicked out it is not hiding till the more menu is clicked once again
More<small>▼</small><div class="more list" id="one" style="display:none">test <span style="color:#329">|</span> test1 <span style="color:#169">|</span> test4</div></div>
Script:
function toggle(one)
{
var o=document.getElementById(one);
o.style.display=(o.style.display=='none')?'block':'none';
}
how to make it close while the mosuse clicks on any other place other than the menus
Try using the onblur event.
I see you've tagged this with jQuery, if that is an option, you can clear up the link a bit, like this:
More<small>▼</small>
And use unobtrusive script combined with event bubbling to your advantage, like this:
$(function() {
$(".more_link").click(function(e) {
$(this).next(".more").toggle();
e.stopPropagation();
});​​
$(".more").click(function(e) {
e.stopPropagation();
});
$(document).click(function() {
$(".more").hide();
});​
});
You can test it out here, this only closes the menu if you clicked neither the menu of the toggle, e.g. clicking one of the test links will not close it. If you want it to, just remove the $(".more").click(function(e) { e.stopPropagation(); }); portion.
It uses event.stopPropagation() to stop the click from bubbling up to document, which if happens (and would if you clicked anything else) triggers its click handler, closing all the .more elements.
I wouldn't use onBlur because it's not a good accessibility approach (for example if the user is using tab to navigate the page).
Look at this solution instead:
jQuery click event for document but ignore a div
Typically, I let the event bubble up to the 'body' or 'html' doc and check if the target is what i want (and/or isn't contained within what i want). If the event target is not contained within your menu, then perform your desired operation (in this case, hide the div).
i.e.
jQuery(document).ready(function(){
jQuery("html").bind("click", function(evt){
var $target = jQuery(evt.target);
var shouldShowMenu = $target.hasClass("menu_toggle");
shouldShowMenu |= $target.parents(".menu_toggle, .more_list").length;
if(!shouldShowMenu)jQuery(".more_list").hide();
});
});
NOTE: your markup would needs to be extended such that the "more" href becomes has a class attribute, class="menu_toggle"

Categories