如何从卡片或类似文件中获取标题以与弹性框具有相同的高度?

Posted

技术标签:

【中文标题】如何从卡片或类似文件中获取标题以与弹性框具有相同的高度?【英文标题】:How to get header from cards or similar to have the same height with flex box? 【发布时间】:2018-03-17 16:41:15 【问题描述】:

请不要破解

没有硬编码。这个想法不是针对一种情况解决它,例如对于有 4 列的情况,但要解决动态内容和响应式屏幕尺寸的问题。

对我来说问题是基本上不是直子,而是它的内容

在这里编写代码:

https://codepen.io/anon/pen/OxzrzV

html

<h1>disclaimer: resize the window. Make the blue headers in a row match height</h1>
<div class="row mycontainer">
  <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
      <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
      </div>
  </div>
  <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala some content lala some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
      <div class="item">
       <div class="header">oh no this header wraps</div>
        <div class="content">some content lala </div>
      </div>
  </div>
</div>

CSS

 body
  padding: 20px;


.item
  height: 100%;
  padding-right: 20px;
  padding-top: 20px;
  display: flex;
  flex-direction: column


.header
  background-color: cornflowerblue;


.content
  background-color: salmon;
  flex-grow: 1;


.mycontainer
  max-width: 500px;

我想要什么?

蓝色标题始终与当前行中的所有元素具有相同的大小。

一个可靠的 jquery 解决方案也很好......但它必须是万无一失的并且也可以调整大小。 html结构的一般变化也很好。但必须响应正确。

所以这个(通过硬编码而不是响应式实现):

【问题讨论】:

我的回答中是否缺少某些内容,我可以添加或调整以供您接受? @LGSon 我不太了解“css 方式”,但这不是你的错。干得好 【参考方案1】:

基本上有两种方法可以做到这一点,CSS方式,

CSS - How to have children in different parents the same height?

还有脚本方式,这里使用jQuery。


第一个脚本示例展示了如何在所有项目上设置相等的高度。

第二个样本将每行的高度设置为相等,实现此目的的方法是检查项目的最高值(它会更改为新行)并为每个处理的范围/行设置高度。

我还添加了一些优化,预加载项目,因此如果只有 1 个项目或列,它将不会处理它们。


Updated codepen 1

堆栈 sn-p 1

(function ($) 

  // preload object array to gain performance
  var $headers = $('.header')
  
  // run at resize
  $( window ).resize(function() 
    $.fn.setHeaderHeight(0);   
  );  

  $.fn.setHeaderHeight = function(height) 

    // reset to auto or else we can't check height
    $($headers).css( 'height': 'auto' );
    
    // get highest value
    $($headers).each(function(i, obj)     
      height = Math.max(height, $(obj).outerHeight()) 
    );

    // set the height
    $($headers).css( 'height': height + 'px' );    
  

  // run at load
  $.fn.setHeaderHeight(0);
  
(jQuery));
body
  padding: 20px;


.item
  height: 100%;
  padding-right: 20px;
  padding-top: 20px;
  display: flex;
  flex-direction: column


.header
  background-color: cornflowerblue;


.content
  background-color: salmon;
  flex-grow: 1;


.mycontainer
  max-width: 500px;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.css" rel="stylesheet"/>

<div class="row mycontainer">
  <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
      <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
      </div>
  </div>
  <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala some content lala some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
      <div class="item">
       <div class="header">oh no this header wraps</div>
        <div class="content">some content lala </div>
      </div>
  </div>
</div>

Updated codepen 2

堆栈 sn-p 2

(function ($) 
  //  preload object array to gain performance
  var $headers = $('.header')

  // only do this if there is more than 1 item
  if ($headers.length < 2)  return; 
    
  //  run at resize
  $( window ).resize(function() 
    $.fn.setHeaderHeight(0,0);   
  );

  $.fn.setHeaderHeight = function(height, idx) 
    // reset to auto or else we can't check height
    $($headers).css( 'height': 'auto' );
     
    $($headers).each(function(i, obj)     

      // only continue if there is more than 1 column
      if ($($headers).eq(0).offset().top !== $($headers).eq(1).offset().top  ) 
        return false;
      
      
      // get highest value
      height = Math.max(height, $(obj).outerHeight()) 
      
      // did top value changed or are we at last item
      if (i != 0 && $($headers).eq(i - 1).offset().top != $(obj).offset().top) 

        // set height for row
        $($headers).slice(idx, i).css( 'height': height + 'px' );
        
        // reset height and startIndex
        height = 0;
        idx = i;
       else if ($headers.length - 1 == i) 
        
        // last row
        $($headers).slice(idx, i + 1).css( 'height': height + 'px' );   
      

    );        
  
  
  //  run at load
  $.fn.setHeaderHeight(0,0);

(jQuery));
body
  padding: 20px;


.item
  height: 100%;
  padding-right: 20px;
  padding-top: 20px;
  display: flex;
  flex-direction: column


.header
  background-color: cornflowerblue;


.content
  background-color: salmon;
  flex-grow: 1;


.mycontainer
  max-width: 500px;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.css" rel="stylesheet"/>

