components.png
一.上拉刷新数据的原理
- 一个父盒子内部套一个可以scroll的子盒子
- 给子盒子设置touchstart事件,将子盒子
e.targetTouches[0].pageY
的值存到变量touchStart
中
- 给子盒子设置touchmove事件,根据手指滑动的距离去改变子盒子的
top
:scroll.style.top = scroll.offsetTop + touch.pageY-touchStart + 'px';
- 给子盒子设置touchend事件,获取子盒子
scrollTop
的值,如果大于一定的值,发送ajax请求获取新的数据, 创建DOM元素insertBefore
到子盒子中.
- 详细实现代码如下:
<style>
div{
position: absolute;
top:0px;
bottom:0px;
width:100%;
left:0px;
overflow: hidden;
}
li{
list-style-type: none;
height:35px;
background: #ccc;
border-bottom: solid 1px #fff;
text-align: left;
line-height: 35px;
padding-left:15px;
}
ul{
width:100%;
margin-top:0px;
position: absolute;
left:0px;
padding:0px;
top:0px;
}
</style>
<div class="outerScroller">
<ul class = 'scroll'>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>10</li>
</ul>
</div>
<script>
var scroll = document.querySelector('.scroll');
var outerScroller = document.querySelector('.outerScroller');
var touchStart = 0;
var touchDis = 0;
outerScroller.addEventListener('touchstart', function(event) {
var touch = event.targetTouches[0];
// 把元素放在手指所在的位置
touchStart = touch.pageY;
console.log(touchStart);
}, false);
outerScroller.addEventListener('touchmove', function(event) {
var touch = event.targetTouches[0];
console.log(touch.pageY + 'px');
//改变子盒子的top值
scroll.style.top = scroll.offsetTop + touch.pageY-touchStart + 'px';
console.log(scroll.style.top);
touchStart = touch.pageY;
touchDis = touch.pageY -touchStart;
}, false);
outerScroller.addEventListener('touchend', function(event) {
touchStart = 0;
var top = scroll.offsetTop;
console.log(top);
if(top>70)refresh();
if(top>0){
var time = setInterval(function(){
scroll.style.top = scroll.offsetTop -2+'px';
if(scroll.offsetTop<=0)clearInterval(time);
},1)
}
}, false);
function refresh(){
for(var i = 10;i>0;i--)
{
var node = document.createElement("li");
node.innerHTML = "我是被你刷出来的";
scroll.insertBefore(node,scroll.firstChild);
}
}
</script>
二.请说说实现分页的简单步骤
- 根据数据总量和每页显示的数量计算出页数
- 根据页数动态生成分页的按钮,将其页码保存在自定义标签中
- 给页码按钮的父盒子添加其代理事件, 获取自定义标签中的页码,根据页码计算出当前的起始数据发送ajax请求获取数据,动态渲染页面.
- 给左右箭头按钮的父盒子添加其代理事件,设置变量count,每次点击对count进行计算后得到页码发送ajax请求(同上一步),注意判断第一页和最后一页不能再点击的情况
- 具体的模拟实现如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>js分页</title>
<style type="text/css">
body { margin: 0; padding: 0; }
.pagination { color: #333; text-align: center; margin: 8px; }
.pagination span { color: #999; margin: 0 1px; padding: 3px 6px; border: 1px solid #ccc; }
.pagination span.on { background-color: #337ab7; color: #fff; font-weight: bold; border: 1px solid #333; }
.pagination a { color: #00f; text-decoration: none; }
.pagination a span { border: 1px solid #66c; color: #33f; }
#pager { margin: 20px; padding: 4px; }
#content { text-align: center; }
</style>
</head>
<body>
<div id="pager"></div>
<div id="content"></div>
<script>
var currentPage = 1; // 当前页码, 从1开始
var pageSize = 5; // 每页显示记录数
var maxButtons = 10; // 显示的分页按钮数量
var totalNumber = 30; // 记录总数
var totalPage = parseInt(Math.ceil(totalNumber / pageSize)); // 总页数
initPage();
function initPage() {
//循环生成数组
var arr = [];
for (var o = 0; o < totalNumber; o++) {
arr.push(o);
}
//每一页第一个li
var rangeStartitem = (currentPage - 1) * pageSize;
//开始页
var rangeStart = Math.max(1, currentPage - parseInt(maxButtons / 2));
//最后一页
var rangeEnd = Math.min(totalPage, rangeStart + maxButtons - 1);
var constr = pageCon(arr, rangeStartitem, pageSize);
var divcontent = document.getElementById("content");
divcontent.innerHTML = constr;
//创建分页模板
var str = "";
str += "<div class='pagination'>";
str += "当前第" + currentPage + "页"
//如果总页数大于1
if (totalPage > 1) {
//当前页不是第一页
if (currentPage != 1) {
str += '<a href="#!" data-num="1"><span>|<</span></a>';
str += '<a href="#!" data-num="' + (currentPage - 1) + '"><span><<</span></a>';
} else {
//如果是第一页,禁用上一页按钮
str += '<span>|<</span>';
str += '<span><<</span>';
}
//中间页码
for (var i = rangeStart; i <= rangeEnd; i++) {
//如果是当前页的话,就禁用当前页的按钮
if (i == currentPage) {
str += '<span class="on">' + i + "</span>";
} else {
//否则就可以点击该页
str += '<a href="#" data-num="' + i + '"><span>' + i + "</span></a>";
}
}
//当前页不是总页,即是最后一页
if (currentPage != totalPage) {
str += '<a href="#" data-num="' + (currentPage + 1) + '"><span>>></span></a>';
str += '<a href="#" data-num="' + totalPage + '"><span>>|</span></a>';
} else {
//如果是最后页,禁用下一页
str += '<span>>></span>';
str += '<span>>|</span>';
}
}
str += ' 一共' + totalPage + '页, ' + totalNumber + '条记录 </div>';
var divpager = document.getElementById("pager");
divpager.innerHTML = str;
//获取所有生成的页面链接
var listTag = divpager.getElementsByTagName('a');
//绑定li事件
for (var i = 0; i < listTag.length; i++) {
listTag[i].onclick = function() {
var currentPage = this.getAttribute('data-num');
nowcurrentPage(currentPage);
return false;
};
}
}
//传递页面
function nowcurrentPage(currentPage) {
this.currentPage = currentPage;
initPage();
}
//生成每页的数据
function pageCon(arr, rangeStartitem, len) {
var constr = '';
for (var i = rangeStartitem; i < rangeStartitem + len; i++) {
constr += "<li>"+ arr[i] + "</li>";
}
return constr;
}
</script>
</body>
</html>
三.轮播图的实现思路
- 一个父盒子用做container
- 在container下有个
ul
, 其宽度为其所以li
的总宽度
- 将
ul
设置overflow:hidden
属性,让其只显示当前的li
- 通过
setInterval
改变其ul
的left
的值,实现自动轮播
- 给左右箭头和小点添加点击事件
- 具体代码实现如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
padding: 0;
margin: 0;
list-style: none;
border: 0;
}
.all {
width: 500px;
height: 200px;
padding: 7px;
border: 1px solid #ccc;
margin: 100px auto;
position: relative;
}
.screen {
width: 500px;
height: 200px;
/*overflow: hidden;*/
position: relative;
}
.screen li {
width: 500px;
height: 200px;
overflow: hidden;
float: left;
}
.screen ul {
position: absolute;
left: 0;
top: 0px;
width: 3000px;
}
.all ol {
position: absolute;
right: 10px;
bottom: 10px;
line-height: 20px;
text-align: center;
}
.all ol li {
float: left;
width: 20px;
height: 20px;
background: #fff;
border: 1px solid #ccc;
margin-left: 10px;
cursor: pointer;
}
.all ol li.current {
background: yellow;
}
#arr {
display: none;
}
#arr span {
width: 40px;
height: 40px;
position: absolute;
left: 5px;
top: 50%;
margin-top: -20px;
background: #000;
cursor: pointer;
line-height: 40px;
text-align: center;
font-weight: bold;
font-family: '黑体';
font-size: 30px;
color: #fff;
opacity: 0.3;
border: 1px solid #fff;
}
#arr #right {
right: 5px;
left: auto;
}
</style>
</head>
<body>
<div class="all" id='box'>
<div class="screen">
<ul>
<li>![](images/1.jpg)</li>
<li>![](images/2.jpg)</li>
<li>![](images/3.jpg)</li>
<li>![](images/4.jpg)</li>
<li>![](images/5.jpg)</li>
</ul>
<ol>
<!-- 动态创建的小方块,添加在这里,样式已经给写好了-->
</ol>
</div>
<div id="arr"><span id="left"><</span><span id="right">></span></div>
</div>
<script>
//1 获取元素
var box = document.getElementById("box");
var screenBox = box.children[0];//可视区域
var imgWid = screenBox.offsetWidth;//图片宽度
var ul = screenBox.children[0];//运动的ul
var lisUl = ul.children;//所有的图片
var ol = screenBox.children[1];//小方块的父盒子
var lisOl = ol.children;//上来取值是没有内容的,动态添加后,由于是动态数组,后期可以直接操作
var arrBox = box.children[1];
var arrLeft = arrBox.children[0];
var arrRight = arrBox.children[1];
//添加一个pic用来count图片的数量
var pic = 0;
//动态添加盒子
for (var i = 0; i < lisUl.length; i++) {
var li = document.createElement("li");
li.innerText = i + 1;
ol.appendChild(li);
}
//给第一个盒子增加效果
lisOl[0].className = "current";
//给盒子增加简单的点击切换效果
//遍历所有的lisOl,为其添加事件
for (var i = 0; i < lisOl.length; i++) {
//设置一个索引值
lisOl[i].index = i;
//每个添加事件
lisOl[i].onclick = function () {
//更改对应的属性
for (var i = 0; i < lisOl.length; i++) {
lisOl[i].className = "";
}
this.className = "current";
pic = this.index;
//移动图片
animate(ul, -this.index * imgWid);
}
}
//克隆第一张图片,放入到ul的最后位置
ul.appendChild(lisUl[0].cloneNode(true));
//给两端的箭头添加点击事件
//给右边的箭头添加事件
arrRight.onclick = function () {
if(pic == lisUl.length - 1){
ul.style.left = 0 + "px";
pic = 0;
}
pic++;
//点击按钮的时候,对相应ol中的li进行变色
//首先清除对应的className
for (var i = 0; i < lisOl.length; i++) {
lisOl[i].className = "";
}
//接下来对当前的ol中的li添加属性
//进行条件判断
if(pic == lisUl.length - 1){
pic = 0;
}
lisOl[pic].className = "current";
//点击的时候,移动位置
animate(ul, -pic * imgWid);
};
//给左边的箭头添加事件
arrLeft.onclick = function () {
if(pic == 0){
ul.style.left = -(lisUl.length - 1)*imgWid + "px";
pic = -(lisUl.length - 1);
}
pic--;
//点击的时候,移动位置
animate(ul, -pic * imgWid);
};
var timer = null;
//放在最后
//给screenoBox添加移入移出时间,一旦移入,我们就需要show出两端箭头
box.onmouseover = function () {
arrBox.style.display = "block";
clearInterval(timer);
}
box.onmouseout = function () {
arrBox.style.display = "none";
timer = setInterval(function () {
arrRight.click();
},2000)
}
function animate(tag, target) {
clearInterval(tag.timer);//防止加速
tag.timer = setInterval(function () {
//1 标签当前位置的获取
var leader = tag.offsetLeft;
//2 设置运动的步长
var step = 15;
step = leader > target ? -step : step;
if (Math.abs(leader - target) > Math.abs(step)) {//设置运动的目标位置
//3 套用运动公式: 当前位置(新) = 当前位置(旧) + 步长
leader = leader + step;
//4 设置给标签的left
tag.style.left = leader + "px";
} else {
tag.style.left = target + "px";
clearInterval(tag.timer);//运动结束,清除定时器
}
}, 20);
}
</script>
</body>
</html>
网友评论