2009-08-19 3 views
0

Ich habe eine Seite, die DIVs enthält, die kurze Sätze (ein-zwei Wörter) unterschiedlicher Schriftgrößen enthalten, die nach einem numerischen Parameter von links nach rechts positioniert werden müssen, und vertikal, um nicht zu überlappen.Positionieren von Divs halb zufällig, ohne Überlappungen

Es ist wie ein Tag-Cloud, aber es gibt Informationen, die in der y-Achse enthalten sowie („Kühle“ in diesem Fall - http://cool-wall.appspot.com)

Wie soll ich diese auslegen? Ich bin derzeit eine sehr unordentlich Reihe von DIVs wie folgt aus:

<div style="position:absolute; top:150px;left:10px;right:10px;bottom:10px"> 

<!-- then, repeated, with different top, left and font-size values --> 

    <div style="align:center; margin:0; border:none; padding:0; float:left; visibility:visible; position:absolute; top:21%; left:56%; font-size:11px"> 
    <div style="margin-top:0%; margin-right:50%; margin-bottom:0%; margin-left:-50%;"> 
     <a href="foo"><span style="display:inline"> &larr; </span></a> 
     <a href="bar"><span style="display:inline"> Buzz </span></a> 
     <span style="display:inline"> &rarr; </span> 
    </div> 
    </div> 

    <!-- of course, followed by a close div --> 

</div> 

Ich benutze ein Sheet einige dieser Arten zu extrahieren, und ich merke, dass es ziemlich schlecht CSS (und HTML) ... aber das war alles, was ich zusammenhacken konnte, um (fast) das zu tun, was ich tun wollte. Das Hauptproblem mit dem oben genannten (abgesehen davon, dass es verwirrend ist) ist, dass ich die Positionierung nicht so einstellen kann, dass sie sich nicht überschneidet, weil ich nicht weiß, wie groß die Schriftart sein wird und wie sie auf dem Bildschirm angezeigt wird.

Gerne verwenden Sie JavaScript, um es richtig zu machen. Aber ich weiß nicht, wo ich anfangen soll. Irgendwelche Tipps?

Antwort

0

Der x-Wert wird auf jeden einzelnen gesetzt, so hoch wie möglich auf der Seite (niedrigster y) wie es gehen kann ohne überlappend. Nicht so schlecht:

1) Den Container rendern - Position: relativ; Rendern Sie jedes Objekt innerhalb des Containers mit "position: absolute; top: 0; left: -1000;" - zeichne sie alle aus dem Bildschirm.

2) Verschieben Sie das Element nacheinander nach Bedarf x-coorinate und y = 0; Prüfen Sie es mit allen vorherigen Renderelemente zu sehen, ob es kollidiert, wenn es der Fall ist, bewegen sie ein Pixel nach unten, bis es kollidiert:

var regions = []; 
for(var i = 0; i < items.length; i++){ 
    var item = items[i]; 

    item.style.x = getX(item); // however you get this... 
    var region = YAHOO.util.Dom.getRegion(item); 
    var startingTop = region.top; 
    for(var iReg = 0; iReg < regions.length; iReg++){ 
    var existingRegion = regions[iRegion]; 
    while(region.intersect(existingRegion)){ 
     region.top++; 
     region.bottom++; 
    } 
    item.style.y = (region.top - startingTop) + 'px'; 
    } 
} 

Es ist wichtig, nur die Region zu aktualisieren und nicht wirklich den dom Knoten verschieben Aus Leistungsgründen jeweils 1px.

Setzen Sie die wichtigsten Elemente zuerst und sie rendern mit höherer Priorität als Objekte darunter.

+0

Das sieht wirklich gut aus. Aber ich denke, es gibt ein paar Bugs in dem obigen Code: "... Regionen [iRegion];" sollte "regions [iReg]" sein; Und Sie müssen die Regionen zu dem Array am unteren Rand der äußersten for-Schleife hinzufügen: regions.push (region); ... Außerdem benötigt es Yahoos YUI-Code, der meiner Meinung nach am besten instanziiert wird durch:

1

Es gibt eine JavaScript-Eigenschaft auf dem dom-Objekt, die Ihnen die Höhe des Tags mitteilen wird, wenn Sie die Breite festgelegt haben. Ich glaube, es heißt clientHeight

alert (document.getElementById ('myElement'). OffsetHeight);

Versuchen Sie, dass (auch http://www.webdeveloper.com/forum/archive/index.php/t-121578.html sehen)

OR

Versuchen Sie, diese

<span style="margin-top:${randomNumber}px;margin-bottom:${randomNumber}">randomtext</span> 
<span style="margin-top:${randomNumber}px;margin-bottom:${randomNumber}">randomtext</span> 
.. 
<span style="margin-top:${randomNumber}px;margin-bottom:${randomNumber}">randomtext</span> 

Ihr Element alle haben nur inline angezeigt werden, geben sie in zufälliger Reihenfolge, und dann setzen Zufallsmarge auf sie . Dies könnte alles mit serverseitigem Code geschehen (oder Javascript, wenn Sie es clientseitig haben wollen).

+0

Ist es möglich, dies automatisch zu tun, ohne eine Menge Berechnungen in JavaScript durchzuführen? Soweit ich das beurteilen kann, müsste ich mit dieser Eigenschaft eine Funktion haben, um die Teile des Bildschirms zu berechnen, die mit DIVs belegt sind, und dies entweder zu verfolgen oder jedes Mal neu zu berechnen ... oder? –

+0

Nicht mit absoluter Position.Die einzige Möglichkeit, das zu tun, was Sie tun möchten, ist Javascript. Schwebende Elemente lassen sie nach links (oder rechts) des Bildschirms schweben und nehmen so viel horizontalen Platz wie möglich ein. Dies funktioniert jedoch nicht für vertikalen Raum. Das Javascript, um so etwas zu tun, wäre nicht zu schwierig. Sie müssen nur die Elemente durchlaufen, die daran beteiligt sind, und anhand der Breite und Höhe den besten Platz für die Platzierung berechnen. – Zoidberg

+0

OK, interessant. Sie haben auch erwähnt, dass dies "wenn Sie die Breite eingestellt haben" funktioniert. Ich weiß nicht, wie groß es sein wird, bis es gerendert wird, da es von der Schriftart und Schriftgröße abhängt. Ich würde denken, dass ich auch eine ähnliche Funktion benötigen würde, um die Breite zu bekommen, damit ich die Bildschirmnutzungsberechnung machen kann. Ich nehme an, ich kann OffsetWidth auf die gleiche Weise verwenden? –

0

Positionieren Sie Ihre Elemente nicht unbedingt. Dies ist der Grund, warum sie aufeinander fallen ....

+0

OK, aber wie soll ich sie positionieren? Ich möchte einen absoluten X-Wert und einen Y-Wert, der keine Überlappung verursacht. –