【问题标题】:Combine float and absolute position结合浮动和绝对位置
【发布时间】:2015-02-02 02:32:27
【问题描述】:

我正在创建一个日历,其中所有事件都显示在一个 div 中。根据topheight 的值,应该将事件放置在确定的位置。让我给你看看。

在这张图片中,早上 6 点的两个事件都处于相同的垂直对齐方式。我可以使用float: left(jsfiddle) 解决这种行为。

如果事件没有vertical alignment 冲突(高度和顶部不冲突),那么我可以使用absolute position(jsfiddle) 而不是float 来模拟这种行为。

问题

真正的问题是当我尝试将事件安排在上午 9 点和 9:40 并让它们看起来像上图时。假设以下属性:

  • 9:00高度:50px,顶部:200px
  • 9:40高度:50px,顶部:230px
  • 9:00 event 的底部:200px + 50px = 250px
  • 9:30 event 的顶部:230px
  • 然后,他们垂直分享20px (250px - 230px)。

这就是为什么我尝试做这样的事情:

<div class="container">
    <div class="event" style="height: 50px; top: 200px; float:left;">9 AM</div>
    <div class="event" style="height: 50px; top: 230px; float:left;">9:40 AM</div>
</div>

...但是 float 属性在具有绝对位置的元素中不起作用。

概述

我的想法是将top 值视为根据时间将事件垂直放置在日历中的指南。例如,

  • 上午 6 点 -> 顶部:100 像素
  • 上午 7 点 -> 顶部:150 像素
  • 晚上 8 点 -> 顶部:200 像素

实现方式

我尝试使用纯 ccs 自己解决这个问题,但我不介意应用 javascript。但是,我无法向您展示我对 javascript 的尝试,因为我什至无法做出相当大的 css 结果。正如我之前所说,我使用 top 属性是因为我认为它可以很容易地进行位置操作,但如果有必要我可以使用另一种方法。提前谢谢你。

【问题讨论】:

    标签: javascript html css css-float absolute


    【解决方案1】:

    使用相对定位几乎可以解决您的问题。但是,它会在事件之间留下空隙:

    Fiddle #1

    我知道解决这个问题的唯一方法是使用绝对定位,JavaScript 确定 topleft 坐标:

    var events= [].slice.call(document.querySelectorAll('.container div')),
                    //array of event elements. See http://davidwalsh.name/nodelist-array
        count= [],  //running total of events during an hour. used to calculate left offset.
        i,          //loop through the events
        time,       //event time as array, such as ['6','AM']
        hour,       //event hour (1 - 24)
        minute,     //event minute (0 - 59)
        offset;     //top offset based on hour and minute
    
    events.sort(function(a,b) {
      return a.textContent < b.textContent ? -1 : 1;
    });
    
    for(i = 0 ; i < events.length ; i++) {
      time= events[i].textContent.split(' ');
      hour= time[0].split(':')[0] * 1;
      if(time[1]==='PM' && hour !== 12) {
        hour+= 12;
      }
      minute= time[0].split(':')[1] || 0;
      offset= hour+minute/60;
      count[hour]= (count[hour] || 0)+1;
      events[i].style.top= (offset-6)*50 + 'px';
      events[i].style.left= count[hour]*100-100 + 'px';
    }
    

    Fiddle #2

    请注意,此代码需要进行一些调整以避免事件覆盖其他事件,因为您将在下午 12:00 使用 Fiddle。

    【讨论】:

    • Rick,你的代码很有意义。你能重命名 javascript 变量并稍微评论一下吗?我想了解并尝试在我身边改进您的代码,因为它看起来非常好应用
    • 哈,我的代码确实很简洁,尤其是当我在半夜编程的时候。对此表示歉意。我已经更新了我的答案,另外我添加了一个排序过程,以确保无论顺序如何,内容始终显示相同。
    【解决方案2】:

    您应该为您的 div 添加定位。如果您将position:relative 添加到您的类中,您将能够使用top:xxpx 来偏移垂直位置。我认为您将需要考虑许多可能使纯 css 解决方案变得困难的边缘情况,但认为这至少可能会有所帮助。

    这是一个小提琴:http://jsfiddle.net/markm/qvevedva/

    【讨论】:

    • 实际上使用relative 修复了很多结构:D。但正如你所说,需要做一个非常庞大的工作来填充边缘。
    【解决方案3】:

    如果您使用margin-top 而不是top,它对您有用吗?你也许可以得到这个结果:

    您可能还需要每小时创建一个容器 div 并在其中包含底层事件 div:

    <div class="container">
       <div class="event" style="height: 50px;">6AM</div>
       <div class="event" style=" height: 50px;">6AM</div>
    </div>
    <div class="container">
       <div class="event" style="height: 50px;">9 AM</div>
       <div class="event" style="height: 50px; margin-top: 25px;">9:30 AM</div>
       <div class="event" style="height: 50px; margin-top: 33px;">9:40 AM</div>
    </div>
    

    这是 JSFiddle 上的一些 sample 代码供参考。

    【讨论】:

    • 使用边距的问题是每个元素都相对于最近的元素,很容易破坏架构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多