Determine absolute or global z-index?
OK guys, here's a tricky one (perhaps): is there any to get a sort of "global z-index" of an element? here is an example of what i'd like to do:
given two element references, how would you determine which one is higher in the z order (given that they may not hav开发者_Go百科e assigned z-indices or are in separated containers)
Elaborate hacks welcome! Not-so elaborate methods more than welcome.
This was an interesting problem. The following code may not be bug free. I just put it together right now and haven't tested it entirely. Its purpose is to demonstrate an approach.
It compares two elements and tests them on three criteria:
Looking through the ancestor tree of each element, if the first ancestor for element A to have a z-index has a greater z-index than the first ancestor of element B to have a z-index (if one exists for element B at all), then element A is higher in the z-order.
Otherwise, if element B is a descendent of element A then element B has a higher z-order.
Otherwise, looking at the siblings of the last ancestor that element A and element B had in common, if an ancestor of element A comes first in the array of children of that common ancestor then element B has a higher z order.
There may be an simpler way of describing of the logic above and the algorithm can be improved. (For example, the second check above could be done first.) However, here's the code:
<html>
<head>
<script language="javascript">
function getAncestorsAsArray(element){
var arr = new Array();
arr.unshift(element);
while (arr[0].parentNode){
arr.unshift(arr[0].parentNode);
}
return arr;
}
function highestInitialZIndex(elementArr){
for (var i=0; i<elementArr.length; i++){
if (elementArr[i].style == undefined) continue;
var r = elementArr[i].style.zIndex;
if (!isNaN(r) && r!="") {
return r;
}
}
return undefined;
}
function findCommonAncestor(elementArr1, elementArr2){
var commonAncestor;
for (var i=0; i<elementArr1.length; i++){
if (elementArr1[i] == elementArr2[i]) {
commonAncestor = elementArr1[i];
}
}
return commonAncestor;
}
function findHighestAbsoluteIndex(element1, element2){
var arr1 = getAncestorsAsArray(element1);
var arr2 = getAncestorsAsArray(element2);
// Does an ancestor of one elment simply have a higher z-index?
var arr1Z = highestInitialZIndex(arr1);
var arr2Z = highestInitialZIndex(arr2);
if (arr1Z > arr2Z || (!isNaN(arr1Z) && isNaN(arr2Z))) return element1;
if (arr2Z > arr1Z || (!isNaN(arr2Z) && isNaN(arr1Z))) return element2;
// Is one element a descendent of the other?
var commonAncestor = findCommonAncestor(arr1, arr2);
if (commonAncestor == element1) return element2;
if (commonAncestor == element2) return element1;
// OK, which has the oldest common sibling? (Greater index of child node for an element = "older" child)
var indexOfCommonAncestor;
for (var i=0; i<arr1.length; i++){
if (arr1[i] == commonAncestor) {
indexOfCommonAncestor = i;
break;
}
}
for (var j=commonAncestor.childNodes.length; j>=0; j--){
if (arr1[indexOfCommonAncestor+1] == commonAncestor.childNodes[j]) return element1;
if (arr2[indexOfCommonAncestor+1] == commonAncestor.childNodes[j]) return element2;
}
}
function doTest(){
var e1 = document.getElementById("myDiv1");
var e2 = document.getElementById("myDiv2");
highest = findHighestAbsoluteIndex(e1, e2);
alert(highest.id);
}
</script>
</head>
<body onload="javascript:doTest();">
<div>
<div>
<div style="position:absolute; z-index:20;" id="myDiv1">
</div>
</div>
</div>
<div>
</div>
<div style="position:absolute; z-index:10;" id="myDiv2">
</div>
</body>
</html>
Play around with the nested div
s in the body to test it working.
精彩评论