html模仿原生ios通讯录制作国家展示页(手机端)

来源:互联网 发布:php出生以来的时间戳 编辑:程序博客网 时间:2024/06/06 18:08

html内容






<div id="item-container">    <ul></ul></div><script src="sidebar.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>

sidebar.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 = optionsthis.initialize(options)

}

IndexSidebar.prototype.initialize = function (options) {

var chars = options.charsvar el =  document.createElement('div')el.className = 'index-sidebar-container'el.innerHTML = this.render(chars)document.body.appendChild(el)this.el = elthis.elChar = el.querySelector('.current-char')this.chars = charsif (options.isAdjust) {    this.adjust(options)}this.initEvents(options)

}

IndexSidebar.prototype.render = function (chars) {
return (
’ +

    ’ +
    [].map.call(chars, function (ch) {
    return ‘
  • ’ + ch + ‘

  • }).join(”) +

)
}

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.heightvar boxClientTop = boxRect.topvar charOffsetX = options.charOffsetXvar charOffsetY = options.charOffsetYvar touching = falsevar lastChar// touch eventsif ('ontouchstart' in document) {    el.addEventListener('touchstart', function (e) {        if (!touching) {            e.preventDefault()            var t = e.touches[0]            start(t.clientX, t.clientY)        }    }, false)    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 eventselse {    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.offsetBottomvar expectLineHeight = expectHeight / charCountvar expectFontSize = expectLineHeight * options.lineScalevar style = this.el.querySelector('ul').stylestyle.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

})

data.js存储国家名

var app = app || {}
app.data = [ …….];

sidebar .css

  • {margin: 0; padding: 0}
    body {
    font: 14px/1.7 arial, “Microsoft Yahei”, sans-serif;
    }

header {
position: relative;
padding: 0 20px;
font-size: 30px;
line-height: 60px;
color: #fff;
background: #2fc9da;
}

.link-github {
position: absolute;
top: 15px;
right: 20px;
padding: 5px 15px;
font-size: 14px;
line-height: 20px;
color: #333;
background: #fff;
border-radius: 15px;
}
.link-github svg {
margin-right: 5px;
vertical-align: middle;
}
.link-github:hover,
.link-github:active {
background: #eee;
}

item-container {

position: fixed;top: 60px;left: 0;right: 0;width: 100%;bottom: 0;overflow: auto;background: #f7f7f7;

}

item-container li {

padding: 10px 20px;border-bottom: 1px solid #ccc;

}

item-container li:last-child {

border-bottom: none;

}

.index-sidebar-container {
position: fixed;
top: 70px;
right: 0;
overflow: visible;
-webkit-user-select: none;
user-select: none;
cursor: default;
}
.index-sidebar-container ul {
padding: 0 5px;
list-style: none;
font-size: 13px;
line-height: 1.5;
color: #999;
}
.index-sidebar-container li {
text-align: center;
}
.index-sidebar-container .current-char {
display: none;
position: fixed;
top: 0;
left: 0;
margin-left: -80px;
margin-top: -20px;
height: 40px;
width: 40px;
line-height: 40px;
font-size: 32px;
text-align: center;
color: #999;
}这里写图片描述