<!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>
複製程式碼