PDA

View Full Version : facebox breaks if I use innerHTML on a div using it



tomba
12-05-2009, 09:14 PM
1) Script Title: facebox

2) Script URL (on DD): http://www.dynamicdrive.com/dynamicindex4/facebox/index.htm

3) Describe problem: I am having a strange problem with facebox breaking if I use innerHTML on a div calling that calls it. In fact I have a tiny demo that merely gets the innerHTML of the div and then immediately sets it back without even modifying it -- i.e. essentially a nop. From then on the facebox popup won't appear. I thought this might have something to with escapes but now that I have this trivial example I don't think so. I'm at a loss as to how such a "simple" operation that doesn't even change the div's contents can possibly break facebox action. I'd really like to use facebox as I like it's look but I have to be able to modify the contents of the divs using it (not the target of the facebox action but a div that has rel="facebox" in it).

Any insight would be greatly appreciated as I am at the point of giving up on facebox. What other scripts are available that can do the same thing with nice rounded corners AND can survive dynamic changes to the divs that use it?

I've attached lookingforbug.js, and of course you'd need the small facebox package too. To see the bug just uncomment the commented out line the js that reads teeCells.innerHTML = inStr; I can't seem to attach my html (what's with that) so here it is:




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Facebox Problem Demo</title>

<script src="facefiles/jquery-1.2.2.pack.js" type="text/javascript"></script>
<link href="facefiles/facebox.css" media="screen" rel="stylesheet" type="text/css" />
<script src="facefiles/facebox.js" type="text/javascript"></script>

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


<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<script src="JS/lookingforbug.js" type="text/javascript"></script>
</head>
<body onLoad="gettingLoaded_notable()">

<div id="fullcontainer">

<div id="mydiv" style="display:none">
This is the contents of a hidden DIV on the page, with ID="mydiv" and style set to "display:none"<br /><br />
<a href="http://www.dynamicdrive.com/dynamicindex4/facebox/index.htm">Facebox image and content viewer (v 1.1)</a>
</div> <!-- end hidden div -->

<!-- here's the div we try to work with using innerHTML but even just getting the innerHTML and then setting it right back
without changing it breaks the facebox popup -->
<div id="teedisplay" width="850" border="0" style="background-color:white;">
<div>
<p><a href="#mydiv" rel="facebox">View DIV with id="mydiv" on the page</a></p></div>
</div>

</div> <!-- end fullcontainer-->
</body>
</html>


Thanks in advance for any insight...

jscheuer1
12-06-2009, 10:11 AM
There's really nothing strange about it. When Facebox loads, it initiates (assigns) onclick events to all the rel="facebox" links. If you take one of those away by overwriting it with innerHTML, it's gone. If you bring it back with innerHTML, it's no longer initiated, because it's not really the same link (the one that was initiated, it just looks the same). So, to get that to work you would either have to initate it with Facebox after its 'brought in', or you would have to have saved it by using standard DOM methods (either before or as you were removing it) instead of the non-standard innerHTML method, and then later reinsert it using standard DOM methods. But even that might not work in some browsers due to inconsistencies in how assigned events are kept when using the cloneNode or removeChild methods, which are the standard methods for this sort of thing (getting a copy with clone or a reference with remove).

But I imagine you want to do this so that you could import new Facebox triggers, not just replace an existing one with a copy of itself.

To do that, you need to either find a way to initiate it to Facebox after importing it, or change the way Facebox operates so that it can deal with new imported content that arrives after Facebox's primary initialization.

The latter is the more elegant solution, but it will take me a bit of time to arrange.

jscheuer1
12-06-2009, 11:24 AM
For an explanation of why we're doing this, read my previous post in this thread.

OK, find this in the facebox.js file:


this.click(click_handler)
return this

Replace it with:


if(!$.facebox.extra){
$(document).bind('click', function(e){
var a = e.target;
while(!/^facebox/.test(a.rel) && a.parentNode){
a = a.parentNode;
}
if(/^facebox/.test(a.rel)){
click_handler.apply(a);
e.preventDefault();
}
});
$.facebox.extra = true;
}