滚动时动态添加和删除div?

时间:2015-04-01 10:43:57

标签: javascript jquery html css dojo

我试图像Dojo网格一样滚动时添加和删除div标签。我只想显示7个div标签。

当在容器内向左滚动时,当第一个div标签(在左侧)从网页中隐藏时,那个隐藏的div将从容器中移除,并且新的一个附加到右侧。

向右滚动时应该应用相同的过程。

它类似于this example。但是我不想滚动<tr>标记,而是想滚动浏览<div>

这是我之前尝试过的:https://jsfiddle.net/9y2ptsbg/3/我该怎么做?如果有任何插件(如Dojo),它也会有帮助。

4 个答案:

答案 0 :(得分:0)

尝试

$(function() {
          
  // adjust `colors` length to multiples of 7
  var colors = [
    "rgba(143, 146, 199, 0.49)",
    "rgba(199, 143, 186, 0.49)",
    "rgba(149, 199, 143, 0.49)",
    "rgba(229, 86, 61, 0.49)",
    "rgba(212, 229, 61, 0.49)",
    "rgba(206, 61, 229, 0.49)",
    "rgba(229, 157, 61, 0.49)",
    "rgba(61, 165, 229, 0.49)",
    "rgba(61, 229, 133, 0.49)",
    "rgba(229, 61, 61, 0.49)",
    "rgba(116, 61, 229, 0.49",
    "rgba(218, 229, 61, 0.49)",
    "rgba(21, 43, 157, 0.49)",
    "rgba(153, 157, 21, 0.49)",
    "rgba(199, 143, 186, 0.49)",
    "rgba(149, 199, 143, 0.49)",
    "rgba(229, 86, 61, 0.49)",
    "rgba(212, 229, 61, 0.49)",
    "rgba(206, 61, 229, 0.49)",
    "rgba(229, 157, 61, 0.49)",
    "rgba(61, 165, 229, 0.49)",
    "rgba(61, 229, 133, 0.49)",
    "rgba(229, 61, 61, 0.49)",
    "rgba(116, 61, 229, 0.49",
    "rgba(218, 229, 61, 0.49)",
    "rgba(21, 43, 157, 0.49)",
    "rgba(153, 157, 21, 0.49)",
    "rgba(199, 143, 186, 0.49)"
    // "rgba(149, 199, 143, 0.49)"
  ];
  
  var container = $("<div/>", {
    "id":"container",
    "title":"click to pause , resume `scroller`"
  });
  
  var n = 7;

  var scrolled = false;

  var elems = $.map(colors, function(color, i) {
    return $("<div>", {
      "class": "blocks-" + (i + 1),
      "text": i + 1,
      "css": {
        "backgroundColor": color,
        "left": (i * 25) + "%"
      }
    })[0].outerHTML
  });
  
  var scroller = function scroller(e) {

    var xz = container.scrollLeft();
    
    var wx = container.width() * .73;
    
    var keys = $.map($("div:first, div:last", container), function(el) {
      return Number(el.className.replace(/[^\d+]/g, ""));
    });
    
    var first = keys[0];
    
    var last = keys[1];
    
    var _scroller = function _scroller(elem, idx) {

      if (idx === 1 && scrolled) {
        scrolled = false;
        elem.scroll()
        return
      };
      
      elem
      .stop(true, true)
      .off("scroll")
      .empty()
      .append(
        elems
        .slice(idx ? (idx - 1) - n : last
               , idx ? idx - 1 : last + n)
        .map(function(el, i) {
           return $(el).css("left", (i * 25) + "%")[0].outerHTML
        }).join("")
      )
      .delay(250)
      .animate({
          scrollLeft: (idx ? "+=" : "-=") + elem.width() / 3
        }, 1000, function() {
            scrolled = true;
            elem.on("scroll", scroller).scroll()
      })      
    };
        
    if (xz < n && first !== 1 ) {
      _scroller(container, first)
    };
    
    if (xz > wx && last !== colors.length) {              
       _scroller(container);   
    };
    


  };

  $("body")
  .append(
    container.data("scroll", true).html(elems.slice(0, n))
    .on("scroll", scroller)
  );
  
  container.on("click", function() {
     if (container.data("scroll")) {
       container.data("scroll", false).off("scroll")
     } else {
       container.data("scroll", true)
       .on("scroll", scroller).scroll()
     }
  })

});
[class^=blocks] {
  padding: 0px;
  width: 25%;
  position: absolute;
  height: 150%;
  text-align: center;
  font-size: 100px;
}
#container {
  width: 100%;
  height: 250px;
  position: relative;
  overflow: auto;
  margin-top: 50%;
  background: #2a2a2a;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

答案 1 :(得分:0)

是的,这是可能的。首先,你需要这样的结构:

<div class="scroll">
    <div class="container">
        <div class="element element-1">1</div>
        <div class="element element-2">2</div>
        <div class="element element-3">3</div>
        <div class="element element-4">4</div>
        <div class="element element-5">5</div>
        <div class="element element-6">6</div>
    </div>
</div>

.scroll元素将是您的滚动容器,它的宽度或高度都有限(取决于您想要滚动的方式)并且有一个overflow

另一只手上的.container采用尽可能宽的宽度,因此对于6个元素,它将是element width * 6

最后,因为您要创建左/右滚动动画,您可能希望将float: left设置为所有.element个节点。

JavaScript代码也不难。您想要向onScroll元素添加.scroll事件处理程序,您可以这样做:

query(".scroll").on("scroll", function(evt) {

});

然后你要检测你是否向左或向右滚动。您可以通过将滚动偏移与前一个滚动偏移进行比较来实现,例如:

