faqts : Computers : Internet : Web : HTML : Forms

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

54 of 101 people (53%) answered Yes
Recently 6 of 10 people (60%) answered Yes

Entry

why do select boxes show through popup layers
why do select boxes show through popup layers

Nov 4th, 2003 11:30
Adam Lyons,


http://notnull.org/docs/windowedvswindowless.htm (formatted document 
source)

1         Managing WINDOWED ELEMENTS 
There are several kinds of page elements on any given html document. A 
common property to manage the layering aspect of these layers is the “z-
index” attribute. However, the implementation of the “z-index” is 
inconsistent with global depth coordinates. These coordinate values are 
segregated between “Windowed” and “Windowless” elements.

1.1        What Elements are What
The following sections have been extracted from Microsoft from this 
location. 

1.1.1.1     Windowed Elements
·               <OBJECT> tag elements 

·               ActiveX controls 

·               Plug-ins 

·               Dynamic HTML (DHTML) Scriptlets 

·               SELECT elements 

·               IFRAMEs in Internet Explorer 5.01 and earlier

NOTE ActiveX controls are implemented as windowless and actually fall 
into the windowless category. By default, Microsoft Visual Basic and 
Microsoft Foundation Class (MFC) controls are windowed, but Active 
Template Library (ATL) controls are windowless. 

1.1.1.2     Windowless Elements
·               Windowless ActiveX controls 

·               IFRAMEs in Internet Explorer 5.5 and later 

·               Most DHTML elements, such as hyperlinks or tables

 
1.2        The common problem and solution
The following screen capture show the problem in a generic sense. If 
you wish to display content in a rollover effect (mouseover) and there 
are windowed elements “beneth” the popup layer, the windowed elements 
will show through, and the z-index property will not be respected. The 
result of the interpreted code found in 1.4 looks like figure 1. It is 
evident that the select element should not appear through the popup 
table.

 


Figure 1 (example) http://notnull.org/docs/figure1.html

There are only a few ways to effectively handle this scenario depending 
on the kind of content you are wishing to display. If the content is 
not in a list format, meaning that you require layout control and text 
markup features that are not singular to the content being displayed, 
then you have but a few options to solve this problem. The first and 
simplest option is to ensure that your layout of the document is 
compatible with this issue. Simply do not layout and windowed elements 
in places where popup content may overlap. If this is not sufficient or 
too much time has already been invested in the initial layout and 
design, then you could refer the all the popup content in a <IFRAME>. 
Using IFRAMES with mouseover events could dampen performance 
significantly, especially in complex CGI implementations. The other 
possibility is to determine the coordinates (globally) of every 
windowed element on a document and determine if the area of the element 
is within the coordinates of the popup layer. This could impact the 
overall aesthetics of the web page though, and confuse users as to why 
portions of the page disappear when mouseover events are triggered! The 
most practical method in battling this windowed vs. windowless 
challenge is to popup a windowed element, instead of a windowless 
element such as a table. All you need to do is populate a select box 
with a specified height for read-ability. Figure 2 shows a much more 
advanced layout along with the result of this technique.


Figure 2

For the sake of the previous example shown in Figure 1, here is the 
modified result in figure 3.


Figure 3 (example) http://notnull.org/docs/figure3.html

 

Using CSS, you can modify a fair amount of properties to improve the 
look of the popup. It is also a good idea to attach additional 
javascript to the layer  for maintaining the visibility of the popup 
when the mouse enters the popup coordinates.

 

1.3        The complex solution
Using javascript to determine if a popup layer is over the coordinates 
of a windowed element can be complex and damage the appearance of the 
website. Figure 4 shows this result. The source code is available in 
the appendix. This solution could work better if it was possible to set 
the clipping regions of any element in a HTML document, however, you 
can only set clipping on an image tag.


Figure 4 (example) http://notnull.org/docs/figure4.html



1.4        Appendix
1.4.1        Supporting code for figure 1
1.4.1.1         Style Sheet
 

<style type="text/css"><!--

