Jquery 如何在溢出:隐藏区域中添加DOM元素?

Jquery 如何在溢出:隐藏区域中添加DOM元素?,jquery,html,css,dom,Jquery,Html,Css,Dom,我正在创建一个每年显示表数据的控件。类型为table的DOM元素被添加到div中,该div将溢出设置为隐藏。这些表的位置设置为相对。div的height设置为固定一张桌子的高度,以便一次只能看到一张桌子 我有一个分页机制,可以向前和向后翻页,并通过更改表的top属性来设置转换的动画,使其看起来像是表数据在上下滑动。就像一个经典的日历 我面临的问题是:在添加新元素时,我希望将其添加到现有表顶部div内容的隐藏部分,以便在将其添加到DOM树后将其动画化到视图中。没有“黑客”这可能吗 在将表添加到di

我正在创建一个每年显示表数据的控件。类型为
table
的DOM元素被添加到
div
中,该div将
溢出设置为
隐藏。这些表的
位置
设置为
相对
div
height
设置为固定一张桌子的高度,以便一次只能看到一张桌子

我有一个分页机制,可以向前和向后翻页,并通过更改表的
top
属性来设置转换的动画,使其看起来像是表数据在上下滑动。就像一个经典的日历

我面临的问题是:在添加新元素时,我希望将其添加到现有表顶部div内容的隐藏部分,以便在将其添加到DOM树后将其动画化到视图中。没有“黑客”这可能吗

在将表添加到
div
之前,我尝试更改表的
top
属性,但这并没有将它们放入
div
溢出:隐藏部分

我怎样才能做到这一点

到目前为止,我在JSFIDLE中已经做到了这一点:

更新

我也尝试过使用hide()和slideDown(),但是slideDown的动画似乎不是很流畅(至少在jsfiddle中是这样)


您指定的尺寸是多少?如果您没有使用“height:500px”或类似的工具,那么在向div添加新元素时,div将被简单地扩展。

更新的答案

你在评论中说

我面临的问题是,我想预先准备新表

…我跟你确认过你想让新桌子从上面滑进去

以下原始答案中的大部分讨论涵盖了我们需要做什么以及我们如何做,下面是一个示例,说明了无论是从顶部还是从底部放入表格,我们都可以这样做:

或者,如果我们只需要在动画期间固定高度,则在开始时测量高度,然后固定高度,进行动画,然后取消固定高度(可能设置为新高度):


你能把你得到的东西发一篇文章吗?你是在添加新行吗?如果你发个代码,我也许能帮上忙snippet@MartinOngtangco不,我正在添加完整的表格,我现在正在准备一个JSFIDLE。@scragar我已经添加了JSFIDLE的链接。看着小提琴,你会看到一些有趣的行为,特别是如果你按照这个顺序将下拉列表改为2013、2012、2014。我现在正在工作,但是如果没有人解决你的问题,我会在有机会的时候尝试一下。事实上,考虑到我们的部分问题,我的答案是加上“身高:500px”。当然,根据他的CSS,它可能不适用,但我们还没有看到。我已经在问题中添加了这些信息,以澄清容器div的高度已经设置。我目前正在使用我所拥有的设置JSFIDLE,但肯定也在研究您的代码。也许是这样。承诺()就是我要找的。我现在正在做一件类似的事情,但我想我在设置新表的
top
值时出现了一个错误。顺便说一句,感谢您的示例。我也将您的示例放到了JSFIDLE中。我面临的问题是,我想为新表做预处理,但如果没有hide()和slideDown(),这似乎是不可能的,因为hide()和slideDown()似乎会结巴很多。@ovm:你想让表从顶部向下,而不是从底部向上?@ovm:我已经演示了如何做。我认为代码演示的各种技术应该可以帮助您达到您想要达到的目的。最好的,
$(markup).hide().prependTo('.overviewContainer').slideDown();  
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
  <meta charset="utf-8">
  <title>Example</title>
  <style>
    #parent {
      overflow: hidden;
      border: 1px solid black;
      position: relative;
    }
    #parent table {
      position: relative;
      border: 1px solid black;
      width: 100%;
    }
  </style>
</head>
<body>
  <input type="button" value="Back" data-direction="-1">
  <input type="button" value="Forward" data-direction="1">
  <div id="parent">
    <table>
      <tbody>
        <tr><td>Zero</td></tr>
        <tr><td>Zero</td></tr>
        <tr><td>Zero</td></tr>
        <tr><td>Zero</td></tr>
        <tr><td>Zero</td></tr>
        <tr><td>Zero</td></tr>
        <tr><td>Zero</td></tr>
        <tr><td>Zero</td></tr>
        <tr><td>Zero</td></tr>
      </tbody>
    </table>
  </div>
