【问题标题】:Positioning Divs semi-randomly, without overlaps半随机定位 Div,没有重叠
【发布时间】:2009-08-19 16:44:18
【问题描述】:

我有一个页面,其中包含 DIV,其中包含不同字体大小的短语(一两个词),需要根据数字参数从左到右放置,并且垂直放置,以免重叠。

它就像一个标签云,但也包含在 y 轴中的信息(在本例中为“coolness” - http://cool-wall.appspot.com

我应该如何布置这些?我目前正在使用一系列非常混乱的 DIV,如下所示:

<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>

我使用样式表来提取其中一些样式,并且我意识到它的 CSS(和 HTML)非常糟糕……但这就是我可以一起做的(几乎)我想做的事情。上面的主要问题(除了令人困惑之外)是我无法设置定位,因此它不会重叠,因为我不知道字体的大小,也不知道它在屏幕上的显示方式。

乐于使用 JavaScript 来做正确的事。但我不知道从哪里开始。有什么建议吗?

【问题讨论】:

    标签: javascript html css overlap


    【解决方案1】:

    如果您设置了宽度,则 dom 对象上有一个 javascript 属性会告诉您标签的高度。我相信它叫做clientHeight

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

    试试看(另见http://www.webdeveloper.com/forum/archive/index.php/t-121578.html

    试试这个

    <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>
    

    让你的所有元素只显示内联,以随机顺序输出它们,然后在它们上设置随机边距。这一切都可以通过服务器端代码(如果您需要客户端代码,也可以使用 javascript)来完成。

    【讨论】:

    • 是否可以自动执行此操作,而无需在 JavaScript 中进行大量计算?据我所知,有了这个属性,我需要一个函数来计算 DIV 占用的屏幕部分,并跟踪这个或每次重新计算......对吗?
    • 不是绝对位置。我能看到做你想做的事情的唯一方法是使用 Javascript。浮动元素会使它们浮动到屏幕的左侧(或右侧)并尽可能多地占用水平空间。但是,这不适用于垂直空间。用javascript做这样的事情不会太难。您只需遍历参与其中的元素并使用宽度和高度,计算放置它们的最佳位置。
    • 好的,很有趣。另外,您提到“如果您设置了宽度”,这将有效。在渲染之前我不知道它会有多大,因为它取决于字体渲染和字体大小。我认为我还需要一个类似的函数来获取宽度,所以我可以进行屏幕使用率计算。我想我可以以同样的方式使用 offsetWidth?
    • 是的,偏移宽度也是如此。我发布的链接显示该人也使用 scrollHeight 和 scrollWidth,(他获得了 scrollHeight 和 offsetHeight 之间的最大值)。那应该对你有用。当我开发需要动态更改 css 的创作工具时,它对我有用。 css 可以改变所有拖放元素的大小,因此需要重新定位一些东西。
    • 谢谢 - 这是一个非常好的答案。我仍然希望有人会知道一种使浏览器的布局引擎自动执行此操作的方法。 :-)
    【解决方案2】:

    x 值设置在每一个上,您希望在页面上尽可能高(最低 y),因为它可以不重叠。还不错:

    1) 渲染容器 - position:relative;使用“position:absolute; top:0; left:-1000;”渲染容器内的每个项目 - 将它们全部绘制到屏幕外。

    2) 一个一个地移动元素到它需要的x坐标和y=0;检查它与所有之前的渲染项是否发生冲突,如果发生冲突,将其向下移动一个像素,直到它不发生冲突:

    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';
      }
    }
    

    出于性能原因,重要的是只更新区域而不是实际将 dom 节点一次移动 1px。

    将最重要的项目放在首位,它们的优先级将高于其下方的项目。

    【讨论】:

    • 这看起来很不错。但我认为上面的代码中存在一些错误:“...regions[iRegion];”应该是“区域[iReg]”;您需要将区域添加到最外层 for 循环底部的数组中:regions.push(region); ...此外,它需要雅虎的 YUI 代码,我认为最好通过以下方式对其进行实例化:
    【解决方案3】:

    不要绝对定位你的元素。这就是它们相互重叠的原因......

    【讨论】:

    • 好的,但我应该如何定位它们?我想要一个绝对 X 值,以及任何不会导致重叠的 Y 值。
    猜你喜欢
    • 2015-02-28
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多