Facebox no display problem in Chrome

In my previous post, I provide a solution to allow all anchor tags being loaded in a Facebox, which I call it "Stick on Facebox". And I just found there is a bug either on Facebox or Chrome causes the hidden element’s content could be displayed in the Facebox.

See the code in the following,

<style>
.hidden { display:none;}
</style>

<div class="hidden" id="hide1">
I am a hidden div
</div>

<a href="hide1" rel="facebox">View Hidden Content</a>

Note that for the hidden div, instead of using inline css, <div style="display:none;">, I define a class named hidden with the same style. When click "View Hidden Content" link, we expect the content of hide1 will be displayed in the facebox. (of course, we need to attached facebox function to anchor where rel="facebox"). It works fine in IE6+ and Firefox, however, in the Chrome, it displays nothing. Looks like Chrome think the div (#hide1) should be hidden because it has class defined as display as none. However, if we define div (#hide1) using inline css, it would fix the problem.

<div style="display:none"; id="hide1">
I am a hidden div
</div>

Is it odd? Anyway, if you have multiple hidden divs, like the example in the Stick on Facebox, you can still use class hidden, but code will be like this,

<div class="hidden"><!--use this hidden wrap-->
<div id="hide01">I am hidden div #1!<br /><a href="#hide02" class="infinite-find">Click here</a> to find hidden div #2</div>
<div id="hide02">I am hidden div #2!<br /><a href="#hide03" class="infinite-find">Click here</a> to find hidden div #3</div>
<!--more ...-->
</div>

Stick on Facebox

I wrote a short tutorial to explain “how to click a link inside Facebox and load it on the same Facebox” a few days ago. Today I will extend this solution more, eventually, you will see the anchor tags are bound continually, so they can stick on Facebox.

Updates

  • 09/01/2010 – fixed no display problem on Chrome. Note script has been updated in Download folder, but not in this article.
  • 11/18/2010 – Updated function to support external page, which answers Aaron Layton‘s question in the comment.
  • 01/11/2011 – Added new function to display select box (dropdown menu) on facebox

Initial Version

First let’s see the method shown at Facebox official Guide, which attachs Facebox function on any anchor tag after document ready.

<a href="#info" rel="facebox">first link<a>
<!--div 1-->
<div id="info">
Some info here and also some link<br />
<a href="#another-info" rel="facebox">another link</a>
</div>
<!--div 2-->
<div id="another-info">
another info here
</div>

<script type="text/javascript">
jQuery(document).ready(function($) {
  //attached facebox onLoad on all anchors with rel=facebox
  $('a[rel*=facebox]').facebox()
})
</script>

Ok. when you click the “first link”, because it was attached facebox function, it’s open the “info” div in the facebox. And there is another link in the “info” div, which was also attached facebox function, so you expect to view the content of “another-info” div in the facebox, too. However, it does not work, because the content of “info” div is dynamically generated to be viewed in the facebox, and the facebox function attached to anchor tag inside “info” div does not persist. One solution as I explained in the previous post is attaching the facebox function “on fly.”  See the following,

<p><a href="#hide1" id="start">Start to find some</a> hidden divs</p>
<div class="hidden" id="hide1">

I am hidden div #1!<br />

<a href="#hide2" class="find all">Click here</a> to find hidden div #2

</div>
<div class="hidden" id="hide2">

I am hidden div #2.<br> No more hidden div :-(

</div>
<script type="text/javascript">
jQuery(document).ready(function($){
        $("#start").click(function(){
                jQuery.facebox({div:'#hide1'});
                $('.find').click(function(){
                        var glink = $(this).attr('href');
                        jQuery.facebox({div: glink});
                        return false;
                });
        });

})
</script>

In the example above, you see that we don’t attach facebox function onLoad, but control it programmatically. We use jQuery.facebox({div:’#hide1′} to pass the div content into the facebox, and at the same time, we attach the same event handler to the anchor tag, so then when you click the link on the facebox, which can be loaded on the same facebox. But this is not a elegant solution. Says there is another link in the secondary facebox (i.e., div “hide2” in this case), then it will not be open in the facebox, because you know, the event handlers could not persist in the way we bind it.

So the much better solution will be using recursive binding technique. Here is what the code looks like,

<p><a href="#hide01" class="infinite-find">Start infinite finding</a> and have fun!</p>

<div class="hidden" id="hide01">
I am hidden div #1!<br />
<a href="#hide02" class="infinite-find">Click here</a> to find hidden div #2
</div>
<div class="hidden" id="hide02">
I am hidden div #2!<br />
<a href="#hide03" class="infinite-find">Click here</a> to find hidden div #3
</div>
<div class="hidden" id="hide03">
I am hidden div #3!<br />
<a href="#hide04" class="infinite-find">Click here</a> to find hidden div #4
</div>
<div class="hidden" id="hide04">
I am hidden div #4!<br />
<a href="#hide05" class="infinite-find">Click here</a> to find hidden div #5
</div>
<div class="hidden" id="hide05">
I am hidden div #5 (last one).<br /><a href="#hide02" class="infinite-find">Start Over :-)</a>
</div>

<script type="text/javascript">
function find_hidden(){
        $('.infinite-find')
        .unbind('click')
        .bind('click', function() {
                var glink = $(this).attr('href');
                jQuery.facebox({div: glink});
                find_hidden();
        });
}

jQuery(document).ready(function($){
//infinite find - really stick in facebox
        find_hidden();

})
</script>

As you see, I created a recursive function find_hidden() to unbind and rebind event recursively, so facebox function is attached continually, which I called “Stick on facebox”.

Display External Page

Updated on 11/18/2010
As you see in the previous version above, I used the following code to display the content of hidden div on the facebox,

jQuery.facebox({div: glink});

In order to display an external page, we can use ajax method, so just need to slightly update the code to support both as the following,

function find_hidden(){
   $('.infinite-find')
   .unbind('click')
   .bind('click', function() {
      var glink = $(this).attr('href');
//if glink match #, then we say it's div, otherwise, it's an external page.
//of course, you may make this smarter as you need.
      if(glink.match(/^#/)){
                jQuery.facebox({div: glink});
      }else{
         jQuery.facebox({ajax: glink});
      }
      find_hidden();
      return false;
   });
}

And then in the HTML, you can do this,

<p><a href="external1.html" class="infinite-find">
Start infinite finding on EXTERNAL PAGE</a> and have fun!</p>

And the external page will be something like this,

<h3>Exteranl Page 01</h3>
<div>I am EXTERNAL page #1!<br />
<a href="external2.html" class="infinite-find">Click here</a> to find EXTERNAL page #2
<div>
<script type="text/javascript">
   //infinite find - really stick in facebox
   find_hidden();
</script>

Note that you have to call find_hidden function again in the external page, because the one called in the start up page does not bind the click function to the links on the external page.

Display Select Box

Updated on 01/11/2011
As a request from one of my reader, I added this function to display select box (I also call it dropdown menu) on facebox, and the select result will be display on the facebox without leaving facebox. Basically, it uses another ajax call inside the facebox. Nothing complicated. :-) Just need to add the following code in a external page.

<h3>Quotes of the Day</h3>
<div>
Select a quote:
    <select id="link">
       <option value="drop1.html">Quote1</option>
       <option value="drop2.html">Quote2</option>
       <option value="drop3.html">Quote3</option>
    </select>
<div>
<div id="innerajax" style="border:1px solid #2297CA; padding:5px; margin-top:10px;">
You can't build a reputation on what you are going to do.<br />
<b>- Henry Ford</b>
</div>

<script type="text/javascript">
   $('#link').change(function(){
      var innerlink = $("#link option:selected").val()
      $("#innerajax").load(innerlink);
   });
</script>

Check out the updated Demo. And feel free to leave comments if you have any questions.

Open Link Within Facebox

Facebox is a great jQuery plugin, which I have used in many projects. The official Facebox guide is a good start, but it may not cover all you need.  Also, some functions are missing in original Facebox plugin, which you may need in your real work. So I would like to share you some Facebox tips.

OK. The first tip is how to “Open Link Within Facebox and load in the same Facebox”?

Let’s start with a hidden div. If you already read the official Facebox guide, you probably know that the plugin allows you to open a hidden div on a pretty Facebox. For example,

<div id="secret" style="display:none;">
I am a hidden div, you cannot see me until you click "dig" link.
<a class="see" href="#your-new-link">guesswhat?</a>
</div>
<a href="#secret" id="fb-pop">dig</a>

You see there is a link in the hidden div.  By default, when you click that link, it will open in a new window. If you want to load it in the same Facebox. Here is a solution,

$(document).ready(function(){
   $('#fb-pop').click(function(){
      var divid = $(this).attr('href');
      jQuery.facebox({div: divid});
      $('.see').click(function(){
      var glink = $(this).attr('href');
      jQuery.facebox({image: glink});
      return false;
      });
   });
});

Check out Demo right here: dig

Note:

  1. The main point is that you need to bind click event to the <a> link with Facebox on fly.
  2. The <a> link with Facebox, can be another hidden div in the page, or ajax, or image, etc.
  3. The <a> link in hidden div must use ‘class’, not ‘id’ (Not sure why), in this example, I use <a class="see">.