html模仿原生ios通讯录制作国家展示页(手机端)
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 htmlhtml = 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] = truereturn '<li data-ch="' + ch + '">' + en + '<br>' + cn + '</li>'}}).join('')var elItemList = document.querySelector('#item-container ul')elItemList.innerHTML = htmlreturn {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 = 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 (
‘’ +
‘
- ’ +
[].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.height
var boxClientTop = boxRect.topvar charOffsetX = options.charOffsetX
var charOffsetY = options.charOffsetYvar 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.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 = trueelChar.style.display = 'block'move(clientX, clientY)
}function move(clientX, clientY) {var offset = calcRelativePosition(clientY)var percent = offset / boxHeightvar ch = getPositionChar(percent)updateChar(clientX, clientY, ch)
}function end() {touching = falseelChar.style.display = 'none'
}function updateChar(clientX, clientY, ch) {var x = Math.max(clientX, charOffsetX)var yMin = boxClientTopvar yMax = window.innerHeight - charOffsetYvar y = Math.min(Math.max(clientY, yMin), yMax)elChar.textContent = chelChar.style.left = x + 'px'elChar.style.top = y + 'px'if (ch && lastChar !== ch) {lastChar = chview.trigger('charChange', ch)}
}function calcRelativePosition(clientY) {var y = clientY - boxClientTopif (y < 0) {y = 0} else if (y > boxHeight) {y = boxHeight}return y
}// yPercent {Number} in range of [0, 1]
function getPositionChar(yPercent) {var min = 1var max = chars.lengthvar 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.lineScalevar 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
})
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;
}
html模仿原生ios通讯录制作国家展示页(手机端)相关推荐
- HTML制作个人简历——适配手机端和PC端
在学习完HTML后,参考他人项目制作了个人简历. 先放链接:https://xiaoxinnolabi.gitee.io/myresume/ 码云:https://gitee.com/Xiaoxinn ...
- mac下为iOS app制作gif展示动画图
简介 一般来说我们做一个demo,希望能够把效果展示给别人看,但是静态的截图并不能展示一些动画效果,所以一般来说制作成gif动图会利于展示,本文就讲述制作gif的全过程.这个过程中我们需要用到两个软件 ...
- flutter引入高德地图_Flutter笔记-调用原生IOS高德地图sdk
一.前言 2017年底因公司业务组合部门调整,新的团队部分维护的项目用React Native技术混合开发.为适应环境变化,开启疯狂RN学习之旅,晚上回来啃资料看视频.可能由于本身对RN技术体验不感冒 ...
- 将 75000 行原生 iOS 应用程序移植到 Flutter 后,结果太惊讶!
[CSDN编者按]很少有文章,介绍如何将大型应用,移植到Flutter.而本文的作者--一位来自澳洲的Native iOS & Flutter的开发者,尝试这样做了,结果让他十分惊讶.到底是什 ...
- Flutter和原生iOS调用相册
文章链接:https://juejin.cn/post/6908232699673722888 目的: 实现一个flutter调用原生ios相册的功能,并传递照片 flutter的操作 flutter ...
- css+html 3D变形制作视频展示区
3D 转换 CSS3 允许您使用 3D 转换来对元素进行格式化. 在本章中,您将学到其中的一些 3D 转换方法: rotateX() rotateY() 转换属性: 下表列出了所有的转换属性: 属性 ...
- html5 实现ios原生控件,vue.js实现仿原生ios时间选择组件开发经验
前言 最近几个月一直在看VUE,然后试着只用原生js+vue实现某些组件. PC端时间选择组件 这是最开始实现的pc上的时间选择,平时移动端也在做,所以就想实现一下移动端的时间选择器,下面分享一下我实 ...
- rn项目 假如cocoapods_React Native 如何集成到原生IOS项目中?
想了很久,要先介绍各种组件的实际应用好,还是先介绍怎么把React Native集成到原生项目好. 因为想起,一旦开始写各种组件的应用,就会花很长很长的篇幅,会把这个挺重要的内容抛到好远,而集成到原生 ...
- iOS 通讯录备份、恢复
和相册 备份一样,公司产品备份功能有通讯录备份 功能,自然也有通讯录恢复了.iOS通讯录相关操作,iOS对通讯录的操作离不开的框架: #import <AddressBook/A ...
最新文章
- R语言基础知识详解及概括
- o oia ospf 路由优先_OSPF基本配置及OSPF特殊区域配置
- python-匿名函数lambda
- C++复习 第一部分c到c++的过度
- js怎么实现对html代码加密解密,javascript脚本加密解密及HTML转JS
- sqlalchemy mysql_使用SQLAlchemy操作MySQL
- 【C语言及程序设计】项目1-24-4:个人所得税计算器if语句版
- innobackupex参数之 --throttle 限速这个值设置多少合理 原创
- php pg connect 扩展,php安装gnupg扩展
- stooge sort
- Prism初研究之依赖管理
- weblogic设置classpath、debug端口和log目录
- 【webservice】Axis2 客户端调用 设置超时时间
- 公差带与配合 配合选择基础
- ubantu 终端屏幕查找字符串
- vmware win7 iso 镜像文件下载
- 【2020总结】脚踏实地,仰望星空
- 发现了吗?西部世界III在Broadway上的广告
- LVGL8学习之Background Styles
- access数据库的用户名和密码的问题
热门文章
- java3d点线面_3D游戏与计算机图形学中的数学方法-点线面
- java 差的绝对值_Java判断绝对值的方法总结
- 水晶报表Crystal Reports XI服务器版
- QrCodeUtil--二维码工具类
- 字节跳动(抖音)收购VR眼镜厂商Pico的划时代意义
- 2020华数杯全国大学生数学建模竞赛C题-脱贫帮扶绩效评价体系的构建与探究(二)(附MATLAB和Python代码)
- win10常用电脑快捷操作;gif工具推荐
- html 获取登录状态,登录后如何获取HTML代码?
- HTML中上传与读取图片或文件(input file)----在路上(25)
- IDEATerminate vs Disconnect