Reusing the jQuery function in iframe documents

25 Jun2013

Today I had to write a TinyMCE plugin that opens up a popup window and does some stuff. This popup however is contained in an iframe element, and so it doesn’t benefit from the jQuery that is already loaded in its parent window.

I didn’t want to follow the usual route and just throw a <script> tag to load jQuery – mainly because this plugin is supposed to be self-contained (e.g. not referring to external resources), and it’s supposed to work with the jQuery build of TinyMCE anyway, so it’s reasonably safe to assume that there is a jQuery function in window.parent.$

However, simply reusing window.parent.$ in the context of an iframe document doesn’t work nearly as well as having our own jQuery initialized in the current window. That’s because the $ object keeps references to the window and document it was loaded in.

Trying to find a solution to this problem, I stumbled upon this thread in the jQuery forum. What this person suggested is exactly what I had in mind!

When you load jquery.js, what it contains is an anonymous self-executing factory function that looks like this:

(function(window, undefined){
    // init jQuery here
})( window );

However, after the factory function is executed, it’s immediately discarded! So if I want to have another $ object in another document without loading jquery.js again, I have to somehow save this factory function for later use.

What the thread poster suggested is to change the above construct a bit. My own take on this is slightly different in syntax, but identical in end result:

(window.jQueryFactory = function(window, undefined){
    // init jQuery here
})( window );

What you do in the iframe document is this:


This creates another instance of $, this time bounded to the iframe window.

Granted, modifying the jquery.js file is something I don’t like, but for the time being it will have to do. Maybe one day jQuery will provide access to the factory function out of the box…

It’s worth noting what Dave Methvin from the jQuery team had to say about this:

It’s an interesting idea, but would need a LOT of compatibility testing. For example if you used the parent’s jQuery then you’d also be using the parent’s Array constructor. API calls returning an Array would return $(selector).toArray().constructor !== Array.constructor in an iframe.

So… beware 🙂


CVS vs. SVN vs. GIT

29 Jan2013

Интересна графика от Google Trends, сравняваща популярността на трите термина:

Графиката е филтрирана по категория “Computers & Electronics / Programming”.

Моят опит общо взето се припокрива с трендовете от графиката – вече дори не помня кога за последно ползвах CVS, а напоследък в офиса се създават повече GIT repos отколкото SVN такива. И това не е само заради лекотата, с която това става при GIT!


Какво е ACTA?

15 Feb2012

През последните дни ми се струва, че повече се шуми “ЗА” или “ПРОТИВ” ACTA (Търговско споразумение за борба с фалшифицирането), вместо да се обсъжда какво всъщност пише в споразумението. И нищо чудно, при положение че намирането на текста му не е от най-елементарните задачи… Или поне досега 😉 – Европейската Комисия публикува съдържанието на ACTA на български, така че всеки интересуващ се да може да реши за себе си дали одобрява подкрепата към споразумението от страна на своето правителство.

Текстът на споразумението ACTA на всички европейски езици


Градски транспорт – виртуални табла

30 Jan2012

От една седмица “Център за градска мобилност” си прави експерименти с мобилния си сайт, вследствие на които ползването на услугата им “Виртуални табла” стана много неудобна за ползване. Вече няма възможност човек да си запише някоя спирка в bookmarks на браузъра, така че всеки път се налага на ръка да се пише кода на спирката.

Първо смениха метода на формата си от GET на POST, сложиха изискване за Referer: хедър, а накрая решиха имената на полетата във формата да се генерират динамично и да се сменят. Нямам идея точно какво се опитват да постигнат и защо, но като редовен ползвател на въпросната услуга, това положение на нещата хич не ме урежда!

За щастие разполагам с възможностите да си реша проблема, тъй че си написах една страничка, която да поддържа GET заявки и да ги препраща към Центъра за градска мобилност. Ако и вие страдате от този проблем, моля заповядайте!


CSS: Rating stars with mouse-over

02 Dec2011

That’s something I thought of quite some time ago, but didn’t have the chance to use anywhere – until now! This will appear in an upcoming project that will probably be released in the next few weeks. I will show you how to make an IMDB-like star rating interface where you rate a product by giving it a number of stars (1 to 5). When you’re not hovering the stars, the control displays the current rating of the product (say, 3.5 stars). When you move the mouse over one of the stars, it is highlighted as well as all other stars to the left of it, so that the number of highlighted stars corresponds to the rating you’re going to give for that product. When you click the star, your rating is processed (which is out of the scope of this article). Except for handling the mouse clicks, everything else is pure CSS – including the mouse-over effects.