.red      { color:#ff0000; }

.white    { color:#ffffff; }

.relative { position:relative; visibility:hidden; }

.absolute { position:absolute; visibility:hidden; }

.shadetable { background-color:#E6E1D0; cell-spacing:0; }

 

//--></style>

1.4.1.2         Javascript
<script language="JavaScript"><!--

function showByLink(object,link,x,y) {

    if (document.layers && document.layers[object]) {

        document.layers[object].left = link.x + x;

        document.layers[object].top = link.y + y;

        document.layers[object].visibility = 'visible';

    }

    else if (document.all) {

        document.all[object].style.visibility = 'visible';

 

        if (document.all[object].myFlag == null) {

            document.all[object].style.posLeft = document.all
[object].offsetLeft + x;

            document.all[object].style.posTop = document.all
[object].offsetTop + y;

        }

 

        document.all[object].myFlag = true;

    }

}

 

function hide(object) {

    if (document.layers && document.layers[object])

        document.layers[object].visibility = 'hidden';

    else if (document.all)

        document.all[object].style.visibility = 'hidden';

}

//--></script>

1.4.1.3         HTML
<hr>

<table width="100%" border="1"><tr><td width="50%">

 

<center>

 

<p>

blah blah

<br>

blah blah

 

<span id="myLayer13" class="absolute" style="width:150;">

<table class="shadetable"><tr><td><div class="color:#ffffff" 
height=100>Some popup text <br>Some popup 
text<br>Windowless<br><br></div></td></tr></table>

</span>

 

<a href="nextpage.htm" onMouseover="showByLink('myLayer13',this,0,15)" 
onMouseout="hide('myLayer13')">example popup</a> 

 

blah blah

<br>

<select name=foo><option value="">Windowed

</p>

 

</center>

 

</td></tr></table>

<hr>

 

1.4.2        Supporting code for Figure 4
<html>

<script language="Javascript">

 

var ObjRestore = new Array;

 

function show() {

                document.all.popup.style.visibility = 'visible';

                showXY('popup');

 

                var s_object = new ObjCoor();

                s_object = setGlobalX('popup', 'popup', s_object)

                s_object.name = 'popup';

 

                for(i=0; i<=document.forms[0].elements.length; i++) {

                                if(document.forms[0].elements[i] != 
null) {

                                                if(document.forms
[0].elements[i].type == 'select-one') {

 

                                                                id = 
document.forms[0].elements[i].id;

 

                                                                if(id) {

                                                                        
        var test_object = new ObjCoor();

                                                                        
        test_object = setGlobalX(id, id, test_object)

 

                                                                        
        test_object.name = id;

 

                                                                        
        //getGlobalX(id, id);

                                                                        
        //alert("test " + document.forms[0].elements[i].id);

 

                                                                        
        // Test to see if c_object values are within overlay clip

 

                                                                        
        if(test_object.tl < c_object.tr) {

                                                                        
                        if(test_object.tr < c_object.tl) {

                                                                        
                                        // the select is clear of the 
popup

                                                                        
                        } else {

                                                                        
                                        // hide the select

                                                                        
                                        //clipper(test_object, 
s_object);

                                                                        
                                        if(test_object.top > 
c_object.top) {

                                                                        
                                                        if
(test_object.bottom < c_object.bottom) {

                                                                        
                                                                        
clipper(test_object, s_object);

                                                                        
                                                        }

                                                                        
                                        }

                                                                        
                        }

                                                                        
        } else {

                                                                        
                        if(test_object.tr < c_object.tl) {

                                                                        
                                        // hide the select

                                                                        
                        

                                                                        
                                        clipper(test_object, s_object);

                                                                        
                        }

                                                                        
        }

                                                                }

                                                }

                                }

                }

}

 

function clipper(test_object, s_object) {

                //alert("CLIPPER" + test_object.name + " " + 
c_object.name);

 

                clipped = document.getElementById(test_object.name);

 

                //alert(clipped.id);

 

                clipped.style.clip.top = 0;

                clipped.style.clip.right = 50;

                clipped.style.clip.bottom = 50;

                clipped.style.clip.left = 0;

 

                clipped.style.visibility = 'hidden';

 

                ObjRestore.push(id);

 

                // clip:rect(top right bottom left)

 

 

}

 

function hide() {

                document.all.popup.style.visibility = 'hidden';

                

                for(i=0; i<= ObjRestore.length; i++) {

                                id = ObjRestore[i];

                                if(id) {

                                clipped = document.getElementById(id);

                                clipped.style.visibility = 'visible';

                                }

                }

}

 

 

function getParent(id) { 

                var el=document.getElementById(id).offsetParent.id; 

                Falert('showParent', el);

}

 

var globalx = 0;

var globaly = 0;

var globalxr = 0;

 

var c_object = new ObjCoor();

 

function ObjCoor() {

                this.tl = 0;

                this.tr = 0;

                this.bl = 0;

                this.br = 0;

                this.top = 0;

                this.bottom = 0;

}

 

function setGlobalX(id, child, object) {

                var parent = document.getElementById
(id).offsetParent.id;

                globalxr = 0;

                if(parent) {

                                globaly += document.getElementById
(parent).offsetTop;

                                globalx += document.getElementById
(parent).offsetLeft;

                                setGlobalX(parent, child, object);

                } else {

                                object.name = document.getElementById
(child).id;

 

                                globaly += document.getElementById
(child).offsetTop;

                                object.top = globaly;

 

                                object.bottom = globaly + 
document.getElementById(child).offsetHeight;

 

                                globalx += document.getElementById
(id).offsetLeft;

                                object.tl = globalx;

                                

                                object.tr = globalx + 
document.getElementById(child).offsetWidth;

                                

                                object.bl = document.getElementById
(child).offsetHeight + globalx;

 

                                object.br = document.getElementById
(child).offsetHeight + c_object.tr;

 

                                globalx = 0;

                                globaly = 0;

                                globalxr = 0;

                }

 

                return object;

}

 

function getGlobalX(id, child) {

                

                var parent = document.getElementById
(id).offsetParent.id;

                globalxr = 0;

                if(parent) {

                                globaly += document.getElementById
(parent).offsetTop;

                                globalx += document.getElementById
(parent).offsetLeft;

                                getGlobalX(parent, child);

                } else {

                                c_object.name = document.getElementById
(child).id;

 

                                globaly += document.getElementById
(child).offsetTop;

                                c_object.top = globaly;

 

                                c_object.bottom = globaly + 
document.getElementById(child).offsetHeight;

                

                                Falert('showY', globaly);

                                Falert('showB', c_object.bottom);

 

                                globalx += document.getElementById
(id).offsetLeft;

                                c_object.tl = globalx;

                                Falert('showGlobalTL', c_object.tl);

 

                                c_object.tr = globalx + 
document.getElementById(child).offsetWidth;

                                Falert('showGlobalTR', c_object.tr);

 

                                c_object.bl = document.getElementById
(child).offsetHeight + globalx;

                                Falert('showGlobalBL', c_object.bl);

 

                                c_object.br = document.getElementById
(child).offsetHeight + c_object.tr;

                                Falert('showGlobalBR', c_object.br);

 

                                

 

                                globalx = 0;

                                globaly = 0;

                                globalxr = 0;

                }

}

 

function showXY(id) {

                getLeft(id);

                getTop(id);

                getWidth(id);

                getHeight(id);

                getParent(id);

                getGlobalX(id, id); 

 

}

 

function getLeft(id) { 

                var el=document.getElementById(id).offsetLeft; 

                Falert('showX', el); 

} 

function getTop(id) { 

                var el=document.getElementById(id).offsetTop; 

                Falert('showY', el);                 

} 

function getWidth(id) { 

                var el=document.getElementById(id).offsetWidth; 

                Falert('showW', el); 

                return(el);

} 

function getHeight(id) { 

                var el=document.getElementById
(id).offsetHeight;                 

                Falert('showH', el); 

                return(el);

} 

function Falert(id, val) {

                document.getElementById(id).value = val;

}

 

</script>

 

 

<input id=show type=input name=showX size=4>X (offset)<br>

<input id=show type=input name=showY size=4>Y (offset)<br>

<input id=show type=input name=showB size=4>Bottom (offset)<br>

<input id=show type=input name=showW size=4>Width (offset)<br>

<input id=show type=input name=showH size=4>Height (offset)<br>

<input id=show type=input name=showParent size=4>Parent<br>

<input id=show type=input name=showGlobalTL size=4>X (global top left)
<br>

<input id=show type=input name=showGlobalTR size=4>X Right (global top 
right)<br>

<input id=show type=input name=showGlobalBL size=4>X (global bottom 
left)<br>

<input id=show type=input name=showGlobalBR size=4>X Right (global 
bottom right)<br><br>

 

 

<br>

<a href="javascript:void()" onmouseover="javascript:show()" 
onmouseout="javascript:hide()">SHOW THE POPUP FLAW</a>

 

<div style="visibility: hidden; position: absolute" id=popup>

<table border=1>

<tr><td>TEST</td><td>TEST</td><td>TEST</td></tr>

<tr><td>TEST</td><td>TEST</td><td>TEST</td></tr>

<tr><td>TEST</td><td>TEST</td><td>TEST</td></tr>

<tr><td>TEST</td><td>TEST</td><td>TEST</td></tr>

<tr><td>TEST</td><td>TEST</td><td>TEST</td></tr>

<tr><td>TEST</td><td>TEST</td><td>TEST</td></tr>

<tr><td>TEST</td><td>TEST</td><td>TEST</td></tr>

 

</table>

</div>

 

<div id=divtag>

<form>

<table border=1 id=table>

<tr>

<td>foo</td>

<td id=col1><select name=select1 onmouseover="javascript:showXY
('select1')" 


id=select1><option>one<option>two<option>three<option>four<option>five</
select></td>

<td id=col2><select name=select2 onmouseover="javascript:showXY
('select2')" 


id=select2><option>tow<option>two<option>three<option>four<option>five</
select></td>

<td id=col3><select name=select3  onmouseover="javascript:showXY
('select3')" 


id=select3><option>three<option>two<option>three<option>four<option>five
</select></td>

<td id=col4><select name=select4 onmouseover="javascript:showXY
('select4')" id=select4> 


<option>four<option>two<option>three<option>four<option>five</select></t
d>

<td id=col5><select name=select5 onmouseover="javascript:showXY
('select5')" 


id=select5><option>five<option>two<option>three<option>four<option>five<
/select></td>

<td id=col6><select name=select6 onmouseover="javascript:showXY
('select6')" 


id=select6><option>six<option>two<option>three<option>four<option>five</
select></td>

</tr>

<tr>

<td>foo</td>

<td id=col7><select name=select7 onmouseover="javascript:showXY
('select7')" 


id=select7><option>one<option>two<option>three<option>four<option>five</
select></td>

<td id=col8><select name=select8 onmouseover="javascript:showXY
('select8')" 


id=select8><option>tow<option>two<option>three<option>four<option>five</
select></td>

<td id=col9><select name=select9  onmouseover="javascript:showXY
('select9')" 


id=select9><option>three<option>two<option>three<option>four<option>five
</select></td>

<td id=col10><select name=select10 onmouseover="javascript:showXY
('select10')" id=select10> 


<option>four<option>two<option>three<option>four<option>five</select></t
d>

<td id=col11><select name=select11 onmouseover="javascript:showXY
('select11')" 


id=select11><option>five<option>two<option>three<option>four<option>five
</select></td>

<td id=col12><select name=select12 onmouseover="javascript:showXY
('select12')" 


id=select12><option>six<option>two<option>three<option>four<option>five<
/select></td>

</tr>

<tr>

<td>foo</td>

<td id=col13><select name=select1 onmouseover="javascript:showXY
('select13')" 


id=select13><option>one<option>two<option>three<option>four<option>five<
/select></td>

<td id=col14><select name=select2 onmouseover="javascript:showXY
('select14')" 


id=select14><option>tow<option>two<option>three<option>four<option>five<
/select></td>

<td id=col15><select name=select3  onmouseover="javascript:showXY
('select15')" 


id=select15><option>three<option>two<option>three<option>four<option>fiv
e</select></td>

<td id=col16><select name=select4 onmouseover="javascript:showXY
('select16')" id=select16> 


<option>four<option>two<option>three<option>four<option>five</select></t
d>

<td id=col17><select name=select5 onmouseover="javascript:showXY
('select17')" 


id=select17><option>five<option>two<option>three<option>four<option>five
</select></td>

<td id=col18><select name=select6 onmouseover="javascript:showXY
('select18')" 


id=select18><option>six<option>two<option>three<option>four<option>five<
/select></td>

</tr>

<tr>

<td>foo</td>

<td id=col19><select name=select1 onmouseover="javascript:showXY
('select19')" 


id=select19><option>one<option>two<option>three<option>four<option>five<
/select></td>

<td id=col20><select name=select2 onmouseover="javascript:showXY
('select20')" 


id=select20><option>tow<option>two<option>three<option>four<option>five<
/select></td>

<td id=col21><select name=select3  onmouseover="javascript:showXY
('select21')" 


id=select21><option>three<option>two<option>three<option>four<option>fiv
e</select></td>

<td id=col22><select name=select4 onmouseover="javascript:showXY
('select22')" id=select22> 


<option>four<option>two<option>three<option>four<option>five</select></t
d>

<td id=col23><select name=select5 onmouseover="javascript:showXY
('select23')" 


id=select23><option>five<option>two<option>three<option>four<option>five
</select></td>

<td id=col24><select name=select6 onmouseover="javascript:showXY
('select24')" 


id=select24><option>six<option>two<option>three<option>four<option>five<
/select></td>

</tr>

<tr>

<td>foo</td>

<td id=col25><select name=select1 onmouseover="javascript:showXY
('select25')" 


id=select25><option>one<option>two<option>three<option>four<option>five<
/select></td>

<td id=col26><select name=select2 onmouseover="javascript:showXY
('select26')" 


id=select26><option>tow<option>two<option>three<option>four<option>five<
/select></td>

<td id=col27><select name=select3  onmouseover="javascript:showXY
('select27')" 


id=select27><option>three<option>two<option>three<option>four<option>fiv
e</select></td>

<td id=col28><select name=select4 onmouseover="javascript:showXY
('select28')" id=select28> 


<option>four<option>two<option>three<option>four<option>five</select></t
d>

<td id=col29><select name=select5 onmouseover="javascript:showXY
('select29')" 


id=select29><option>five<option>two<option>three<option>four<option>five
</select></td>

<td id=col30><select name=select6 onmouseover="javascript:showXY
('select30')" 


id=select30><option>six<option>two<option>three<option>four<option>five<
/select></td>

</tr>

<tr>

<td>foo</td>

<td id=col31><select name=select1 onmouseover="javascript:showXY
('select31')" 


id=select31><option>one<option>two<option>three<option>four<option>five<
/select></td>

<td id=col32><select name=select2 onmouseover="javascript:showXY
('select32')" 


id=select32><option>tow<option>two<option>three<option>four<option>five<
/select></td>

<td id=col33><select name=select3  onmouseover="javascript:showXY
('select33')" 


id=select33><option>three<option>two<option>three<option>four<option>fiv
e</select></td>

<td id=col34><select name=select4 onmouseover="javascript:showXY
('select34')" id=select34> 


<option>four<option>two<option>three<option>four<option>five</select></t
d>

<td id=col35><select name=select5 onmouseover="javascript:showXY
('select35')" 


id=select35><option>five<option>two<option>three<option>four<option>five
</select></td>

<td id=col36><select name=select6 onmouseover="javascript:showXY
('select36')" 


id=select36><option>six<option>two<option>three<option>four<option>five<
/select></td>

</tr>

<tr>

<td>foo</td>

<td id=col37><select name=select1 onmouseover="javascript:showXY
('select37')" 


id=select37><option>one<option>two<option>three<option>four<option>five<
/select></td>

<td id=col38><select name=select2 onmouseover="javascript:showXY
('select38')" 


id=select38><option>tow<option>two<option>three<option>four<option>five<
/select></td>

<td id=col39><select name=select3  onmouseover="javascript:showXY
('select39')" 


id=select39><option>three<option>two<option>three<option>four<option>fiv
e</select></td>

<td id=col40><select name=select4 onmouseover="javascript:showXY
('select40')" id=select40> 


<option>four<option>two<option>three<option>four<option>five</select></t
d>

<td id=col41><select name=select5 onmouseover="javascript:showXY
('select41')" 


id=select41><option>five<option>two<option>three<option>four<option>five
</select></td>

<td id=col42><select name=select6 onmouseover="javascript:showXY
('select42')" 


id=select42><option>six<option>two<option>three<option>four<option>five<
/select></td>

</tr>

<tr>

<td>foo</td>

<td id=col43><select name=select1 onmouseover="javascript:showXY
('select43')" 


id=select43><option>one<option>two<option>three<option>four<option>five<
/select></td>

<td id=col44><select name=select2 onmouseover="javascript:showXY
('select44')" 


id=select44><option>tow<option>two<option>three<option>four<option>five<
/select></td>

<td id=col45><select name=select3  onmouseover="javascript:showXY
('select45')" 


id=select45><option>three<option>two<option>three<option>four<option>fiv
e</select></td>

<td id=col46><select name=select4 onmouseover="javascript:showXY
('select46')" id=select46> 


<option>four<option>two<option>three<option>four<option>five</select></t
d>

<td id=col47><select name=select5 onmouseover="javascript:showXY
('select47')" 


id=select47><option>five<option>two<option>three<option>four<option>five
</select></td>

<td id=col48><select name=select6 onmouseover="javascript:showXY
('select48')" 


id=select48><option>six<option>two<option>three<option>four<option>five<
/select></td>

</tr>

</table>

</form>

 

</div>

</html>