Greybox Redux

Posted on by

Another popular DOM/CSS/Javascript project popped up today: Greybox. It’s a lot like the popular lightbox, but is used to display web sites on top of your current page.

I saw this as another great opportunity to demonstrate how easy it is to make great code with jQuery. I modified greybox in two phases.

  1. First step was to make greybox work unobtrusively (they embeded javascript into the page to make it work) and to fix the broken back-button (you’d have to hit back twice after visiting a site).
  2. The next step was to completely overhaul the library itself and remove the need for Amir’s personal Javascript library – leaving it to run completely using jQuery. The resulting code is only about 1.2kb (compared to the original 12kb of the original).

A demo and a download are available if you’re interested in seeing some more examples of how jQuery works in a practical application. Enjoy!

39 thoughts on “Greybox Redux

  1. Alain Ravet on said:

    It looks like a simple way to add small context related tutorials to a site: add a “help” button, and have it display a – sequence of – page(s) in a greybox.

    Great.

  2. I only just had had the time to notice the broken back button in the original greybox that you already come up with this.

    I am impressed.

    One question. Wouldn’t you prefer, as a general rule, to use e.preventDefault() rather than returning false (which I understand also cancels the bubbling up of the event) in the $(“a.greybox”).click()? I believe this would ensure you don’t break other behaviours of the page relying, say, on a $(“body”).click() – or am I missing a point somewhere?

    That’s how I’m using jQuery’s event handling, and I wonder whether there is any specific reason why you opted for cancelling all further event handling rather than only the default execution.

    Kudos again, jquery is the first js library I couldn’t resist using for real. Working with JS has just become so much quicker, and the code has become a lot more auto-documenting and easy to review.

  3. Alain Do you have an example page running with the two, together? I’d like to see what the problem is.

    Andrea I probably should make the preventDefault explicit – but I’m having a hard time deciding if that’s what I should do. I’m finding that, more often than not, I can preventDefault and have it continue to work like I want it to. I guess the best example is:

    $("a").click(function(e){
      alert("hello!");
      e.preventDefault();
      return false;
    });

    Some very simple code just became much longer and hard to understand. There’s gotta be a better meeting point for this. Please let me know what you think about this, because it’s obviously still a point of confusion.

  4. From the ‘base events’ documentation I understand that writing e.preventDefault() is redundant if your event handling code also returns false, so to me the alternatives seem to be the following:

    1. make use of the event argument (e) and finish the routine with e.preventDefault();

    2. simply return false;

    Version 2 is so much simpler but prevents the click from being handled by ancestor elements, possibly interfering with other active scripts.

    To make the code both do only what it must do and be more understandable by visitors looking for examples they can undestand at the first glance, maybe you should rather use more self-explanatory argument names and a short comment:

    $("a").click(function(clickEvent){
      alert("Hi There!");
      clickEvent.preventDefault(); // don't follow the link
    });

    But it’s really only a detail…

  5. Alain Ravet on said:

    John,
    >> does not work with prototype
    >Do you have an example page..

    Easy to reproduce
    1/ in , add prototype.js
    2/ in test.html, add “” after .. greybox.js

    problem: when you click, no more greybox, just a standard link following.

    note: tested on a Mac

  6. Brendyn on said:

    Andrea & John,

    Just FYI, I wasn’t understanding what exactly you meant by preventDefault() until I read Andrea’s post and the comment associated with it. It makes perfect sense in the more explicit manner (which Andrea wrote up a snippet of code to demonstrate) what the function does.

  7. Corey Jewett on said:

    WRT to Alain’s note (“Doesn’t work with Prototype”), here’s some JS Console bits from FF 1.5:

    note the only change I’ve made is to add the Prototype import, and to pull jquery locally:

    On Load
    =====
    Error: $ is not defined
    Source File: http://cirqe/js/jquery.js
    Line: 18

    On Click
    =====
    Error: Selector expected. Ruleset ignored due to bad selector.
    Source File: http://www.google.com/
    Line: 5
    Error: Unexpected end of file while searching for closing } of invalid rule set.
    Source File: http://www.google.com/
    Line: 6

  8. Is it me or is this script not working?

    I’m getting “TypeError: o.SetAttribute is not a Function” on FireFox 1.0.7

    works in IE 6 but the animation is strange and every window has scrollbars bot vert and horiz.

    WinXP pro sp2

    This script needs more work.

    Keep it up

  9. Allan: Sorry about the bug, it was due to a fix that I rolled into the code last night. I just fixed it and pushed the code live. Sorry about that.

  10. Dwaine on said:

    This is great! Well done.

    It seems to have issues in Safari? Instead of popping up a greybox it just goes straight to the webpage. Am I doing something wrong, or is this not compatiable?

    Bravo!

  11. Having problems getting this to work, even though I downloaded the same set of files, I get half baked items – the div does not completely cover the page, it looks like a 40px horizontal div on the top. Also, it sometimes goes directly to the page – I’m using IE 6.

  12. matt on said:

    Great job with this! I’m impressed by how lightweight jQuery is.

    This would be perfect solution for a project I’m developing except for one thing: It would be great if it were possible to set the script up so that all links inside the box (or even specific links inside the box) would open up back in the primary browser window instead of the greybox.

    Does anyone have a suggestion for what I might change to accomplish this?

  13. Hi,

    great code,

    just one issue, when i have a greybox link in a 1 screen webpage alls good, but when i have the greybox link say 3 screens down a page – once the link is pressed nothing noticable happens on screen until you scroll back upto the top of the page – the top of the page has the greybox window displaying the linked page and the rest of the screen greyed out – its like only the top ‘screen’ section of the page gets ‘greyboxed’

    Does anyone know a workaround for this?

    Cheers

    Justin

  14. Regarding Justin’s remark above, I have a few changes that you can use to have the box be centered in the screen, and remain centered even on window scroll events.

    Add this after $(window).resize(GB_position);:

    $(window).scroll(GB_position);

    Change GB_position to:

    function GB_position()
    {
    var de = document.documentElement;
    var h = self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
    var w = self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
    var iebody=(document.compatMode && document.compatMode != “BackCompat”)? document.documentElement : document.body;
    var dsocleft=document.all? iebody.scrollLeft : pageXOffset;
    var dsoctop=document.all? iebody.scrollTop : pageYOffset;

    var height = h

    I hope that all formatted properly.

    -Tom

  15. sorry the post didnt turn out as i mean

    1. in your webpage have a greybox “a href” to “a name” in the moddle of your traget file, and have greybox go to that “a name:

    hope that makes sense

    cheers

    justin

  16. z3phir on said:

    it works great froma link but how can i call a greybox redux from a form (on submit to open the page in a greybox redux) ?

  17. Hello Guys,

    This js looks like a great gem.

    I am encountering a problem being able to use it.

    If i put it as first element after starts it will run ok.

    However, if i put it on the position where I want it displayed it won’r work.

    This position is after the following DIVs open (they all close after the greybox):

    how shall I format the 3rd line below:

    var GB_ANIMATION = true;
    $(document).ready(function(){
    $(“a.greybox”).click(function(){
    var t = this.title || $(this).text() || this.href;
    GB_show(t,this.href,590,765);
    return false;
    });
    });

    i’ve tried with:

    $(“#main .column a.greybox”).click(function(){

    but it didn’t work

    keep up the good work

    many thanks,
    Mihai

  18. Great simple plug-in!

    Does anyone know how to remove the space at the bottom of the greybox (below the horizontal scrollbar)? In GB_position, I see that it is subtracting 32 pixels off the iframe height. This appears to be causing the gap, but if you change the value to zero you get two scrollbars.

    Any ideas?

  19. In Firefox I get 2 vertical scrollbars. In IE I have to scroll to the right to get the 2nd scroll bar, which I need to scroll down the page. I’ve checked out your demo and you seem to behaving the same trouble.

  20. Am I missing something or does this script not allow dynamic sizing? If I want to use it in an image gallery, and not all images are the same size, if it can’t auto-detect the image size, maybe it can allow us to specify the size manually in the anchor tag itself?

    I was all set to jump on this script for my band site, but this one-size-for-all limitation is pushing me towards lightbox/thickbox. :-(

  21. Brad on said:

    If you want to add a loading image that hides once the iframe is loaded, just change the document.body.append to the following:

    $(document.body)
    .append(“” +
    “” +
    “”);

    Then in your iframe, hide the loading image when the document is loaded:

    $(document).ready(function() {
    parent.parent.$(‘#GB_loader’).hide();
    });

    Hope that all pasted in ok :)

  22. Brad on said:

    Apparently it didn’t… think the comment board needs a little htmlentities love :)

    At any rate it’s not too difficult but if you need the code for the loading animation drop me an email isawufall at yahoo

  23. Shanti on said:

    Any way to make it so that when I open a Greybox window (a one page, like an image) clicking the back button on the browser will actually close the greybox window instead of going back ?

  24. Hi,

    My wish list make the window movable, and fix the 2 scrollers issue (2 vertical scoller bar).

    Thanks

  25. Stephen on said:

    I’ve got two problems with Greybox, hopefully someone can help

    1) If the page requires vertical scrolling because the content is too much, then kicking off the greybox on a link “down” in the page doesn’t cover the whole entire page and places the box itself up on the “first page”… this behaivor is both on IE7 and FF2… for an example of what i mean, check out (http://www.morningz.com/linked/greybox/test.htm), scroll all the way to the bottom and click the click

    2) In firefox, the “window close” link doesn’t work, it’s kind of like some of my header area is “above” it and the overlay , but there is no z-index set on any my existing code/css

    thanks in advance

  26. Stephen on said:

    Ooops.. i misred what the fix that Tom Zellman posted… that took care of #1…… still poking around in the CSS to try to get #2 to behave in FF

  27. Anyone know how to prevent the box from going away by pressing the esc button or clicking outside of the box?

    thanks

  28. Josh Anderson - Transparent Website Video Player on said:

    I am displaying flash videos in a Greybox Redux and am using “the updated greybox.js file here: http://swampfoot.googlepages.com/greybox.js” from above…

    I have a problem that I need someone’s help on…

    When I close the modal window the flash video keeps playing even though it is no longer visible…

    However if I use another modal script called “videoBox” it does not have that problem.

    Any suggestions?

  29. BOS on said:

    Hi all, I’m relatively new to jQuery and am trying to learn as much as i can.

    I have written a function called GetComments() and which does a $.get() to retrieve the data entered in the greybox window.

    what is the best way to get a function to be called after the greybox window is closed?

    I modified the greybox.js as follows:

    function GB_hide() {
    $(“#GB_window,#GB_overlay”).hide();
    GetComments(); //

  30. Rob Q on said:

    Tom Zellman box position fix for scrolled pages appears not to work with FF 3 release. I’d love to use this.

  31. Rob Q on said:

    One other thing – if you wanted to auto close the pop up from within the iframe (say after a form submission) without having to click out or click the close button, how would that be done?

  32. a same question as Rob Q, how can I close greybox via a function? for example, after I login in greybox, I want to close it without click the mouse, what shall I do?

  33. Rob Q and ranfrow – if you redirect your script to another page with this code in when you successfully enter your form (or whatever) the window will close and the user will be redirected to the page you want them to go to:

    $(document).ready(function(){
    top.location.href=”http://www.yourpagehere.com”;
    }

    Obviously you need to include jQuery as well. I guess you could do this in an onload too, but inline javascript is evil innit?

    Hope this helps :)