<script>
  (function() {
    "use strict";
    var tables, current, busy;

    tables = prepTables();
    current = 0;
    buttonSetup();
    busy = false;
    enableForIndex(current);

    function prepTables() {
      var zero, one, two;

      // Copy the zero table to create "one" and "two", with varying
      // numbers of rows
      zero = $("#parent table");
      one = zero.clone();
      two = zero.clone();
      one.find("td").html("One");
      one.find("tr").slice(1, 5).clone().appendTo(one.find("tbody"));
      two.find("td").html("Two");
      one.find("tr").slice(1, 3).remove();
      return [zero, one, two];
    }

    function buttonSetup() {
      $("input[type=button]").click(function() {
        var direction = +this.getAttribute("data-direction"),
            index;

        if (!busy) {
          index = current + direction;
          if (index >= 0 && index < tables.length) {
            $("input[type=button").prop("disabled", true);
            busy = true;
            swapTables(index, function() {
              busy = false;
              current = index;
              enableForIndex(current);
            });
          }
        }
      });
    }

    function enableForIndex(index) {
      $("input[data-direction=-1]").prop("disabled", index === 0);
      $("input[data-direction=1]").prop("disabled", index === tables.length - 1);
    }

    function swapTables(index, callback) {
      var parent, height,
          table, tableHeight,
          newTable, newTableHeight,
          bothTables,
          target,
          tableTop,
          newHeight;

      // Get the parent
      parent = $("#parent");

      // Get its height
      height = parent.height();
      parent.css({
        height: height,
        maxHeight: height,
        minHeight: height
      });

      // Get the current table and the desired table
      table = tables[current];
      newTable = tables[index];
      bothTables = table.add(newTable);

      // Remember the current table's top
      tableTop = table.position().top;

      // Insert the new table, change tops if necessary,
      // figure out where our animation should stop
      tableHeight = table.height();
      if (index < current) {
        newTable.insertBefore(table);
        newTableHeight = newTable.height();
        table.css("top", "-=" + newTableHeight);
        newTable.css("top", tableTop - newTableHeight);
        target = tableTop;
      } else {
        newTable.insertAfter(table);
        newTableHeight = newTable.height();
        target = tableTop - newTable.position().top;
      }

      // If the new table is a different size, animate that
      // at the same time, but make sure we finish first
      if (newTableHeight != tableHeight) {
        height += newTableHeight - tableHeight;
        parent.animate({
          height: height,
          maxHeight: height,
          minHeight: height
        }, 1000); // 200ms shorter than the below
      }

      // Animate both tables, get a single callback when the animation is complete
      // (using the `animate` callback, we'd get two -- one for each table -- so
      // we use the promise instead)
      bothTables.animate({
        top: target
      }, 1200).promise().then(function() {
        var newHeight;

        // Complete, detach the old one and put the new one in its normal position
        table.detach().css("top", "");
        newTable.css("top", tableTop);

        // Let the parent assume its natural height again; in
        // theory, this should be the new height we set for it
        // earlier if that needed to change
        parent.css({
          height: "",
          maxHeight: "",
          minHeight: ""
        });

        // Done
        callback();
      });
    }
  })();
</script>
</body>
</html>
var height, table, newTable, target;

// Get the height of the parent div
height = $("#parent").height();

// Get the table
table = $("#parent table");

// Add the new table (in my case I'll just clone that one)
newTable = table.clone();
newTable.find("td").text("Two");
newTable.appendTo("#parent");

// Figure out where we want to stop the animation of `top`
target = table.position().top - newTable.position().top;

// Animate both tables, get a single callback when the animation is complete
// (using the `animate` callback, we'd get two -- one for each table -- so
// we use the promise instead)
newTable.add(table).animate({
  top: target
}, 1200).promise().then(function() {
  // Complete, remove the old one and put the new one in its normal position
  table.remove();
  newTable.css("top", 0);
});
var parent, height, table, newTable, target;

// Get the parent
parent = $("#parent");

// Get its height
height = parent.height();
parent.css({
  height: height,
  maxHeight: height,
  minHeight: height
});

// Get the table
table = parent.find("table");

// Add the new table (in my case I'll just clone that one, and add
// more rows)
newTable = table.clone();
newTable.find("td").text("Two");
newTable.find("tr").slice(1, 5).clone().appendTo(newTable.find("tbody"));
newTable.appendTo(parent);

// Figure out where we want to stop the animation of `top`
target = table.position().top - newTable.position().top;

// Animate both tables, get a single callback when the animation is complete
// (using the `animate` callback, we'd get two -- one for each table -- so
// we use the promise instead)
newTable.add(table).animate({
  top: target
}, 1200).promise().then(function() {
  var newHeight;

  // Complete, remove the old one and put the new one in its normal position
  table.remove();
  newTable.css("top", 0);

  // Let the parent assume its natural height again; if the new table is a
  // different size, just clearing the heights we set would be abrupt, so
  // we animate again
  parent.css({
    height: "",
    maxHeight: "",
    minHeight: ""
  });
  newHeight = parent.height();
  if (newHeight !== height) {
    parent.css({
      height: height,
      maxHeight: height,
      minHeight: height
    }).animate({
      height: newHeight,
      maxHeight: newHeight,
      minHeight: newHeight
    }, function() {
      parent.css({
        height: "",
        maxHeight: "",
        minHeight: ""
      });
    });
  }
});