Динамически добавлять и удалять div при прокрутке?

Я попытался добавить и удалить теги div при прокрутке, как работает сетка Dojo. Я хочу отображать только 7 тегов div.

при прокрутке влево внутри контейнера, когда первый тег div (с левой стороны) был скрыт с веб-страницы, затем этот скрытый div удаляется из контейнера, а новый прикрепляется к правой стороне.

тот же процесс должен применяться при прокрутке вправо.

Это похоже на . Но вместо прокрутки <tr> тег, я хочу прокрутить <div> ' s.

это то, что я пробовал раньше:https://jsfiddle.net/9y2ptsbg/3/ Как я могу это сделать? Если есть какой-либо плагин (например, Dojo), это также полезно.

4 ответов


возможно, эта скрипка js поможет ?
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);

Да, это возможно. Прежде всего, вам понадобится что-то вроде этого, как структуру:

<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 на другую сторону списка возникает побочный эффект перемещения всех элементов. Это приведет к странному / багги поведению, если вы не вернете прокрутку позиция.

вы можете сделать это путем регулировки на .scroll элемент.

все вместе вы могли бы придумать что-то вроде этого: http://jsfiddle.net/c3u6bfmf/


попробовать

$(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>

на самом деле в приведенном примере вы прокручиваете divs. Каждый div содержит таблицу, но это не имеет значения.

Я бы сказал, что вам нужен один контент div, и играть с его полями в javascript в соответствии с текущей позицией прокрутки. Просто убедитесь, что общая ширина остается прежней.

это гарантирует, что стандартная полоса прокрутки отображается правильно и не "прыгает", в то время как содержимое можно настроить на его позиция.

в приведенном вами примере, кстати, они используют 3 divS с частичным содержанием - только div или divs на дисплее имеют контент и, возможно, частичный контент (только некоторый контент внизу или вверху, достаточный для заполнения отображаемой области).

в любом случае, ключ здесь-поддерживать прокручиваемый элемент достаточно большим, чтобы полоса прокрутки поддерживала его размер и положение, или использовать пользовательскую полосу прокрутки, полностью написанную на javascript.