if (lastPos && lastPos - evt.target.scrollLeft > 0) {
    // Scrolling to the left
} else if (lastPos && lastPos - evt.target.scrollLeft < 0) {
    // Scrolling to the right
}
lastPos = evt.target.scrollLeft;

现在,在if内,您希望遍历所有.element,检测是否在可见部分的左侧或右侧,以及是否在其中一个那些边,你把它移到另一边(取决于滚动方向)。

要检查该元素是否位于.scroll的左侧或右侧,我正在使用Element.getBoundingClientRect()

var isLeftOfContainer = function(element) {
    var bounds = element.getBoundingClientRect();
    return (-bounds.left + element.parentNode.offsetLeft) >= bounds.width;
};

var isRightOfContainer = function(element) {
    var bounds = element.getBoundingClientRect();
    var box = element.parentNode.parentNode.getBoundingClientRect();
    return bounds.left - element.parentNode.offsetLeft > box.width;
};

要将节点移动到另一侧,我正在使用dojo/dom-construct::place()。您可以添加"first""last"作为第三个参数,具体取决于您滚动的方向,例如:

domConstruct.place(elem, elem.parentNode, "first");

这会将元素(elem)移动到父节点的第一个位置。当我们向左滚动时,我们想要做的是什么。

要遍历所有可以使用dojo/query的元素,例如:

query(".element").forEach(function(element) {

});

请记住,当你向左滚动时,你想要从最后一个元素到第一个元素循环遍历数组,这样如果同时隐藏了2个元素,那么第6个元素将被添加为第一个元素在添加第5个元素作为第一个元素之前。这可确保您始终以正确的顺序添加元素。

然后最后你必须调整.scroll元素的滚动位置。如果将DOM节点移动到列表的另一侧,则会产生副作用,即所有元素都将移动。如果您不向后移动滚动位置,这将导致奇怪/错误的行为。

您可以通过调整scrollLeft元素的.scroll属性来实现此目的。

一切结合在一起你可以得到类似这样的东西:http://jsfiddle.net/c3u6bfmf/

答案 2 :(得分:0)

也许这个小提琴会有帮助吗? https://jsfiddle.net/9y2ptsbg/12/

var container = $("#container"),
info = $("#info");

var j = 0;
var colors = ['rgba(143, 146, 199, 0.49)', 'rgba(199, 143, 186, 0.49)', 'rgba(149, 199, 143, 0.49)', 'rgba(229, 86, 61, 0.49)', 'rgba(212, 229, 61, 0.49)', 'rgba(206, 61, 229, 0.49)', 'rgba(229, 157, 61, 0.49)', 'rgba(61, 165, 229, 0.49)', 'rgba(61, 229, 133, 0.49)', 'rgba(229, 61, 61, 0.49)', 'rgba(116, 61, 229, 0.49', 'rgba(218, 229, 61, 0.49)', 'rgba(21, 43, 157, 0.49)', 'rgba(153, 157, 21, 0.49)', 'rgba(199, 143, 186, 0.49)', 'rgba(149, 199, 143, 0.49)', 'rgba(229, 86, 61, 0.49)', 'rgba(212, 229, 61, 0.49)', 'rgba(206, 61, 229, 0.49)', 'rgba(229, 157, 61, 0.49)', 'rgba(61, 165, 229, 0.49)', 'rgba(61, 229, 133, 0.49)', 'rgba(229, 61, 61, 0.49)', 'rgba(116, 61, 229, 0.49', 'rgba(218, 229, 61, 0.49)', 'rgba(21, 43, 157, 0.49)', 'rgba(153, 157, 21, 0.49)', 'rgba(199, 143, 186, 0.49)', 'rgba(149, 199, 143, 0.49)']

var ary = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36'],
cursor = 0,
attachDiv = function (_curr) {
container.empty();
var j = 0;

for (var i = _curr; i < _curr + 8; i++) {

    container.append('<div  class = "blocks blocks' + i + '" style="left:' +   (j * 25) + '%; background:' + colors[i] + ';">' + ary[i] + '</div>');
    j++;
}
};
var hasScrolled = false,
locked = false,
ticker = function () {
    if (hasScrolled && !locked) {
        locked = true;
        var xz = container.scrollLeft(),
            maxScrollLeft = container.get(0).scrollWidth - container.get(0).clientWidth,
            middle = maxScrollLeft / 2;
        if (xz == 0) {
            cursor = Math.max(0, cursor - 4);
        } else if (xz == maxScrollLeft) {
            cursor = Math.min(cursor + 4, ary.length - 8)
        }
        attachDiv(cursor);
        container.scrollLeft(middle);
        info.text(cursor);
        locked = false;
    }
    hasScrolled = false;
}
setInterval(ticker, 250);
    container.on('scroll', function () {
    hasScrolled = true;
});

attachDiv(0);

答案 3 :(得分:0)

实际上,在您给出的示例中,您正在浏览div。每个div都包含一个表格,但这不是重点。

我会说你需要一个内容div,并根据当前滚动位置在javascript中使用它的边距。只需确保总宽度保持不变。

这样可以确保标准滚动条正确显示并且不会“跳转”,而内容可以调整到其位置。

在您提供的示例中,BTW使用3 div个部分内容 - 只有展示中的divdiv有内容,可能还有部分内容(仅限部分内容)底部或顶部的内容,足以填满显示的区域。)

无论如何,这里的关键是保持一个足够大的可滚动元素,使滚动条保持其大小和位置,或者使用完全用javascript编写的自定义滚动条。