JavaScript原生實現樓梯外掛

wdapp發表於2020-02-01

JavaScript原生實現樓梯外掛

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript原生實現樓梯外掛</title>
  <style>
  * {
    margin: 0;
    padding: 0;
  }

  .container {

  }

  .container .section {
    height: 300px;
  }

  .container .section:nth-last-child(2) {
    height: 1000px;
  }

  .container .aside {
    position: fixed;
    right: 25px;
    top: 100px;
  }

  .container .aside .list {
    list-style: none;
    border-radius: 4px;
    overflow: hidden;
  }

  .container .aside .list .item:first-child {

  }

  .container .aside .list .item {
    width: 40px;
    height: 40px;
    background-color: white;
    font-size: 12px;
    text-align: center;
    line-height: 40px;
    border-bottom: 1px #eeeeee solid;
    cursor: pointer;
    user-select: none;
  }

  .container .aside .list .item:last-child {
    border-bottom: none;
  }

  .container .aside .list .active {
    background-color: orange;
    color: white;
  }
  </style>
</head>
<body>
<div class="container">
  <div class="section" style="background-color: #0A98D5">pages 1</div>
  <div class="section" style="background-color: #ffa200">pages 2</div>
  <div class="section" style="background-color: #07c160">pages 3</div>
  <div class="section" style="background-color: #31b0d5">pages 4</div>
  <div class="section" style="background-color: #F76260">pages 5</div>
  <div class="section" style="background-color: #e80080">pages 6</div>
  <div class="section" style="background-color: #808080">last-page</div>
  <div class="aside"></div>
</div>
<script>
function Stairway(options) {
  if (typeof options !== "object") {
    return false;
  }
  this.target = options.target || ".container";
  this.aside = options.aside || [];
  this.init();
}

Stairway.prototype.init = function() {
  this.container = document.querySelector(this.target);
  if (!this.container) {
    return false;
  }
  this.sections = this.container.getElementsByClassName("section");
  if (this.sections && this.sections.length) {
    this.initAside();
  } else {
    return false;
  }
  this.asideNodes = this.container.getElementsByClassName("aside");
  if (this.asideNodes.length) {
    var asideList = this.crateAsideLists(this.aside);
    this.addAsides(this.asideNodes, asideList);
  }
};

Stairway.prototype.initAside = function() {
  if (this.aside.length) {
    this.addTopAndBottom(this.aside);
    return false;
  }
  for (var i = 0; i < this.sections.length; i++) {
    this.aside.push(i);
  }
  this.addTopAndBottom(this.aside);
};

Stairway.prototype.addTopAndBottom = function(aside) {
  if (!aside.length) {
    return aside;
  }
  aside.unshift("top");
  aside.push("bottom");
};

Stairway.prototype.crateAsideLists = function(aside) {
  var frag = document.createDocumentFragment();
  var list = document.createElement("ul");
  var attr = document.createAttribute("class");
  attr.value = "list";
  list.setAttributeNode(attr);
  frag.appendChild(list);
  aside.forEach(function(item, index) {
    var li = document.createElement("li");
    li.dataset.index = index;
    li.textContent = item;
    li.className = "item";
    if (index === 0) {
      li.className = "item active";
    }
    list.appendChild(li);
  });
  return frag;
};

Stairway.prototype.addAsides = function(nodes, list) {
  var parents = this.realArray(nodes);
  var _this = this;
  parents.forEach(function(parent, index) {
    var frag = list.cloneNode(true);
    var ls = frag.firstChild;
    parent.appendChild(frag);
    _this.eventEntrust(ls);
  });
};

Stairway.prototype.eventEntrust = function(ls) {
  var _this = this;
  ls.addEventListener("click", this.listener.bind(_this, ls), false);
};

Stairway.prototype.listener = function(ls, e) {
  var target = e.target;
  if (target && target.nodeType === 1 && target.tagName === "LI") {
    var children = this.realArray(ls.children);

    children.forEach(function(item, index) {
      item.className = "item";
    });
    var index = target.dataset.index;
    var currentTarget = ls.children.item(index);
    currentTarget.className = "item active";

    var count = this.aside.length;
    var scrollHeight = document.documentElement.scrollHeight;

    if (index == 0) {
      this.moveTo(0, 0);
      console.log("top");
    } else if (index == count - 1) {
      this.moveTo(0, scrollHeight);
      console.log("bottom");
    } else if (index == count - 2) {
      var offsetHeight = this.sections.item(this.sections.length - 1).offsetHeight;
      this.moveTo(0, scrollHeight - offsetHeight);
      console.log("last");
    } else {
      console.log("center");
      var offsetHeight = this.sections.item(index - 1).offsetHeight;
      this.moveTo(0, offsetHeight * (index - 1));
    }
  }
};

Stairway.prototype.moveTo = function(left, top) {
  window.scrollTo({
    top: top,
    left: left,
    behavior: "smooth"
  });
};

Stairway.prototype.realArray = function(nodes) {
  return Array.prototype.slice.call(nodes);
};

var stairway = new Stairway({
  target: ".container",
  aside: ["1", "2", "3", "4", "5", "6", "7"]
});

</script>
</body>
</html>
複製程式碼

相關文章