前端Web前端之路饥人谷技术博客

整理前端面试题(十四): 常用组件的实现思想

2017-09-08  本文已影响351人  熠辉web3
components.png

一.上拉刷新数据的原理

<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>

二.请说说实现分页的简单步骤

<!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>

三.轮播图的实现思路

<!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>

上一篇 下一篇

猜你喜欢

热点阅读