offsetLeft & offsetTop falsch berechnet

FipsTheThief

Erfahrenes Mitglied
Also in einen größeren Projekt kam es nun doch endlich zu Problemen nämlich um eine falsche Position von links von 811 px statt 812 pixeln wie es hätte sein müssen.

Im Opera funktioniert es hingegen sehr gut er gibt tatsächlich die 812px aus.
Aber im FF , IE und Safari fehlt allerdings ein pixel und zwar ist dies 1 Rahmen.

Hier mal ein Beispiel welches ich nun nachgebaut habe nur um sicher zu gehen.

Code:
<!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">
    <head>
        <style type="text/css">
            * {
                margin:0px;
                padding:0px;
            }

            .outer {
                position:relative;
                height:400px;
                width:400px;
                border:1px solid;
                left:20px;
            }

            .inner {
                position:absolute;
                width:100px;
                height:100px;
                border:1px solid;
                top:250px;
                left:180px;
            }

            #inner {
                position:relative;
                top:20px;
                left:10px;
                height:50px;
                width:50px;
                background:#0000FF;
            }
        </style>
        <script type="text/javascript">
            function getCoords() {

                var obj = arguments[0];

                var left = 0;
                var top  = 0;
                var objW = obj.offsetWidth;
                var objH = obj.offsetHeight;
    
                do {
                    left += obj.offsetLeft;
                    top  += obj.offsetTop;
                    obj = obj.offsetParent;
                } while (obj.offsetParent);

                return {posX:left,posY:top,w:objW,h:objH};
             }

                window.onload = function () {
                    var c = getCoords(document.getElementById('inner'));
                    alert(c.posX);
                }
        </script>
    </head>
    <body>
        <div class="outer">
            <div class="inner">
                <div id="inner"></div>
            </div>
        </div>
    </body>
</html>

Ich habe mal versucht es nachzubauen wie es dann aussieht in etwa und wollte nun die Startposition der blauen box bestimmen man bekommt im FF / IE 6.0 und Safari immer den Wert 210 px.
Wenn man diesen Wert nun nachmisst in einen Zeichenprogramm , bekommt man statt 210px aber auf die 212px. Was dem FF / Safari und IE hier fehlt sind die beiden Rahmen die noch hinzukommen.

Einer ne Idee wie man das umgehen kann ?

clientLeft / clientTop kennt der FF 2.0 leider nicht also fällt das schon mal weg, dort einfach zu prüfen ob das offsetParent Element noch einen Rahmen von 1 px hat :/
 
Zuletzt bearbeitet:
So nach einer langen Tortur und einer Reise ins Ungewisse mit getBoxObjectFor() im FF , da durfte das Element von dem wir die Position wollten keinen Rahmen haben sonst kam es wieder zu falschen werten diesmal 1 px zuviel weil er ab dem inneren gemessen hatte.

Sowie getBoundingClientRect() im IE welcher einfach bis zum Bildschirm gemessen hatte was dann halt 2 px zuviel waren immer.

Hatte ich irgendwann die Lösung gefunden , hätte ich mal gewusst das border-left == border-left-width ist wäre es wohl schneller gegangen ;).

Anbei mal meine Lösung falls nochmal wer die Probleme hat.

Code:
            function cssValue (obj,value) {
                if(document.getComputedStyle) {
                    return document.getComputedStyle(obj,"").getPropertyValue(value);
                } else {
                    if(window.currentStyle) {
                        return obj.currentStyle[value];
                    }
                }
                return false;
            }            
        
            function getCoords(htmlObj) {
            
                var obj = htmlObj;
                var o   =   htmlObj;
            
                var left = 0;
                var top  = 0;
                var objW = obj.offsetWidth;
                var objH = obj.offsetHeight;
                                
                do {
                    left += obj.offsetLeft;
                    top  += obj.offsetTop;
                    
                    // den Rahmen vom eigentlichen Element nicht mitzählen
                    // da geht es ja los und Opera macht es sowieso
                    if(!/opera/i.test(navigator.userAgent) && obj != o) {
                        var bT = 0;
                        var bL = 0;
                    
                        // für Safari / FF 
                        if(!/msie/i.test(navigator.userAgent)) {                        
                            bT = parseInt(cssValue(obj,"border-top-width"));
                            bL = parseInt(cssValue(obj,"border-left-width"));
                        } else { // IE
                            bT = parseInt(cssValue(obj,"borderTopWidth"));
                            bL = parseInt(cssValue(obj,"borderLeftWidth"));
                        }
                        
                        // IE 6 gibt NaN zurück wenn kein Rahmen existiert
                        if(bT)  top = top+bT;
                        if (bL) left = left+bL;
                    };
                    
                    obj = obj.offsetParent;
                } while (obj); 
                                
                return {posX:left,posY:top,w:objW,h:objH};
            }

Das Problem tritt nur auf wenn positionierte Elemente in positionierten Elementen liegen und irgend eines der positionierten Elemente hat obendrein noch einen Rahmen.
Da sich das innere Element ja dann an dem oberen positionierten Element ausrichtet. Warum die dann den Rahmen ignorieren kA.
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück