The premise of what I'm trying to do is use jQuery to start a CSS transition to open and close a search box.
User clicks magnifying glass icon, box opens, user clicks anywhere on the page but the search form, box closes.
To close, using this:
$('body *').not('#header-search, #header-field, #header-submit').click(function () {
And different variations of the answer found here: jQuery - Select everything except a single elements and its children? without success.
Clicking on the input#header-field always closes the box.
Pen Here:
http://codepen.io/anon/pen/RNbmwr
Thanks for reading.
Your code is very aggressive (it gets applied to all elements, so inner element to those in the .not() will trigger it).
It is better to delegate the closing of the box to the body (since click events bubble up), and manually cancel any event that occurs under the forbidden list.
$('body').on('click', function(){
// code for closing box here
});
$('#header-search, #header-field, #header-submit').on('click', function(){
return false; // stop bubbling of event
});
And since in your example the #header-field and #header-submit are descendants of header-search you only need to cancel the bubbling on that
$('#header-search').on('click', function(){
return false; // stop bubbling of event
});
Demo at http://codepen.io/gpetrioli/pen/XJrwXO
Try the jQuery toggle() function:
<script>
$( "button" ).click(function() {
$( "p" ).toggle( "slow" );
});
</script>
Substitute the id for your magnifying glass for "button" and change the paragraph -- $("p") -- the search controls you want to show/hide. Toggle changes the visibility of the indicated id or class. If it is initially hidden, mouse click will make it visible; if initially visible, mouse click will hide it.
Finally, change the speed of the transition if you don't want it to move "slow"
A more complete explanation of toggle() is available at http://api.jquery.com/toggle/
There are many elements on the page. Some of them may contain or be contained by the elements you name. So they will still trigger the event.
Instead, bind a single event handler:
$("body").click(function(evt) {
and check if you clicked on one of the elements:
if( $(evt.target).parents("#header-search").length > 0) {
cancelling the handler if so:
return true;
}
Perform the actual event otherwise:
doSomething();
});
Related
I want to trigger a function if a user clicks anywhere on the page, even clicking on no element or link. Is it possible?
The extension runs only on youtube.com so I can't add every element on the page to the trigger and I assume that every page has different element's ids.
Emmanouil Chountasis is correct, you can use the code at "Detect left mouse button press" to detect a left mouse click crossbrowser.
To the heart of your question, I think what you're looking for is Event Delegation. In jQuery,
// Select a wrapper for the events
$('body')
// Whenever any element in the <body> is clicked
.on('click', '*', function (evt) {
// Emmanouil Chountasis's suggestion would be called right here
if (isLeftClick(evt)) {
// ... do stuff
}
});
See http://learn.jquery.com/events/event-delegation/
Reed's answer works fine, but it triggers the action multiple times. I found this solution that only works on left mouse triggers and executes once per click.
$("body").unbind().click(function() {
//Do Stuff
});
I have a textbox and a div below it. I want to hide the div when the user clicks outside the textbox or div.
Is there any other way other than document.click to handle that user has clicked outside. Because in some of the controls, event.stoppropagation is given, which on click wont trigger the document click event.
Thanks
// This means if you click anywhere on the document once, it'll hide the div
$(document).one("click", function() {/*Do stuff, hide div*/});
// This overrides the previous line for just the textarea and div, therefore making this block of code only apply to everything but the textarea and div
$('textbox, div').click(function(){return false;});
Since you mentioned you have event.stopPropagation() at different sections of the page on click event so document.click will not work to hide the textbox.
Why don't you use document.mousedown? It will work fine.
$(document).mousedown(function(){
$('textboxSelector').hide();
});
Make sure you stop the mousedown event propagation from textbox and its containing div.
Create an overlay div (see other questions) and then add a click event to the overlay div that hides the div below the text box and destroys the overlay div.
<script type="text/javascript">
hideDiv()
{
document.getElementById("divId").style.display = "none";
}
</script>
<input type="text" onblur='javascript:hideDiv()'>
I think this should work.
I have a search suggestion box that I hide when the search text box loses focus. This works great, except that when I click one of the suggestions the click event for that suggestion does not fire.
searchText.focusout(function () { $("#search-suggestions").hide(); });
I also tried:
searchText.focusout(function () { $("#search-suggestions").css("visibility", "hidden"); });
I tried commenting out the hide on unfocus code and the click events then worked fine.
(Basically, the blur event happens before the click on the suggestion can be registered, such that the element I attempted to click is not on the screen when the clicm does register)
here's the click event code:
//Called after the ajax load
$("#search-suggestions").find("a").click(function () { alert("hi"); })
I also tried rendering this on the server but it failed as well:
Search Suggestion
If any one has any suggestions I would appreciate it. Thanks!
You could try to define something like this:
//this goes where you first binding focusout handler
searchText.focusout(onFocusOut);
//this is a usual function
function onFocusOut() {
$("#search-suggestions").hide();
}
//this could be defined after you draw the search-suggestions control
$("#search-suggestions").hover(function() {
//this is hover in handler; unbind focusout from searchText
//something like that:
$("#searchText").unbind('focusout', onFocusOut)
}, function() {
//this is hover out handler; bind focusout to searchText
//something like that:
$("#searchText").bind('focusout', onFocusOut)
});
you could also use live (http://api.jquery.com/live/) to define hover handler for #search-suggestions, depending on what exactly you need.
This will make your search suggestions stay visible when clicking them. In click handler you can then hide them.
Try just making it invisible.
Change $('#my_search_box').hide(); to $('#my_search_box').css('visibility','hidden');
If you have surrounding DOM elements that need to act as if the search box is gone, you can just assign it an absolute position as well.
Try using .css('visibility', 'hidden') instead of .hide which uses display:none.
http://jsfiddle.net/waitinforatrain/8AqgU/
The example in that link shows a nested ordered list. If you open up your Chrome/Firebug console, you can see that clicking a child element causes a .click() event on its parents as well.
Is there a way to just detect the .click() on the visible foreground element that was clicked?
You just need to stop the propogation of the click:
$('#toc li').click(function(e) {
console.log ($(this).attr('id'));
e.stopPropagation();
});
Check out this page for more info
I have a menu in jQuery when you click on a link it opens up, but I want it so when you click somewhere else, anywhere else that is not the menu, it becomes hidden.
At the moment I'm binding a click event to
$(':not(#the_menu)')
But this seems like I'm binding a click event to the entire minus the menu, is there a more efficient way of doing something like this?
The best way to do this is with bubbling capture, like this:
$(document).click(function() {
//close menu
})
$("#the_menu").click(function(e) {
e.stopPropagation();
});
How this works is every click bubbles (unless you stop it, usually by return false; or event.stopPopagation()), so whatever you click bubbles all the way up to DOM...if a click does that, we close the menu. If it came from inside the menu, we stop the bubble...so the click doesn't bubble up, triggering a close. This approach uses only 2 event handlers instead of 1 on everything but the menu, so very lightweight :)
Attach event to document's body ($(body)). Also attach another event to #the_menu that's block event propagation:
$(document.body).click(function() {
//close menu if opened
});
$("#the_menu").click(function(e) {
//code heere
e.stopPropagation();
});
How about binding the menu display to hovering over the element in which it is contained?
$("#parentId").hover(
function() { //!! on hovering in
$("#targetId").attr("display","block") ;
} ,
function() { //!! on hovering out
$("#targetId").attr("display","none") ;
}
) ;
If it fits your goal, this seems easier to maintain.