Linuchs: Feld-Position x,y berechnen

Hallo,

bei Eingabe eines oder mehrerer Zeichen in ein inputFeld werden per Ajax mehrere Vorschlagswerte geholt und unter dem Eingabefeld angezeigt.

Da die Javascript-Routine für mehrere Felder und sogar mehrere Formulare gedacht ist, muss ich bei der ersten Nutzung das Anzeige-Feld positionieren. Damit erspare ich mir die Positionierung in den HTML-Formularen.

Doch das Anzeige-Feld wird zu weit rechts und zu weit unten platziert, als ob die Abstände doppelt berechnet werden. Aber ich komme nicht drauf, warum.

So sieht es aus:

Bildbeschreibung

Dazu die Positionierungs-Routine:

function zeigeVorschlaege()
{
  // http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp
  // The onreadystatechange event is triggered every time the readyState changes.
  if ( request.readyState == 4 && request.status == 200 )
  {
    // vorschlagsfeld einmal initialisieren
    if ( document.getElementById( id_sic+"_vorschlaege" ).style.left == 0 ) 
    {
      var left =  5;
      var top  = document.getElementById( id_sic ).offsetHeight;
      var Eltern = document.getElementById( id_sic ).offsetParent;
      while (Eltern) 
      {
        if ( Eltern.style.position=="absolute" || Eltern.style.position=="relative" ) break;
        left += Eltern.offsetLeft;
        top  += Eltern.offsetTop;
        Eltern = Eltern.offsetParent;
      }
      document.getElementById( id_sic+"_vorschlaege" ).style.left    = left+"px";
      document.getElementById( id_sic+"_vorschlaege" ).style.minWidth
        = document.getElementById( id_sic ).offsetWidth +"px";
      document.getElementById( id_sic+"_vorschlaege" ).style.top     = top+"px";
    }
    document.getElementById( id_sic+"_vorschlaege" ).innerHTML     = request.responseText;
    document.getElementById( id_sic+"_vorschlaege" ).style.display = "block";
  }
//alert ("["+id_sic+"] width=["+document.getElementById( id_sic ).style.width+"]");
}

Linuchs

  1. Ergänzende Info: id_sic ist die ID des zugehörigen input-Feldes

  2. Hey,

    ich denke die HTML-Struktur wäre auch hilfreich. Und vor allem: was hast du bei "id_sic_vorschlaege" (und den anderen Elementen in der offsetParent-Kette) für

    position
    

    angegeben?
    Was zum "anfassen" würde den Fehler vermutlich schneller ans Tageslicht bringen. jsfiddle?

    Reinhard

    1. ich denke die HTML-Struktur wäre auch hilfreich.

      Uups, bis ich die auf das Wesentliche zusammengestrichen habe ...

      Und vor allem: was hast du bei "id_sic_vorschlaege" (und den anderen Elementen in der offsetParent-Kette) angegeben?

      position: absolute;
      

      Ich habe ein alert in die while-Schleife eingebaut. Und misstraue den einzelnen Werten, die ich da summiere.

      
            var Eltern = document.getElementById( id_sic ).parentElement; // offsetParent;
            lfd = 0;
            while (Eltern) 
            {
              alert( ++lfd +". [" +Eltern.nodeName +"] left=[" +Eltern.offsetLeft +"] top=[" +Eltern.offsetTop +"]" );
              if ( Eltern.style.position=="absolute" || Eltern.style.position=="relative" ) break;
              left += Eltern.offsetLeft;
              top  += Eltern.offsetTop;
              Eltern = Eltern.parentElement;
            }
      

      Der parent von INPUT ist TD, soll 160 px unter TR liegen, TR wiederum 160 px unter TBODY.

      TD kommt aber unmittelbar unter TR, also 0 wäre richtig.

      Linuchs

      1. Hey,

        Und vor allem: was hast du bei "id_sic_vorschlaege" (und den anderen Elementen in der offsetParent-Kette) angegeben?

        position: absolute;
        

        ...

        Ich habe ein alert in die while-Schleife eingebaut. Und misstraue den einzelnen Werten, die ich da summiere. Der parent von INPUT ist TD, soll 160 px unter TR liegen, TR wiederum 160 px unter TBODY. TD kommt aber unmittelbar unter TR, also 0 wäre richtig.

        So, ich vermute nun mal, dass du das "id_sic_vorschlaege"-Element direkt als Kindelement im body stehen hast mit position: absolute. Warum bei deiner while Schleife so ein Quark raus kommt weiß ich nicht; dazu müsste ich mir die Seite im Browser genauer ansehen.
        Mal nebenbei (ungetestet): "id_sic_vorschlaege" absolut positioniert als Kindelement von dem Input-Eltern-Element (TD) setzen und jenes relativ positionieren. Dann noch id_sic_vorschlaege.top = id_sic.offsetHeight + 'px'; und id_sic_vorschlaege.left = '5px';

        Reinhard

        1. Hallo Reinhard,

          Mal nebenbei (ungetestet): "id_sic_vorschlaege" absolut positioniert als Kindelement von dem Input-Eltern-Element (TD) setzen und jenes relativ positionieren. Dann noch id_sic_vorschlaege.top = id_sic.offsetHeight + 'px'; und id_sic_vorschlaege.left = '5px';

          Danke, der Vorschlag funktioniert und ich mache das so. Ungeklärt bleibt aber, warum das Auf-Addieren der parent-offsetTop ein falsches Ergebnis lieferte.

          Linuchs