Note: Using stopPropagation
is something that should be avoided as it breaks normal event flow in the DOM. See this CSS Tricks article for more information. Consider using this method instead.
Attach a click event to the document body which closes the window. Attach a separate click event to the container which stops propagation to the document body.
$(window).click(function() {
//Hide the menus if visible
});
$('#menucontainer').click(function(event){
event.stopPropagation();
});
With HTML5 you can make file uploads with Ajax and jQuery. Not only that, you can do file validations (name, size, and MIME type) or handle the progress event with the HTML5 progress tag (or a div). Recently I had to make a file uploader, but I didn't want to use Flash nor Iframes or plugins and after some research I came up with the solution.
The HTML:
<form enctype="multipart/form-data">
<input name="file" type="file" />
<input type="button" value="Upload" />
</form>
<progress></progress>
First, you can do some validation if you want. For example, in the .on('change')
event of the file:
$(':file').on('change', function () {
var file = this.files[0];
if (file.size > 1024) {
alert('max upload size is 1k');
}
// Also see .name, .type
});
Now the $.ajax()
submit with the button's click:
$(':button').on('click', function () {
$.ajax({
// Your server script to process the upload
url: 'upload.php',
type: 'POST',
// Form data
data: new FormData($('form')[0]),
// Tell jQuery not to process data or worry about content-type
// You *must* include these options!
cache: false,
contentType: false,
processData: false,
// Custom XMLHttpRequest
xhr: function () {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
// For handling the progress of the upload
myXhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
$('progress').attr({
value: e.loaded,
max: e.total,
});
}
}, false);
}
return myXhr;
}
});
});
As you can see, with HTML5 (and some research) file uploading not only becomes possible but super easy. Try it with Google Chrome as some of the HTML5 components of the examples aren't available in every browser.
Best Answer
tl;dr: (try it here)
If you have the following HTML:
then you can use the following JavaScript code:
But it doesn't work!
This will work as long as the menu and the placeholder have the same offset parent. If they don't, and you don't have nested CSS rules that care where in the DOM the
#menu
element is, use:just before the line that positions the
#menu
element.But it still doesn't work!
You might have some weird layout that doesn't work with this approach. In that case, just use jQuery.ui's position plugin (as mentioned in an answer below), which handles every conceivable eventuality. Note that you'll have to
show()
the menu element before callingposition({...})
; the plugin can't position hidden elements.Update notes 3 years later in 2012:
(The original solution is archived here for posterity)
So, it turns out that the original method I had here was far from ideal. In particular, it would fail if:
Luckily, jQuery introduced methods (
position()
andouterWidth()
) way back in 1.2.6 that make finding the right values in the latter case here a lot easier. For the former case,append
ing the menu element to the placeholder works (but will break CSS rules based on nesting).