offsetParent - Probleme mit Positionierungen
Mel
- javascript
Hallo Forum,
ich habe ein Problem mit der Positionierung der Farbpalette eine Rich Text Editors und zwar diesem hier:
http://www.kevinroth.com/rte/demo.htm
Wenn ich Text nun farbig markieren will klicke ich auf den Button und die Farbpalette wird absolut positioniert und zwar immer unterhalb des Buttons. Analog dazu der button mit dem man den Hintergrund einfärben kann. Die Werte top und left werden dabei über JS dynamisch berechnet (soviel meine ich herausgefunden zu haben ;)
Das Problem: Unser rte liegt nun in einem div mit noch vielen anderen html-elementen welcher positiono: relative; bekommen hat. Nun funktioniert die Positionierung der Farbpalette nicht mehr: der Bezugspunkt ist ein anderer.
Hier ist die richtext.js die ich mal hochgeladen habe...
http://www.sesamstrassenkind.de/richtext.js
Auszug daraus:
//get dialog position
var buttonElement = document.getElementById(command + '_' + rte);
var iLeftPos = findPosX(buttonElement);
var iTopPos = findPosY(buttonElement) + (buttonElement.offsetHeight + 4);
var oDialog = document.getElementById('cp');
oDialog.style.left = (iLeftPos) + "px";
oDialog.style.top = (iTopPos) + "px";
...und weiter unten:
//positioning functions courtesy of Peter-Paul Koch - http://www.quirksmode.org/
function findPosX(obj) {
var curleft = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curleft += obj.offsetLeft;
obj = obj.offsetParent;
}
} else if (obj.x) {
curleft += obj.x;
}
return curleft;
}
function findPosY(obj) {
var curtop = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curtop += obj.offsetTop;
obj = obj.offsetParent;
}
} else if (obj.y) {
curtop += obj.y;
}
return curtop;
}
Ich bitte um Nachsicht was meine JS-Kenntnisse angeht, ich versuche dieses Problem zu verstehen.
Es müsste doch möglich sein dass sich das Skript nicht am oberen Browserfenster orientiert sondern an einem relativ positionierten Container und die Werte top und left trotzdem "richtig" berechnet, also in Abhängigkeit der 2 buttons...
Ich wäre euch sehr dankbar für Denkabstösse, Hilfe.
vg Mel
Hi,
function findPosX(obj) {
function findPosY(obj) {
berechnet Dir die Position eines _nicht_ absolut positionierten Elementes. Um die Position eines absolut positionierten Elementes zu bekommen musst Du auf die Css-Eigenschaften style.top/left zugreifen, bzw das ggf kombinieren.
Gruesse, Joachim
Hallo,
function findPosX(obj) {
function findPosY(obj) {
berechnet Dir die Position eines _nicht_ absolut positionierten Elementes. Um die Position eines absolut positionierten Elementes zu bekommen musst Du auf die Css-Eigenschaften style.top/left zugreifen, bzw das ggf kombinieren.
hmm. top und left wird ja dynamisch berechnet. aber das script nimmt immer die linke obere Ecke des Browserfensterns als bezugspunkt um die Werte auszurechnen. nur wird alles verschoben wenn ein relativ positionierter Container da ist.
ich weiss leider nicht wie ich mit deinem lösungsansatz da weitermachen könnte...
vg melanie
Hi,
ich weiss leider nicht wie ich mit deinem lösungsansatz da weitermachen könnte...
hm, grade noch mal getestet, offsetTop/Left geht auch bei Positionierung, zumindestens im FF, IE habe ich am Mac jetzt nicht... Schau doch mal das Script mit einem Mix aus relativer und absoluter Positionierung an, vielleicht hülfts,
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<style type="text/css">
body {
margin: 0;
}
div {
margin: 100px;
border: 1px solid red;
}
p {
position: absolute;
top: 150px;
left: 150px;
border: 1px solid green;
}
</style>
<script type="text/javascript">
function findPos(el) {
var xPos = 0;
var yPos = 0;
while(el) {
xPos += el.offsetLeft;
yPos += el.offsetTop;
el = el.offsetParent;
}
return {xPos: xPos, yPos: yPos};
}
function get_pos() {
var p = document.getElementsByTagName("p")[0];
alert ("x: " +findPos(p).xPos + ", y: " + findPos(p).yPos);
}
</script>
</head>
<body onload="get_pos()">
<div>
<div style="position:relative">
<p>x</p>
</div>
</div>
</body>
</html>
Gruesse, Joachim
hallo joachim,
vielen dank erstmal. also bei deinem skript passiert ja folgendes: ausgegeben werden die x/y Koordinaten von "X".
diese ändern sich je nachdem ob der umgebende container relativ oder static positoniert ist. die Koordinaten beziehen sich IMMEr auf das Browserfenster. tja in meinem fall ist ja nun so dass diese Koordinaten als WErte für top und left übergeben werden. Und genau das soll nicht sein, wie soll ich denn das element richtig positionieren?
ich weiss einfach keine lösung..
vg melanie
Hi,
diese ändern sich je nachdem ob der umgebende container relativ oder static positoniert ist.
hm, grade festgestellt dass IE völlig durcheinander gerät, sobald positioniert wird, auch bei relative... ABER: gib dem/den relative positionierten containtern mal in conditional comments eine dummy-höhe von 1 px: das zwingt ihn, korrekt zu rechen. Dann jedenfalls funktioniert mein Test.
Gruesse, Joachim
Hi,
diese ändern sich je nachdem ob der umgebende container relativ oder static positoniert ist.
hm, grade festgestellt dass IE völlig durcheinander gerät, sobald positioniert wird, auch bei relative... ABER: gib dem/den relative positionierten containtern mal in conditional comments eine dummy-höhe von 1 px: das zwingt ihn, korrekt zu rechen. Dann jedenfalls funktioniert mein Test.
Hallo Joachim,
ich kann meinem container in dem projekt leider kein hash-layout zuweisen weil dann mehrere andere schlimme Dinge passieren ;// )
ich verstehe auch leider immer noch nicht wie mir die Berechnung helfen könnte mein Problem zu lösen. das PRinzip meine ich ein wenig durchblickt zu haben aber eine Lösung nihct...
vg melanie
function findPosX(obj) {
function findPosY(obj) {
berechnet Dir die Position eines _nicht_ absolut positionierten Elementes. Um die Position eines absolut positionierten Elementes zu bekommen musst Du auf die Css-Eigenschaften style.top/left zugreifen, bzw das ggf kombinieren.
Unsinn!
style.top/left geben nur die Werte zurück, die du dort setzt.
Struppi.
Das Problem: Unser rte liegt nun in einem div mit noch vielen anderen html-elementen welcher positiono: relative; bekommen hat. Nun funktioniert die Positionierung der Farbpalette nicht mehr: der Bezugspunkt ist ein anderer.
Muss der unbedingt relativ postioniert werden?
Oft kann mit padding und margin das gleiche erreicht werden.
Die Position eines positionierten Elementes innerhalb eines relativ positionierten Elementes ist nicht ganz trivial, ich selber habe keine endgültige Lösung gefunden, eine war, wenn das Element relativ positioniert ist, addiere die offset Werte zweimal.
Was aber nicht in jeden Browser funktionierte. Ich hab's dann irgendwann aufgegeben die Position von relativ positionierte Elementen zu ermitteln
Struppi.
Das Problem: Unser rte liegt nun in einem div mit noch vielen anderen html-elementen welcher positiono: relative; bekommen hat. Nun funktioniert die Positionierung der Farbpalette nicht mehr: der Bezugspunkt ist ein anderer.
Muss der unbedingt relativ postioniert werden?
Oft kann mit padding und margin das gleiche erreicht werden.
das ist eine komplizierte geschichte. Position relative brauch ich in diesem Fall um einen hässlichen bug im Ie in den Griff zu kriegen. ich hab schon alles mögliche versucht um darauf zu verzichten, keine Chance.
Die Position eines positionierten Elementes innerhalb eines relativ positionierten Elementes ist nicht ganz trivial, ich selber habe keine endgültige Lösung gefunden, eine war, wenn das Element relativ positioniert ist, addiere die offset Werte zweimal.
Was aber nicht in jeden Browser funktionierte. Ich hab's dann irgendwann aufgegeben die Position von relativ positionierte Elementen zu ermitteln
ohjeh ohjeh..das hab ich befürchtet...
Das Problem: Unser rte liegt nun in einem div mit noch vielen anderen html-elementen welcher positiono: relative; bekommen hat. Nun funktioniert die Positionierung der Farbpalette nicht mehr: der Bezugspunkt ist ein anderer.
Muss der unbedingt relativ postioniert werden?
Oft kann mit padding und margin das gleiche erreicht werden.
Naja, wenn man zu harten Mitteln greifen muss... - da muss es doch einen anderen Weg geben, aber ich kann mir vorstellen dass das nicht einfach wäre uns zu erklären, man kennt ja die Merkwürdigkeiten die auftauchen in einer komplexen Seite.
das ist eine komplizierte geschichte. Position relative brauch ich in diesem Fall um einen hässlichen bug im Ie in den Griff zu kriegen. ich hab schon alles mögliche versucht um darauf zu verzichten, keine Chance.
Die Position eines positionierten Elementes innerhalb eines relativ positionierten Elementes ist nicht ganz trivial, ich selber habe keine endgültige Lösung gefunden, eine war, wenn das Element relativ positioniert ist, addiere die offset Werte zweimal.
Was aber nicht in jeden Browser funktionierte. Ich hab's dann irgendwann aufgegeben die Position von relativ positionierte Elementen zu ermittelnohjeh ohjeh..das hab ich befürchtet...
Also nicht dass meine Aussage endgültig wäre. Ich kann mir vorstellen, dass es welche hier gibt, die der Lösung näher kamen. Vielleicht funktioniert ja auch currentStyle bzw. getComputedStyle?
Wie gesagt ich hatte es irgendwann nicht mehr versucht, weil ich es auch nciht brauchte.
Struppi.
Also nicht dass meine Aussage endgültig wäre. Ich kann mir vorstellen, dass es welche hier gibt, die der Lösung näher kamen. Vielleicht funktioniert ja auch currentStyle bzw. getComputedStyle?
Wie gesagt ich hatte es irgendwann nicht mehr versucht, weil ich es auch nciht brauchte.
ja gut damit muss ich mich mal auseinandersetzen. was ich mir aus meinem naiven Verständnis von JS heraus überlegt habe:
ich müsste mit JS den Abstand des relativ positionierten Containers im Bezug auf das Browserfenster berechnen: also top und left. Diese Werte müsste ich dann abziehen von den Werten welche das script errechnet wenn es den aBstand der Farbpalette von oben und von links des Browserfensters berechnet.
Ist das a: logisch? und b. machbar? ;)
vg melanie
ja gut damit muss ich mich mal auseinandersetzen. was ich mir aus meinem naiven Verständnis von JS heraus überlegt habe:
ich müsste mit JS den Abstand des relativ positionierten Containers im Bezug auf das Browserfenster berechnen: also top und left.
top und left sowieso nicht, falls du style.top/left meinst, diese enthalten nur das was du reingeschrieben hast.
Mit ist grad eingefallen, dass soweit ich mich erinnere, nicht das Problem in der Ermittlung der Position bestand, sondern in der Positionierung. D.h. die Funktion die dir Joachim gezeigt hat sollte korrekt die Position ermitteln, nur positionieren mit style.top/left passiert immer relativ und d.h. du musst die Position, die du setzen willst in Relation zum relativen elternelement ermitteln. (ich hab das nicht ausprobiert, das war so soweit ich mich noch erinnere und wie gesagt, dann gab's noch Probleme mit den diversen Browsern)
Struppi.
top und left sowieso nicht, falls du style.top/left meinst, diese enthalten nur das was du reingeschrieben hast.
..ich dachte nur wenn das skript den ABstand von oben und von links vom browserfenster von dieser farbpalette berechnen kann dann sollte es das doch auch beim container also einem beliebigen anderen element können.
Mit ist grad eingefallen, dass soweit ich mich erinnere, nicht das Problem in der Ermittlung der Position bestand, sondern in der Positionierung.
ja genau.
D.h. die Funktion die dir Joachim gezeigt hat sollte korrekt die Position ermitteln, nur positionieren mit style.top/left passiert immer relativ und d.h. du musst die Position, die du setzen willst in Relation zum relativen elternelement ermitteln. (ich hab das nicht ausprobiert, das war so soweit ich mich noch erinnere und wie gesagt, dann gab's noch Probleme mit den diversen Browsern)
warte...im skript gibt es da diese zwei relevanten auszüge, ich poste sie jetz einfach mal hier um evtl. aneinandervorbeireden auszuschliessen...
//get dialog position
var buttonElement = document.getElementById(command + '_' + rte);
var iLeftPos = findPosX(buttonElement);
var iTopPos = findPosY(buttonElement) + (buttonElement.offsetHeight + 4);
var oDialog = document.getElementById('cp');
oDialog.style.left = (iLeftPos) + "px";
oDialog.style.top = (iTopPos) + "px";
if ((command == parent.command) && (rte == currentRTE)) {
//if current command dialog is currently open, close it
if (oDialog.style.display == "none")
showHideElement('cp', 'show');
} else { showHideElement('cp', 'hide');
}
} else {
showHideElement('cp', 'show');
}
//save current values
parent.command = command;
currentRTE = rte;
} catch (e) {
if (debugMode) alert(e);
}
}
und dann noch:
//positioning functions courtesy of Peter-Paul Koch - http://www.quirksmode.org/
function findPosX(obj) {
var curleft = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curleft += obj.offsetLeft;
obj = obj.offsetParent;
}
} else if (obj.x) {
curleft += obj.x;
}
return curleft;
}
function findPosY(obj) {
var curtop = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curtop += obj.offsetTop;
obj = obj.offsetParent;
}
} else if (obj.y) {
curtop += obj.y;
}
return curtop;
}
tjaa... ;//
top und left sowieso nicht, falls du style.top/left meinst, diese enthalten nur das was du reingeschrieben hast.
..ich dachte nur wenn das skript den ABstand von oben und von links vom browserfenster von dieser farbpalette berechnen kann dann sollte es das doch auch beim container also einem beliebigen anderen element können.
Jein, offsetLeft/Top ist ja schon relativ zu einem beliebigen, du hast es aber wenn ich das richtig verstanden habe nochmal absolut positioniert. Ich werd schon ganz konfus
Mit ist grad eingefallen, dass soweit ich mich erinnere, nicht das Problem in der Ermittlung der Position bestand, sondern in der Positionierung.
ja genau.
D.h. die Funktion die dir Joachim gezeigt hat sollte korrekt die Position ermitteln, nur positionieren mit style.top/left passiert immer relativ und d.h. du musst die Position, die du setzen willst in Relation zum relativen elternelement ermitteln. (ich hab das nicht ausprobiert, das war so soweit ich mich noch erinnere und wie gesagt, dann gab's noch Probleme mit den diversen Browsern)
warte...im skript gibt es da diese zwei relevanten auszüge, ich poste sie jetz einfach mal hier um evtl. aneinandervorbeireden auszuschliessen...
//get dialog position
var buttonElement = document.getElementById(command + '_' + rte);
var iLeftPos = findPosX(buttonElement);
var iTopPos = findPosY(buttonElement) + (buttonElement.offsetHeight + 4);
var oDialog = document.getElementById('cp');
oDialog.style.left = (iLeftPos) + "px";
oDialog.style.top = (iTopPos) + "px";
und hier müßtest du jetzt noch zusätzlich ermitteln, ob offsetParent relativ positioniert ist und wenn ja die Werte dazu addieren. Vermute ich mal.
Tut mir leid ich hab heute keine Zeit mehr, sonst würd ich das mal probieren, aber jetzt bin ich bis morgen weg.
Struppi.
Jein, offsetLeft/Top ist ja schon relativ zu einem beliebigen, du hast es aber wenn ich das richtig verstanden habe nochmal absolut positioniert. Ich werd schon ganz konfus
und ich bins schon ;)
Tut mir leid ich hab heute keine Zeit mehr, sonst würd ich das mal probieren, aber jetzt bin ich bis morgen weg.
kein thema schonmal vielen dank für die hilfe. ich versuch mal ein beispiel online zu stellen damit es transparenter wird. vielleicht magst Du dann nochmal reinschauen ich hoffe der thread ist dann noch nicht ganz verschwunden.
vg melanie