Not responding to events? - javascript

I currently have three Divs and only one of them is in focus at a given time. All of them line up in a film strip fashion. When I click a DIV not in focus, the current one moves to the left or right (depending on the direction) and the new one comes into focus.
The divs can have content that has links. So my problem is that upon clicking on the divs not in focus, if I happen to click on a link, the event is captured. Is there anyway I can disable event detection for divs not in focus?
What I am looking for is something like:
if(div not in focus)
disable all links
if (div comes into focus)
enable all links

Assuming that the active <div> has a class of Active, you can do it like this:
$('.Container div:not(.Active) a').live('click', function(e) {
return false;
});

Sounds like a selector problem. Can't you give those divs unique ids or classes to bind click events individually?

In your event handler, use
if (event.target.tagName == "a") // where `event` is the 1st argument passed
event.preventDefault(); // to the handler
This will prevent the default action if a link was clicked and still allow the div to move into focus.

Related

Simple function hide/show/toggle for a Div

I'm trying to make a Div that is initially hidden to show up and stay toggled unless i do one of the following events (so in that case they hide again):
reclick on the same element that displayed the div on the first hand
click outside the div (container)
click outside of a div's children (descendant of the container)
This is the code i come up with :
(#menu_login being the menu on which i click to make the div appear and .bubble being the div in question)
$(document).ready(function(){
$(".bubble").hide();
$("#menu_login").click(function(){
$(".bubble").toggle();
});
$(document).mouseup(function (e)
{
var container = $(".bubble");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.hide();
}
});
So first, the hide_on_load function works well, but the toggle and mouseup function seems to be in a conflict when running together.
They work well when i use only one of them (and i really like this mouseup function because of the way it allows me to click on the container's descendants even when outside of the div).
The thing happening is when i click on the menu and toggle the div, if i click it again to untoggle and hide the div my mouseup function creates a conflict :
It looks like because i on the menu again to untoggle and hide the div again, the mouseup function also detects that i clicked outside of my div and hide my div before my toggle function can.
So what happen is that the toggle function won't detect that i clicked the menu to untoggle and hide the div, but that i clicked to toggle and show the div because the mouseup function closed it 0.01sec before.
So i don't really know how to do to have theses two functions working together, i had some kind of idea about adding an exeption that says to the mouseup function not to hide the div if i click on the menu (the same it doesnt close it if i click on a div's descendant) so my toggle function can do it and there is no conflict, but my knowledges in JQuery are non-existent.
exemple :
$(document).mouseup(function (e)
{
var container = $(".bubble");
if (!container.is(e.target) container...
&& container.has(e.target).length === 0)
// and here : "don't close it if i click on my #menu_login neither
{
container.hide();
}
Any help/suggestion is welcome, sorry if this a bit heavy to read but i tried to be as specific as possible.
Thank you !
-Apatik
There are three parts you have to consider:
The toggling action you see when #menu_login is clicked (you have addressed this already). But what's more important is that we want to make sure the click event from this element does not bubble up to the document object, for which we will listen for click as well. This is done by using event.stopPropagation().
To prevent clicks within the .bubble element from bubbling up, you will have to prevent the event from propagating when originating from it, too.
Listen to click event bubbling up to the document. Since we used event.stopPropagation() on the anchor element, click events will not bubble from it, but will from the rest of the document (i.e. other elements). We conditionally hide the .bubble element if it is visible, by using .filter().
$(function(){
$('.bubble')
.hide()
.click(function(event) {
// Stops click event from bubbling to document (point #2)
event.stopPropagation();
});
$('#menu_login').click(function(event){
// Stops click event from bubbling to document (point #1)
event.stopPropagation();
// Toggle visibility (point #1)
$('.bubble').toggle();
});
$(document).click(function() {
// Hide bubble if visible (point #3)
// Will listen to click events from all other elements
// ... except for `#menu_login` because we have
// ... prevent the click event from bubbling up
$('.bubble').filter(':visible').hide();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="menu_login" href="#">Menu login</a><div class="bubble">Bubble</div>

How to handle "click" event even if element is moved from beneath the cursor between mousedown and mouseup?

I have an <input> and a <button>.
The input has an onblur event handler that (sometimes) results in the <button> being moved; if, with focus on the <input>, the user goes to click on the <button> (and it is thereby moved from beneath the pointer before the click completes) they must currently move their pointer to the button's new location and click it a second time. This experience is suboptimal.
I would like for users to have to click the <button> only once (but must retain the functionality of the button moving when the <input> loses focus). However, if a user mousedowns over the button and then moves their mouse pointer away (includes switching focus from the application) before mouseup, no click event should be triggered (as normal).
I can't see any approach based on handling onmousedown and/or onmouseup that would not be prone to errors in some edge cases. All that I can think is to forcibly move the cursor in the onblur handler so that the click completes (if indeed it would?)—but this is probably a poor user experience too.
How can this best be handled?
$('button').click(
$('<li><input></li>')
.children('input')
.blur(function(){
if (!this.value.length)
this.parentElement.remove();
})
.end(),
function(e){
e.data.clone(true)
.appendTo($(this).data('target'))
.children('input')
.focus();
}
);
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
List 1<button data-target="#list1">+</button><ul id="list1"></ul>
List 2<button data-target="#list2">+</button><ul id="list2"></ul>
One approach would be to fade the element out over the course of, say, a second rather than immediately, which gives the user time to complete the click before the button moves:
$(this.parentElement).fadeOut("slow", function() {
$(this).remove();
});
Live example:
$('button').click(
$('<li><input></li>')
.children('input')
.blur(function(){
if (!this.value.length)
$(this.parentElement).fadeOut("slow", function() {
$(this).remove();
});
})
.end(),
function(e){
e.data.clone(true)
.appendTo($(this).data('target'))
.children('input')
.focus();
}
);
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
List 1<button data-target="#list1">+</button><ul id="list1"></ul>
List 2<button data-target="#list2">+</button><ul id="list2"></ul>
That said, I think I'd try to find a way that the space between the list elements didn't change at all, because this still means things move around, just at a different time — hopefully at a time the user will be less bothered by it, but... Tricky in this case, though, because of the lists being on top of each other — the second list is going to move at some point. If you made it that there was always an input box for the user to type in, then the second list would just move at a different time (when the box does have a value in it and you add a new blank one for the next value). Could be done with a fixed list size and scrolling within, but it depends on the overall design.
I had a related issue where I was styling buttons to shrink on being pressed, using the :active pseudo-class to resize the button on mouse-down and resetting its size when the button gained focus with the :focus pseudo-class. However, if the button was clicked close enough to its edge, it still was activated and shrank, but the cursor was now just outside of the bounds of the button and the button would no longer gain focus.
This is a result of how the click event itself works. For the onclick event to be fired on a given element, the cursor must be "both pressed and released while the [cursor] is located inside the element." However, if the cursor moves outside of the element before being released, the event is instead fired on the "most specific ancestor element" containing both elements. In specific, this results in a mousedown event being fired on the element and a mouseup event being fired on its ancestor element.
A solution, then, is to monitor a button's mousedown event, and click the button if its parent's mouseup event is fired (i.e., the cursor was pressed over a button but released over its parent).
Vanilla JS code:
// The CSS selector for the buttons to monitor
const selectors = "button";
window.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll(selectors).forEach(button => {
// Watch for button press
button.addEventListener('mousedown', event => {
// The button is the event's original target
const element = event.target;
// Click if the cursor is released over the button's parent
element.parentElement.addEventListener('mouseup', () => {
element.click();
}, { once: true });
});
});
});
This works best if the button's parent is sized the same as the button (such as with width: fit-content). Otherwise, unintentional clicks can occur if the cursor is released far away from the button, but still on the button's parent element.

link not clicked because removed after onblur

I have a textarea with this event bind :
on focus :
display a link that will popup a larger version of text area.
on blur :
remove the link.
but "click" event on the link never triggered because it's already removed when onblur trigerred.
$("#text-area-new-message").focus(function(){
$("#text-area-new-message").after('<a id="enlarge-text-area" href="#">enlarge text area</a>');
$("#enlarge-text-area").click(function(){
alert('test');
});
});
$("#text-area-new-message").blur(function(){
$("#enlarge-text-area").remove();
});
here is the jsfiddle
how is the better way to do that?
When the user leaves the textbox, you could delay the removal of the link by, say, a few seconds:
$("#enlarge-text-area").delay(3000).remove();
Or more. Whatever seems an appropriate amount of time for a user to click the link if that was their intention. This could get even more 'clever', by, for instance, fading out slowly and stopping the animation and subsequent removal only if it captures the mouse (by way of hovering on the link.)
one approach is to use jquery on function to attach event handlers to all 'future'
'#enlarge-text-area' elements :
$('#myParentDiv').on('click', '#enlarge-text-area', function(){});
other approach is to hide rather than remove the link.

Draggable cancel triggering blur event

I have a draggable div which of course could be dragged around.
Inside, I have input text which has two events (focus and blur).
Also inside, I have another div which serve as draggable cancellation div (dragging that div prevent any drag to occur).
you could see it here:
http://jsfiddle.net/wUDzh/4/
Clicking the input box would trigger focus event and clicking outside main div (the red one) would trigger blur event. This is fine.
Clicking or dragging the main div would NOT trigger blur event. That's what I want.
The problem is, clicking the cancellation div (the blue one) cause blur event of the input box to occur. Which is make sense, but that's not what I want.
is there any way to prevent blur event to occur just like the behavior of the main div?
thx
To prevent the input field from blurring when you click the cancellation div, simply do:
$('#cancel').mousedown(function(e) {
e.preventDefault();
});
See fiddle
You could do
$("#text").blur(function(e)
{
// alert('a');
if(e.target.id === 'text'){
//this prevents other blur handlers from firing
e.stopImmediatePropagation();
//this prevent the default action and returns
return false;
}
$(this).val("I've got blur");
});
fiddle here http://jsfiddle.net/wUDzh/6/

Prototype best practice for "click anywhere to close"?

I find myself very often in the situation that I open an element in a web page - e.g. a drop-down menu - that I want to close if the user clicks anywhere on the page except the element itself.
To keep things simple, I have mostly written the code myself instead of employing some drop-down menu class.
However, I have never managed to build an implementation of this that was completely satisfying: Event handling and bubbling would work differently in different browsers, there would be the need for nasty workarounds, in some situations clicking the drop-down button would start closing it in the same moment, and so on.
Is there a Prototype based, authoritative, best practice to do this? Something that works across browsers - IE6 being a plus but not a requirement?
Just this:
click on a button - an element opens
(e.g. an absolutely positioned drop-down menu).
click within the element - the element stays open.
click on the button that opened the element - the element stays open.
click anywhere else on the page - the element closes.
I need help with the event handling part only, the displaying of the menu is totally secondary.
Event.observe(document, 'click', function (event) {
switch (event.element().id) {
case 'example_id':
// do different stuff depending on element clicked
// ofc u don't need to pass id, u can simply throw an element itself
break;
default:
// do close action
break;
}
// also check Event.findElement();
});
You can also add specific classes to the items you don't want to trigger close action and check it inside
if (!event.element().hasClassName('dont_close'))
Element.remove(selectDOMElement);
I guess the open button is within the menu.
$('openbutton').observe('click' function(event) {
var menu = $('openbutton').up();
if (menu.hasClassName('collapsed')) {
menu.removeClassName('collapsed');
menu.addClassName('expanded');
document.observe('click', function (event) {
if(!event.target.descendantOf(menu)) {
menu.addClassName('collapsed');
menu.removeClassName('expanded');
}
});
} else {
menu.addClassName('collapsed');
menu.removeClassName('expanded');
}
});
AFAIK, you need to make an invisible div the size of window, put it behind the current element, and add a click event to that.
Just thinking out loud but you might be able to use the blur event on the dropdown to hide it (blur gets fired when an element loses focus) or another idea might be when the dropdown opens attach a click event to the document object that hides the dropdown. Events get propagated through their containers so it should end up at the document object eventually. You might need to call preventPropegation on the event when your dropdown gets clicked so that it doesn't make it to the handler attached to the document.
maybe you could calculate the Position (X,Y) for the clickevent and compare that to the cumulativeOffset (cumulativeScrollOffset) + [el.width|el.height] of the desired container.
Event.observe(window, 'click', function(e) {
var el = $('el')
if( el.cumulativeOffset[0] < e.Event.pointerX(e) ... )
});
<div id="el" style="position:absolute;width:100px;height:100px;background-color:#00F;top:100px;left:300px;">
</div>

Categories

Resources