Here is what I’m talking about:


My goal was to make the control relying solely on CSS for the mouse-over effects, using the :hover pseudoclass to achieve what normally would be done with JavaScript. I decided not to bother with full support of IE6 – although the control is still functional when being clicked, it won’t highlight the stars as you move the mouse over them. That’s due to the well-known fact that :hover works only on A elements in IE6 – bummer…

I also wanted to be able to specify stepless values for the current rating of the product, instead of being restricted to multiples of one star (or half a star, as commonly seen over the web). Achieving this also has the benefit of not having to use more than 3 images – one for each star state. Of course, nothing stops you from rounding the rating percent for aestetic reasons, but it’s nice not to be limited to just 5 values.

If you don’t want to dig through the code to get the idea, here it is:

  • The outermost container is a DIV element with class .stars and is float-ing to the left; the grey star is used as its background and is repeated along the X axis so that 5 of them are displayed.
  • Inside the container there’s a DIV element with class .rating that has its width set in percent that correspond to the current rating we want to display (for 3.5 out of 5 stars, that would be 70%). Its background is the yellow star, repeated along the X axis. Since that DIV is absolutely positioned, it sticks to the left edge of its container – as its width increases, it covers more and more of the grey stars and they become yellow. At 100%, all stars are yellow.
  • The mouse-over effect is achieved with 5 DIV elements nested into each other (see the markup below). Each of them has a fixed height and left padding corresponding to the size of one star image (in this case, 32px). That padding pushes the left edge of each nested DIV 32px to the right, making it smaller. Although you don’t see it, the 5th orange star is actually all 5 of those DIVs stacked on top of each other (and if you look closely, that’s the reason why I’m not using star images with alpha transparency 😉 ). The first DIV spans over stars 1-5, the second one is over stars 2-5, and so on – to the last and innermost DIV which only spans over star 5. So, when you move your mouse over the fifth star, this triggers the :hover pseudoclass not only for it, but also for its parent elements (which includes all stars to the left)

HTML markup:

<div class="stars">
<div class="rating" style="width: 70%;"></div>
<div class="star" onclick="event.cancelBubble=true; alert('1 star'); return false;">
<div class="star" onclick="event.cancelBubble=true; alert('2 stars'); return false;">
<div class="star" onclick="event.cancelBubble=true; alert('3 stars'); return false;">
<div class="star" onclick="event.cancelBubble=true; alert('4 stars'); return false;">
<div class="star" onclick="event.cancelBubble=true; alert('5 stars'); return false;">


.stars { 
  position: relative; 
  float: left; 
  background: url('/images/star_u.png') repeat-x left top; 
  cursor: default; 
.stars .star { 
  height: 32px; 
  padding-left: 32px; 
  background: transparent none repeat-x left top; 
  cursor: pointer; 
.stars:hover .star { 
  background-image: url('/images/star_u.png'); 
.stars:hover .star:hover {
  background-image: url('/images/star_o.png'); 
.stars .rating { 
  position: absolute; 
  height: 100%; 
  background: url('/images/star_d.png') repeat-x left top; 
.stars:hover .rating { 
  display: none;


  • You can omit the .rating element if you don’t need it – this will result in all-grey stars when you’re not hovering them.
  • Instead of specifying explicit dimensions for the container (.stars), we make it float:left so that its width automatically matches its content. However, this means that we need to take special measures to ensure that it correctly expands the height of its parent element. To do this, you can either append a dummy DIV with clear:both right after the stars control, or set overflow:hidden on the parent element. An alternative approach is to set the width/height of the control explicitly so that you can remove the float:left setting altogether – whatever suits your environment! If you need the stars only for a read-only indicator for rating, you would just use one .stars element containing the .rating element, without all the .star elements – though in this case you’ll have to explicitly define the .stars element’s dimensions instead of floating it.
  • When handling the onclick event for the .star elements, don’t forget that they are nested – this means that the event will bubble up the DOM tree through all the parent .star elements, unless YOU prevent it by setting event.cancelBubble to TRUE.

Hope this helps somebody. If you have any questions or suggestions on how to further simplify this or make it more elegant, please feel free to use the comments 🙂