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 UI 1.8 Widget Factory

jQuery UI 1.8 is set to have its final release any moment now and with it comes an updated Widget Factory.  If you haven’t used the widget factory before it’s a great piece of code that does the generic jQuery plugin type of things for you.  You can read more about the widget factory in this older post I did about it.

In jQuery UI 1.8 the Widget Factory gets a few very welcomed changes.  First default options are no longer defined outside of the widget, you now add an options property to the object you are passing $.widget and it will take care of merging your defined default options with the options the plugin gets initialized with.  This also means that in order to set global default options on the core jQuery UI widgets you need to now use $.ui.foo.prototype.options rather than $.ui.foo.defaults.  Also you no longer have to define getter methods like you did in 1.7.  In 1.8 any method that returns a value other then the plugin instance ( this ) or undefined it will assume it’s a getter and return that value.  This is sweet because now you can define a method that is a chainable setter and a getter.  The option method now returns the full options hash when called without any paramaters.

The _init method has been renamed to _create and a new _init method was created.  Yes go ahead and read that again I had to do a double take too.  Basically _create is now called only once when the plugin is first initialized and should contain all the logic to set up the widget.  The new _init method gets called every time the plugin gets called without passing a name of a method.  So when you do: $(‘.selector’).dialog({ height: 530 }); the first time both _create and _init get called. If you call that again later only _init will be called. This was created to fix a misunderstanding many people were having with the dialog plugin. Many people were calling $(‘.selector’).dialog(); and a dialog would open up, then later in the code they wold call the same thing and expect the dialog to popup. By having _init be called every time there is not a method provided it lets the dialog decide if it should open back up if it’s called again.

The _setData method got renamed to _setOption to fit better with what is actually happening.  Destroy now handles removing all widget-namespaced events for the plugin that are bound to this.element or this.widget().  Meaning name space your events and you don’t have to do the extra work of cleaning them up.

One very sweet thing is now you can create a new widget that extends an existing widget.  Just by doing something like: $.widget(‘myCustomAccordion’, $.ui.accordion, { //all my custom methods }); which makes it very easy to create a custom widget that can expand upon and use functionality that is already in another jQuery UI plugin. (The date picker still does not use the widget factory yet so it can not be extended like this).

There are a few other changes but these are the ones that perked my attention.  If you want more information check out the Upgrade Guide for 1.8 and check out Scott Gonzalez’s jQuery UI example code for migrating the widget factory from 1.7 to 1.8.  If you’re including the jQuery UI core in to your page and not using the jQuery UI Widget Factory to create your plugins you should start asking yourself WHY?



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.



jQuery is a’movin

Lot’s has happen in the past month with jQuery.

14 days of jQuery – We had 14 days of great links videos and info leading up and after the release of jQuery 1.4.

jQuery API – the jQuery API doc’s got a much needed overhall and are now running on WordPress.  Some very slick searching and the ability to comment on the documentation has brought live back in to the docs.

jQuery 1.4 was released in to the wild with tons of bug fixes, lots of speed enhancements and a few nice new features sprinkled on top to make it the prefect candy for all jQuery users to quickly flock to.

jQuery Forums packed up and moved from Google to Zoho which has produced a spam free forum again for the jQuery community

jQuery UI 1.8 rc1 has been released with a final release soon to come, bringing us 2 new widgets, button and autocomplete, along with a lot of bug fixes and improvements including an overhauled widget factory.

jQAIP an alternative viewer of the jQuery Doc’s was released for those who don’t like the design or workings of api.jquery.com.  Has its own nice search features and keyboard navigation.

jQuery Source Viewer – a quick and easy way to search through the jQuery source code.  Something that every jQuery developer should start doing after they learn the basics of jQuery.

I am looking forward to updating my projects to jQuery 1.4 and jQuery UI 1.8.  Will be interesting to see what the jQuery community can produce next.