Popup browser incompability
I have a popup with drop down menus on it. I've scaled it down and simplified it for test purposes, but it still doesn't work the way I want/it should.
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery('.trigger').click(function(){
var picker = jQuery('.popup');
jQuery('<div></div>').css({
height: screen.height,
width: screen.width,
position: 'absolute',
'z-index': -1,
top: picker.offset().top*-1,
left: picker.offset().left*-1,
border: '1px solid red'
}).click(function(){
picker.trigger('focusout');
jQuery(this).hide();
}).prependTo(picker);
picker.css('visibility', 'visible');
});
jQuery('.popup').live("focusout", function() {
jQuery('.popup').fadeTo(500, 0.0, function() {
开发者_运维百科 jQuery('.popup').css('visibility', 'hidden');
jQuery('.popup').css('opacity', '1.0');
});
});
});
</script>
</head>
<body>
<p>
<input type=text class=trigger />
<div id=popup-div class=popup style="visibility: hidden; border: 1px solid red">
<select>
<option>option1</option>
</select>
<p>Popup text</p>
</div>
</p>
</body>
When you click on the input field, a 'popup' appears, if you click outside the red border it fades away. If you click on the select option it shouldn't dissappear! However on this point, Chrome doesn't work the same as IE/FF/Opera/Safari, and makes the div dissappear.
(Using Chrome 4.0.295.0)
Does anybody knows a work-around for Chrome?
Calling event.stopPropagation() on select elements did not work so farThis seems to behave correctly in Chrome 5.0.375.23, however I'd change this up a bit to have consistent behavior in all browsers including Chrome 4, since focusout
isn't necessarily a valid event on an element that can't have focus
in the first place. A better approach here is to take advantage of bubbling and event order. To do this, you'd replace this:
jQuery('.popup').live("focusout", function() {
jQuery('.popup').fadeTo(500, 0.0, function() {
jQuery('.popup').css('visibility', 'hidden');
jQuery('.popup').css('opacity', '1.0');
});
});
With this:
jQuery('.popup, .trigger').live('click', function(e) {
e.stopImmediatePropagation()
});
jQuery(document).click(function() {
jQuery('.popup:visible').fadeTo(500, 0.0, function() {
jQuery(this).css('visibility', 'hidden').css('opacity', '1.0');
});
});
What this does is if the click
originated inside a popup element or a trigger (opening it), the hide action isn't executed, because the execution of handlers of this event on the same element (document
) is prevented (as is the bubble, but that doesn't matter in the above code). Even though .live()
lives on the document, with event.stopImmediatePropagation()
you can prevent handlers at the same level from executing if they were bound later, since handlers are executed in the order they were bound.
As an aside on .stopPropgation()
:
If you change this to just event.stopPropagation()
, the other handler still executes, hiding the popup (though you could use event.stopProgation()
and check event.isPropogationStopped()
in the second handler).
精彩评论