【问题标题】:Hiding overflowing element based on its height根据高度隐藏溢出的元素
【发布时间】:2015-06-10 15:41:09
【问题描述】:

我正在编写(使用纯 JavaScript = 无 JQuery)一个自定义控件,它是一个容器,当它们跨越多行并仅显示第一行时,它会折叠它的内容。当您单击控件中的按钮(向下箭头)时,容器会展开其所有内容。 如果内容仅跨越 1 行,我根本不显示按钮,它的行为就像一个常规容器。

下面的 2 张图片显示了控件折叠(上一张)和展开(下一张)。

我面临的问题是我如何知道何时显示按钮以及何时不显示按钮 = 如何检测内容是多行还是仅跨越单行。我的方法是获取元素的高度,然后折叠它并查看高度是否改变(如果改变了,那么它必须是多行的)。

这种方法的问题在于我的函数createCollapsingPanel() 我正在创建的元素尚未附加到 DOM - 函数返回元素,然后才会将其附加到 DOM(由 架构 1 如下)。如果这只涉及 1 个函数,我当然可以在函数内部移动附加(Architecture 2 下面)。不幸的是,这就是我编写所有函数的方式(它们返回元素,然后才将其附加到调用它们的外部函数中的父元素中),因此这意味着重新编写最终调用它的其他父函数,总的来说是我的整个功能架构。


架构 1

function createOuterElement() {
  var outerElement = document.createElement(...);

  outerElement.appendChild(createInnerElement());
  /* Do other things with outerElement */

  return outerElement;
}

function createInnerElement() {
  var innerElement = document.createElement(...);

  /* Do things with innerElement */

  return innerElement;
}

架构 2

function createOuterElement(parentElement) {
  var outerElement = document.createElement(...);

  parentElement.appendChild(outerElement);
  createInnerElement(outerElement);
  /* Do other things with outerElement */
}

function createInnerElement(parentElement) {
  var innerElement = document.createElement(...);

  parentElement.appendChild(innerElement);
  /* Do other things with innerElement */
}

主要问题

关于如何在我当前的架构(架构 1)中处理这个问题有什么想法吗?也许有一个事件我可以附加到控制元素上,它会在元素插入 DOM 并为其计算浏览器样式后被调用?

其他问题

架构 1 中编写函数是否被认为是一种不好的做法?我对非基本 JavaScript 还很陌生,所以不确定什么是好的做法。

【问题讨论】:

  • 你想使用“纯 JavaScript”还是像 jQuery 这样的库适合你的目的?
  • 我在我的项目中使用纯 JavaScript。尽管知道任何解决方案总是好的,即使在 JQuery 中也是如此。
  • 附加问题:我会在插入 dom 之前构建整个树。这可以通过两种架构来实现。在 architecture 2 的情况下,parentElement.appendChild(... 应该是 createOuterElement 函数的最后一次调用。
  • @dreamlab 要在将其插入到 DOM 之前构造一棵树(如您所建议的那样),Architecture 1 对我来说似乎是一个更优雅的解决方案 - 每个函数都有更小的范围,即不知道他们的父母是什么,在哪里以及如何附加。

标签: javascript dom size web-frontend


【解决方案1】:

你总是可以让内部容器是多行的,然后用外部容器夹住它。

关于外容器使用:

  • overflow: hidden
  • height:某个值

关于内胆使用:

  • position: absolute
  • height: auto

span's 放入内部容器中。

您现在可以独立于外部容器测量内部容器的高度。

【讨论】:

  • 我不明白这将如何解决我的问题。事实上,我使用相同的 CSS 来创建我的控件,只是我没有在内部容器上使用 position: absolute。问题在于我想在元素有多行时显示该按钮,并在它只有一行项目时隐藏它。
  • 没有。附加到 dom 后仍然需要测量。通过隐藏的 measerContainer、插入 dom 后的函数或 MutationObserver。我会在插入所有内容后推荐该功能。
  • 所以实际上这个解决方案和之前的解决方案是一样的——在整个结构都在DOM中之后调用一个测量函数。
  • javascript 是一样的。虽然 html/css 允许不必调整外部容器的大小来测量内部容器,就像你问的那样:我的方法是获取容器的高度,然后折叠它并查看高度是否改变(如果它做了,那么它必须是多行的)。
  • 我认为我用了错误的词 - 我的意思是折叠子元素,而不是父容器。对不起。但总的来说,我的问题在于 JavaScript,所以这两个答案都会导致相同的 JavaScript 解决方案。
【解决方案2】:

您可以使用 dom 中的隐藏容器来测量元素大小。隐藏容器可以是 dom 中的简单 div,例如:

   ...
   <body>
      <div id="measurementContainer" style="display:none;"></div>

测量函数可以:

  1. 将元素附加到测量容器 (div)
  2. 测量元素
  3. 并再次将其从测量容器中取出

例如:

    function measureElementWidth(element) {
       var measurementContainer = document.getElementById(measurementContainer);
       measurementContainer.appendChild(element);

       var width = element.clientWidth;

       measurementContainer.removeChild(element);

       return width;
}

或者,您可以使用MutationObservers 并在将元素添加到 dom 时收到通知。检查是否所有需要的浏览器support 这个。


甚至更简单:只需在将元素附加到 dom 后调用大小调整函数即可。

【讨论】:

  • 是的,现在我明白了。谢谢。相当巧妙的把戏。问题是测量容器并不能完全刺激最终将添加元素的父容器。将其附加到目标父级后的大小可能会因父级上应用的样式而有所不同。例如,在我的情况下,父级的宽度不是页面的 100%(并且它的宽度确实暗示容器将跨越多行还是仅一行)。
  • 在这种情况下。首先获取目标容器的宽度和高度,然后在测量容器上手动设置:measuringContainer.style.width = target.clientWidth + 'px'。对高度做同样的事情。
  • 但正如我所说,我的函数 iis 的架构如我的示例 Architecture 1 中所示。这样做的效果是在创建子代时,父代还没有被附加到 DOM 中,所以我无法计算它的大小。我当然可以将这些函数重写到 Architecture 2,但首先要确定这是绝对必要的,或者在 Architecture 1 中编写函数是一种非常糟糕的做法i>.
  • 插入outerElement后需要调用sizing函数。在此之前,让 innerElements 保持原样。
  • 我可以在父节点插入 DOM 后调用它。仍然(由于我的功能架构)只有在最外层的父级插入 DOM 之后才会发生。那里的问题是我没有任何容易接近的面板,它们被埋得很深。我当然可以将所有面板的引用存储在某个地方,但这种方法对我来说并不优雅。我想也许我可以在面板上附加一些事件,在它们已经在 DOM 中之后调用它们(类似于AfterAppendedToDOM)。有没有这样的事件你知道我可以在这里?
猜你喜欢
  • 2012-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 2015-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多