<div class="row mycontainer">
  <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
      <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
      </div>
  </div>
  <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala some content lala some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
      <div class="item">
       <div class="header">oh no this header wraps</div>
        <div class="content">some content lala </div>
      </div>
  </div>
</div>

由于有些人更喜欢纯 javascript,我也更新了这样的示例(在所有项目上设置相等的高度),它动态地应用/添加一个类,计算 height 值。

堆栈sn-p

(function(d,t,h) 
  /*  preload some variables  */
  h = (d.head || d.getElementsByTagName('head')[0]);
  var items = d.querySelectorAll('.header');
  
  function resized() 
    var heights = [], i = 0, css;
    /*  delete set style so we get proper value  */
    removeElement('head_dynamic_css');
    for (i = 0; i < items.length; i++) 
      heights.push(parseFloat(window.getComputedStyle(items[i], null).getPropertyValue("height")));
    
    css = ".header  height: " + Math.max.apply(null, heights) + "px; ";
    /*  create and add style with height  */
    var s = d.createElement('style');
    s.type = 'text/css';
    s.id = 'head_dynamic_css';
    if (s.styleSheet) 
      s.styleSheet.cssText = css
     else 
      s.appendChild(d.createTextNode(css));
    
    h.appendChild(s);
  

  window.addEventListener("load", resized, false);
  window.addEventListener("resize", resizer, false);
  function resizer() 
    if (!t) 
      t = setTimeout(function() 
        t = null;
        resized();
       , 66);
    
  
  function removeElement(el) 
    var el = document.getElementById(el);
    if (el) 
      el.parentElement.removeChild(el);
    
  
(document,null));
body 
  padding: 20px;


.item 
  height: 100%;
  padding-right: 20px;
  padding-top: 20px;
  display: flex;
  flex-direction: column


.header 
  background-color: cornflowerblue;


.content 
  background-color: salmon;
  flex-grow: 1;


.mycontainer 
  max-width: 500px;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.css" rel="stylesheet"/>

<div class="row mycontainer">
  <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
      <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
      </div>
  </div>
  <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
    <div class="item">
       <div class="header">bippo</div>
        <div class="content">some content lala some content lala some content lala </div>
    </div>
  </div>
    <div class="col-12 col-md-4 col-lg-3">
      <div class="item">
       <div class="header">oh no this header wraps</div>
        <div class="content">some content lala </div>
      </div>
  </div>
</div>

【讨论】:

Updated codepen 1 存在一些问题,基本上它仅在最后一项是使标题换行的项时才有效。我修复了我现在还添加了创建“标题组”的可能性,以便您可以说“标题必须在各自的组中具有相同的高度。请在看到它们时提供反馈或改进codepen.io/anon/pen/POozLo @Toskan 你能否给我看一个使用我的codepen 1 中的脚本的版本,该版本仅在最后一项是使标题换行的项目时才有效? ....正如我在上一个问题中所说,不使用 CSS 框架像 Bootstrap 一样工作,我也不使用 jQuery,也制作了自己的脚本库,并且不熟悉它的所有功能:) 对不起,我的意思是 codepen 2。codepen.io/anon/pen/eemNKq 我正在考虑在 github 上为它创建一个 jquery 插件【参考方案2】:

这里你有我使用 jQuery 的方法。事情变得更加复杂,因为您希望每行的高度相等,但独立于其他行。

我所做的是使用每个元素的顶部位置作为行标识符,循环遍历所有标题,为它们添加一个具有该位置的类,以便稍后我们可以使用该类选择一整行。在每个循环中,我检查高度并保存最大值,当我检测到我们在新行中(顶部位置已更改)时,我使用类 I 将行最大高度应用于前一行的所有元素已分配。

这里是代码...

function adjustHeaderHeights() 

    // First reset all heights to just increase if needed.
    $('div.header').css('height','auto');

    var curRow=$('div.header').first().offset().top,
        curRowMaxHeight=$('div.header').first().height();
    var n = $('div.header').length;

    $('div.header').each(function(index) 

        // Get header top position as row identifier, and add it as a class.
        var rowId = $(this).offset().top;
        $(this).addClass('rowid'+rowId);

        if (rowId != curRow)   // It's a new row.
            $('div.header.rowid'+curRow).height(curRowMaxHeight);
            curRow = rowId;
            curRowMaxHeight=$(this).height();
        
        else 
            curRowMaxHeight = $(this).height() > curRowMaxHeight ? $(this).height() : curRowMaxHeight;

            // It's the last header element, so we adjust heights of the last row.
            if (index+1 == n)
                $('div.header.rowid'+curRow).height(curRowMaxHeight);
        
    );



$(window).resize(function() 
    adjustHeaderHeights();
);

adjustHeaderHeights();

希望对你有帮助

【讨论】:

以上是关于如何从卡片或类似文件中获取标题以与弹性框具有相同的高度?的主要内容,如果未能解决你的问题,请参考以下文章

弹性负载平衡

如何从 Lync 联系人卡片中获取用户的电话号码或其他联系人详细信息?

如何通过熊猫或火花数据框删除所有行中具有相同值的列?

如何从 Angular 的弹性框中的组件中获取元素信息

每四个元素后动态打破弹性框[重复]

以与 Jupyter Notebook 相同的样式将 pandas 数据框呈现为 HTML