这是我在网上找来一个 demo 但是我不知道如何吧 data.js 里面的数据换成我自己本地的列表数据
js脚本文件
(function (factory) {
if (typeof module === 'object' && module.export) {
module.export = factory()
} else if (typeof define === 'function' && (define.amd || define.cmd)) {
define([], factory)
} else if (typeof window !== 'undefined') {
window.IndexSidebar = factory()
}
})
//构造字母导航组件
(function () {
var defaultOptions = {
chars: '*ABCDEFGHIJKLMNOPQRSTUVWXYZ#',
isAdjust: true, //是否是自动调整高度
offsetTop: 70,
offsetBottom: 10,
lineScale: 0.7,
charOffsetX: 80,
charOffsetY: 20
}
function IndexSidebar(options) {
options = options || {}
//遍历缺省选项逐一处理
for (var k in defaultOptions) {
if (defaultOptions.hasOwnProperty(k)) {
//未给出选项值时使用缺省选项值
options[k] = options[k] || defaultOptions[k]
}
}
this.options = options
this.initialize(options)
}
//特定事件触发时,调用传入的回调函数并传入事件数据
IndexSidebar.prototype.initialize = function (options) {
//实现事件监听
var chars = options.chars
var el = document.createElement('div')
el.className = 'index-sidebar-container'
el.innerHTML = this.render(chars)
document.body.appendChild(el)
this.el = el
this.elChar = el.querySelector('.current-char')
this.chars = chars
if (options.isAdjust) {
this.adjust(options)
}
this.initEvents(options)
}
IndexSidebar.prototype.render = function (chars) {
return (
'<span class="current-char"></span>' +
'<ul>' +
[].map.call(chars, function (ch) {
return '<li>' + ch + '</li>'
}).join('') +
'</ul>'
)
}
//实现手指拖动更新索引字母
IndexSidebar.prototype.initEvents = function (options) {
var view = this
var el = this.el
var elChar = this.elChar
var chars = this.chars
var boxRect = el.getBoundingClientRect()
var boxHeight = boxRect.height
var boxClientTop = boxRect.top
var charOffsetX = options.charOffsetX
var charOffsetY = options.charOffsetY
var touching = false
var lastChar
// touch events
if ('ontouchstart' in document) {
el.addEventListener('touchstart', function (e) {
if (!touching) {
e.preventDefault()
var t = e.touches[0]
start(t.clientX, t.clientY)
}
}, false)
//拖动过程中手指可能会移出导航栏,所以输在document 上监听
document.addEventListener('touchmove', function handler(e) {
if (touching) {
e.preventDefault()
var t = e.touches[0]
move(t.clientX, t.clientY)
}
}, false)
document.addEventListener('touchend', function (e) {
if (touching) {
e.preventDefault()
end()
}
}, false)
}
// mouse events
else {
el.addEventListener('mousedown', function (e) {
if (!touching) {
e.preventDefault()
start(e.clientX, e.clientY)
}
})
document.addEventListener('mousemove', function (e) {
if (touching) {
e.preventDefault()
move(e.clientX, e.clientY)
}
})
document.addEventListener('mouseup', function (e) {
if (touching) {
e.preventDefault()
end()
}
})
}
//实现实现索引字符更新
function start(clientX, clientY) {
touching = true
elChar.style.display = 'block'
move(clientX, clientY)
}
function move(clientX, clientY) {
var offset = calcRelativePosition(clientY)
var percent = offset / boxHeight
var ch = getPositionChar(percent)
updateChar(clientX, clientY, ch)
}
function end() {
touching = false
elChar.style.display = 'none'
}
function updateChar(clientX, clientY, ch) {
var x = Math.max(clientX, charOffsetX)
var yMin = boxClientTop
var yMax = window.innerHeight - charOffsetY
var y = Math.min(Math.max(clientY, yMin), yMax)
elChar.textContent = ch
elChar.style.left = x + 'px'
elChar.style.top = y + 'px'
if (ch && lastChar !== ch) {
lastChar = ch
view.trigger('charChange', ch)
}
}
//计算出手指位置在组件的相对高度
function calcRelativePosition(clientY) {
var y = clientY - boxClientTop
if (y < 0) {
y = 0
} else if (y > boxHeight) {
y = boxHeight
}
return y
}
// yPercent {Number} in range of [0, 1]
function getPositionChar(yPercent) {
var min = 1
var max = chars.length
var index = Math.ceil(yPercent * max)
if (index < min) {
index = min
} else if (index > max) {
index = max
}
return chars[index - 1]
}
}
IndexSidebar.prototype.adjust = function (options) {
var charCount = options.chars.length
var expectHeight = window.innerHeight - options.offsetTop - options.offsetBottom
var expectLineHeight = expectHeight / charCount
var expectFontSize = expectLineHeight * options.lineScale
var style = this.el.querySelector('ul').style
style.lineHeight = expectLineHeight + 'px'
style.fontSize = expectFontSize + 'px'
}
/* Event Emitter API */
//触发特定事件,并给出事件数据供监听的回调函数使用
IndexSidebar.prototype.trigger = function (event, data) {
var listeners = this._listeners && this._listeners[event]
if (listeners) {
listeners.forEach(function (listener) {
listener(data)
})
}
}
//特定事件触发时,调用传入的回调函数并传入事件数据
IndexSidebar.prototype.on = function (event, callback) {
this._listeners = this._listeners || {}
var listeners = this._listeners[event] || (this._listeners[event] = [])
listeners.push(callback)
}
// 解除事件监听
IndexSidebar.prototype.off = function (event, callback) {
var listeners = this._listeners && this._listeners[event]
if (listeners) {
var i = listeners.indexOf(callback)
if (i > -1) {
listeners.splice(i, 1)
if (listeners.length === 0) {
this._listeners[event] = null
}
}
}
}
return IndexSidebar
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index Sidebar - luobotang</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<!-- <header>Index Sidebar <a class="link-github" href="https://github.com/luobotang/index-sidebar"><svg aria-hidden="true" class="octicon octicon-mark-github" height="14" version="1.1" viewBox="0 0 16 16" width="14"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>github</a></header> -->
<div id="item-container">
<ul></ul>
</div>
<script src="index.js"></script>
<script src="data.js"></script>
<script>
var app = app || {}
app.ItemList = function (data) {
var list = []
var map = {}
var html
html = data.map(function (item) {
var i = item.lastIndexOf(' ')
var en = item.slice(0, i)
var cn = item.slice(i + 1)
var ch = en[0]
if (map[ch]) {
return '<li>' + en + '<br>' + cn + '</li>'
} else {
map[ch] = true
return '<li data-ch="' + ch + '">' + en + '<br>' + cn + '</li>'
}
}).join('')
var elItemList = document.querySelector('#item-container ul')
elItemList.innerHTML = html
return {
gotoChar: function (ch) {
if (ch === '*') {
elItemList.scrollTop = 0
} else if (ch === '#') {
elItemList.scrollTop = elItemList.scrollHeight
} else {
var target = elItemList.querySelector('[data-ch="' + ch + '"]')
if (target) {
target.scrollIntoView()
}
}
}
}
}
app.main = function () {
var itemList = app.ItemList(app.data)
new IndexSidebar().on('charChange', itemList.gotoChar)
}
app.main()
</script>
</body>
</html>