Popup blocker detection in Chrome
Chrome has a popup blocker just like all good browsers, protecting us from annoying advertisements for face cream and “enhancements”. But Chrome’s popup blocker acts a little different than other browsers. Most browsers do not create the window when window.open is called. Window open returns undefined and you know that your popup was blocked. Chrome does it differently, it passes you a window object. Not only does it create the window object it actually loads the page! So how do you figure out if Chrome blocked a popup?! From some testing and playing I found that after the popup you can do something like:
newWindow.onload = function () {
console.log("The popup is " + (newWindow.innerHeight > 0 ? 'open' : 'blocked') );
}
(Thanks to @rem for refining this with me)
After the popup is created you bind to the onload event and check the windows innerHeight. If the innerHeight of the popup window is greater than 1 then popup wasn’t blocked, if its not well then Chrome blocked you.
My original attempt at this used a setTimeout because I wanted to allow for Chrome to block the popup, then the user react to the block and open it. I have combinded my original attempt with @rem‘s solution and came up with this: http://jsfiddle.net/petersendidit/8gLyz/1/
cssHooks in jQuery 1.4.3
jQuery 1.4.3 brought us a complete rewrite of the CSS module. The main focus of this rewrite was to add extensibility. Along with some nice speed-ups in getting styles, the CSS module of jQuery now let you extend the functionality of .css() and .animate(). It allows this by adding cssHooks.
cssHooks allow you to “hook” in to how jQuery gets and sets css properties. This means that you could create a cssHook to help normalize differences between browsers, or to add some missing functionality from the stock jQuery.fn.css().
Brandon Aaron has been doing some work, along with others, to create a collection of cssHooks. They currently have:
- margin and padding
- backgroundPosition, backgroundPositionX, backgroundPositionY
- boxShadow, boxShadowColor, boxShadowBlur, boxShadowX, boxShadowY
And I am sure there more to come.
Defining a new cssHook is very easy
$.cssHooks['cssproperty'] = {
get: function( elem, computed, extra ) {
// Handle getting the css property here
},
set: function( elem, value ) {
// Handle setting the css value here
}
};
Very simple and easy. To allow your new cssHook to be used with .animate() all it takes is (for simple number value animations):
$.fx.step[ 'cssproperty' ] = function( fx ) {
$.cssHooks['cssproperty'].set( fx.elem, fx.now + fx.unit);
};
Will be interesting to see what other cssHooks show up.
Fast jQuery each when you need $(this)
Most of the time you use the jQuery $.fn.each function you end up doing $(this) inside the function that is getting looped. You want access the jQuery magic in your loop. It’s always seemed weird to me that $.fn.each didn’t pass your function a jQuery version of the element, since you already selected it in order to do the $.fn.each call. Well James Padolsey started playing and created a quickEach plugin that passes in a jQueryized version of this. Then Ben Alman started playing with it and ended up with a $.fn.each2 plugin. It is optimize just for the case where you need a jQueryized version of this in the loop, it is slower then the built in $.fn.each function when you don’t.
// jQuery each2 plugin usage:
$('a').each2(function( i, jq ){
this; // DOM element
i; // DOM element index
jq; // jQuery object
});
// jQuery core .each method usage:
$('a').each(function( i, elem ){
this; // DOM element ( this === elem )
i; // DOM element index
$(this); // jQuery object
});
jQuery focusoutside event
I was doing my part helping out on StackOverflow in the jQuery tag yesterday and ran across a question asking how to hide a div on blur of an input field as long as the click wasn’t inside a div that “connected” to that input field. What I ended up with for an answer was to bind a click and a focusin event on the document and check of the event.target was or is a child of the div we care about. The focusin event is a special focus event the bubbles since the normal focus event does not. I needed to use the focusin event incase the user tabbed to the next field rather then clicking. This got me thinking, Ben Alman created a custom jQuery event ‘clickoutside’ for those times when you need to know that the user just clicked outside of your div and you should now close it. If the same code could also handle the focusin event then it would make answering that question very slick. So I forked Ben Alman’s clickoutside event on github and did some hacking to add the focusoutside event. I am sure the code could be shorted up even more then it is now but it works nicely.
UPDATE
My hacking inspired Ben to do some hacking of his own and we worked on making the plugin work for all the native jQuery events that made since to have outside versions. Check out the new jQuery Outside Events.