5、瀑布流、九宫格之位置交换(普通模式和发布订阅/观察者模式)、跑马灯效果、卷轴展开效果、“几”字形选项卡、胶卷式放映、放大镜、锚点

一、瀑布流
所谓瀑布流图片,就是随着鼠标往下拉,图片无穷无尽,但又不是死循环。因为这次拉到底后,后面的才显示出来。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        *{
            margin:0;
            padding:0;
            list-style: none;
            font-size: 50px;
            color: white;
        }
        div{
             1050px;
            margin:0 auto;
        }
        div ul{
             200px;
            float: left;
            margin: 0 5px;
        }
        div ul li{
             100%;
            background: url("http://www.qdfuns.com/misc.php?mod=attach&genre=editor&aid=5c2ddf7c938c5a6ae54f0b1ab390b9fe") no-repeat center #e1e1e1;
            margin-bottom: 10px;
        }
        div ul li img{
            display: block;
             100%;
        }
    </style>
</head>
<body>
<div>
    <ul><!--<li><img realImg="1.jpg" alt=""/></li>--></ul>
    <ul></ul>
    <ul></ul>
    <ul></ul>
    <ul></ul>
</div>
<script>
    var oDiv=document.getElementsByTagName('div')[0];
    var aUl=oDiv.getElementsByTagName('ul');
    var aLi=oDiv.getElementsByTagName('li');
    var aImg=oDiv.getElementsByTagName('img');
    //此处是自己造的假数据
    var data=[
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517838828_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517841171_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517843343_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517845828_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517848093_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517850750_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517853171_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517855671_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517857750_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517860171_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12227263_12227263_1441518058703_mthumb.jpg"},
        {"src":"http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12227263_12227263_1441518060703_mthumb.jpg"}
    ];
    function rnd(n,m){
        return Math.round(Math.random()*(m-n)+n);
    }
    function makeArray(arg){
        var ary=[];
        if('getComputedStyle' in window){
            ary=Array.prototype.slice.call(arg);
        }else{
            for(var i=0; i<arg.length; i++){
                ary.push(arg[i])
            }
        }
        return ary;
    }
    function win(attr){
        return document.documentElement[attr]||document.body[attr];
    }
    //1.动态创建1个li,li的宽度不管,高度随机,内容是img;
    function createLi(){
        var oLi=document.createElement('li');
        oLi.style.height=rnd(100,300)+'px';
        oLi.innerHTML='<img realImg="'+data[rnd(0,9)].src+'" alt=""/>';
        return oLi;
    }
    //2.创建50个li,每次都插入最短的ul
    function li50(){
        for(var i=0; i<50; i++){
            var oLi=createLi();
            var ary=makeArray(aUl);
            ary.sort(function(a,b){
                return a.offsetHeight- b.offsetHeight;
            });
            ary[0].appendChild(oLi);
        }
    }
    li50();
    showImg();
    window.onscroll=function(){
        var scrollBottom=win('scrollTop')+win('clientHeight');
        showImg();//延迟加载图片,只要图片进入可视区,才显示图片
        if(scrollBottom>=win("scrollHeight")){
            li50();//不管是否进入可视区,只要满足条件,都会动态创建50个;
        }
    };
    function showImg(){
        var scrollBottom=win('scrollTop')+win('clientHeight');
        for(var i=0; i<aLi.length; i++){
            var imgPos=aLi[i].offsetTop+aLi[i].offsetHeight;
            if(imgPos<scrollBottom){
                aImg[i].src=aImg[i].getAttribute('realImg');
                aImg[i].parentNode.style.height='auto';
            }
        }
    }
</script>
</body>
</html>

二、九宫格之位置交换
1、普通模式(DOM二级事件)
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>九宫格之位置交换</title>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
            list-style: none;
        }
        .whole {
             480px;
            height: 480px;
            padding: 5px;
            background: #CFC;
            position: relative;
            margin: 100px auto;
        }
        .whole .single {
             150px;
            height: 150px;
            margin: 5px;
            cursor: move;
            user-select: none;
            background: #FF9;
            overflow: hidden;
            float: left;
        }
        .whole .single img {
             100%;
            height: 100%;
            border: none;
        }
    </style>
</head>
<body>
<div class="whole">
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
</div>
</body>
</html>
<script>
    /*第一步:准备(订阅、解除订阅、发布)方法*/
    function on(ele, type, fn) {
        if (ele.addEventListener) {
            ele.addEventListener(type, fn, false);
        } else {
            if (!ele["onEvent" + type]) {
                ele["onEvent" + type] = [];
                ele.attachEvent("on" + type, function () {
                    run.call(ele)
                });
            }
            var single = ele["onEvent" + type];
            for (var i = 0; i < single.length; i++) {
                if (single[i] == fn)return;
            }
            single.push(fn);
        }
    }
    function off(ele, type, fn) {
        if (ele.removeEventListener) {
            ele.removeEventListener(type, fn, false);
        } else {
            var single = ele["onEvent" + type];
            if (single && single.length) {
                for (var i = 0; i < single.length; i++) {
                    if (single[i] == fn) {
                        single[i] = null;
                        return;
                    }
                }
            }
        }
    }
    function run(ele, type, event) {
        var single = ele["custom" + type];
        if (single && single.length) {
            for (var i = 0; i < single.length; i++) {
                if (typeof single[i] == "function") {
                    single[i].call(ele, event);
                } else {
                    single.splice(i, 1);
                    i--;
                }
            }
        }
    };
    /*第二步:准备与动画相关的方法*/
    function animate(ele, obj, duration) {
        var allBegin = {};//用来保存多个方向begin;
        var allChange = {};//用来保存多个方向的change;
        var flag = 0;//用来记录各个方向的距离是否有效
        for (var attr in obj) {
            var target = obj[attr]
            var begin = getCss(ele, attr);
            var change = target - begin;
            if (change) {//判断一下此方向的运动距离有效,不为0
                allBegin[attr] = begin;
                allChange[attr] = change;
                flag++;
            }
        }
        if (!flag) return; //如果各个方向的运动距离都是0,则结束动画的执行
        var interval = 15;
        var times = 0;
        clearInterval(ele.timer);
        function step() {
            times += interval;
            if (times < duration) {
                for (var attr in allChange) {
                    var change = allChange[attr];
                    var begin = allBegin[attr];
                    var val=times/duration*change+begin;
                    setCss(ele, attr, val);
                }
            } else {
                for (var attr in allChange) {
                    var target = obj[attr];
                    setCss(ele, attr, target);
                }
                clearInterval(ele.timer);
            }
        }
        ele.timer = setInterval(step, interval);
    }
    function getCss(ele, attr) {
        if (window.getComputedStyle) {
            return parseFloat(window.getComputedStyle(ele, null)[attr]);
        } else {
            if (attr == "opacity") {
                //opacity:0.5;
                //filter:Alpha(opacity=50); 
                var filter = ele.currentStyle.filter;
                var reg = /alpha(opacity=(d+(?:.d+)?))/;
                if (reg.test(filter)) {// IE8 以及更早的浏览器
                    return RegExp.$1 / 100;
                } else {
                    return 1;//如果没有给不透明度赋值,则应该把默认值1返回
                }
            } else {
                return parseFloat(ele.currentStyle[attr]);
            }
        }
    }
    function setCss(ele, attr, val) {
        if (attr == "opacity") {
            ele.style.opacity = val;
            ele.style.filter = "alpha(opacity=" + val * 100 + ")";
        } else {
            ele.style[attr] = val + "px";
        }
    }
    function processThis(fn, context) {
        return function (event) {
            fn.call(context, event);
        };
    }
    function Drag(ele) {
        this.minX = null;
        this.minY = null;
        this.maxX = null;
        this.maxY = null;
        this.ele = ele;
        this.selfDown = processThis(this.down, this);
        this.selfMove = processThis(this.move, this);
        this.selfUp = processThis(this.up, this);
        on(this.ele, "mousedown", this.selfDown);
    }
    /*第三步:准备拖拽的类*/
    Drag.prototype.down = function (event) {
        this.minX = this.ele.offsetLeft;
        this.minY = this.ele.offsetTop;
        this.maxX = event.pageX;
        this.maxY = event.pageY;
        if (this.ele.setCapture) {
            this.ele.setCapture();
            on(this.ele, "mousemove", this.selfMove);
            on(this.ele, "mouseup", this.selfUp);
        } else {
            on(document, "mousemove", this.selfMove);
            on(document, "mouseup", this.selfUp);
        }
        event.preventDefault();
        this.ele.style.zIndex = ++index;
    };
    Drag.prototype.move = function (event) {
        this.ele.style.left = this.minX + (event.pageX - this.maxX) + "px";
        this.ele.style.top = this.minY + (event.pageY - this.maxY) + "px";
        var ele = this.ele;
        this.allCover = [];
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            if (item == ele)continue;
            //以下检测item是否在this.ele的右、下、左、上方
            var isRight = item.offsetLeft > ele.offsetLeft + ele.offsetWidth;
            var isBottom = item.offsetTop > ele.offsetTop + ele.offsetHeight;
            var isLeft = ele.offsetLeft > item.offsetLeft + item.offsetWidth;
            var isTop = ele.offsetTop > item.offsetTop + item.offsetHeight;
            if (isRight || isBottom || isLeft || isTop) {
              item.style.backgroundColor = "";
            } else {
              this.allCover.push(item);
              item.style.backgroundColor = "red";
            }  
        }
    };
    Drag.prototype.up = function (event) {
        if (this.ele.releaseCapture) {
            this.ele.releaseCapture();
            off(this.ele, "mousemove", this.selfMove);
            off(this.ele, "mouseup", this.selfUp);
        } else {
            off(document, "mousemove", this.selfMove);
            off(document, "mouseup", this.selfUp);
        }
        var allCover = this.allCover;
        if (allCover && allCover.length) {
            for (var i = 0; i < allCover.length; i++) {
                var item = allCover[i];
                //计算被拖拽的元素和撞上的元素之间的距离,并且把距离保存到distance属性上
                //可以先找一个距离四周图片都相等的位置,然后再移动、看效果
                item.distance = Math.sqrt(Math.pow(this.ele.offsetLeft - item.offsetLeft, 2)
                        + Math.pow(this.ele.offsetTop - item.offsetTop, 2));
                item.style.backgroundColor = "";
            }
            //排序,找出和被拖拽元素距离最短(重合面积最大)的那个元素
            allCover.sort(function (one, two) {
                return one.distance - two.distance
            });
            var shortest = allCover[0];
            shortest.style.backgroundColor = "orange";
            this.ele.style.backgroundColor = "orange";
            //交换位置
            animate(shortest, {left: this.ele.left, top: this.ele.top}, 700);
            animate(this.ele, {left: shortest.left, top: shortest.top}, 700);
            var left = this.ele.left;
            var top = this.ele.top;
            this.ele.left = shortest.left;
            this.ele.top = shortest.top;
            shortest.left = left;
            shortest.top = top;
        } else {//如果没有撞上的元素,则返回原始位置
            animate(this.ele, {left: this.ele.left, top: this.ele.top}, 700);
        }
    };
    /*第四步:碰撞检测*/
    var index = 0;
    var items = document.getElementsByClassName("single");
    for (var i = items.length - 1; i >= 0; i--) {
        //从后往前逐个定位。
        //如果从前往后逐个定位,随着前面的脱离文档流,后面的会移动到前面的位置,最终都叠加到第一张图片的上面。
        var item = items[i];
        item.style.left = (item.left = item.offsetLeft) + "px";
        item.style.top = (item.top = item.offsetTop) + "px";
        item.style.position = "absolute";
        new Drag(item)
    }
</script>
2、发布订阅/观察者模式(在实例上订阅,在实例执行事件时发布,含DOM二级事件)
发布/订阅模式中,发布者只要做好消息的发布,而不关心消息有没有订阅者订阅。而观察者模式则要求两端同时存在
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>九宫格之位置交换</title>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
            list-style: none;
        }
        .whole {
             480px;
            height: 480px;
            padding: 5px;
            background: #CFC;
            position: relative;
            margin: 100px auto;
        }
        .whole .single {
             150px;
            height: 150px;
            margin: 5px;
            cursor: move;
            user-select: none;
            background: #FF9;
            overflow: hidden;
            float: left;
        }
        .whole .single img {
             100%;
            height: 100%;
            border: none;
        }
    </style>
</head>
<body>
<div class="whole">
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
    <div class="single"><img src=""></div>
</div>
</body>
</html>
<script>
    /*第一步:准备(订阅、解除订阅、发布)方法*/
    function on(ele, type, fn) {//把方法订阅给实例或文档
        if (ele.addEventListener) {
            ele.addEventListener(type, fn, false);
        } else {
            if (!ele["onEvent" + type]) {
                ele["onEvent" + type] = [];
                ele.attachEvent("on" + type, function () {
                    run.call(ele)
                });
            }
            var single = ele["onEvent" + type];
            for (var i = 0; i < single.length; i++) {
                if (single[i] == fn)return;
            }
            single.push(fn);
        }
    }
    function off(ele, type, fn) {
        if (ele.removeEventListener) {
            ele.removeEventListener(type, fn, false);
        } else {
            var single = ele["onEvent" + type];
            if (single && single.length) {
                for (var i = 0; i < single.length; i++) {
                    if (single[i] == fn) {
                        single[i] = null;
                        return;
                    }
                }
            }
        }
    }
    function run(ele, type, event) {
        var single = ele["custom" + type];
        if (single && single.length) {
            for (var i = 0; i < single.length; i++) {
                if (typeof single[i] == "function") {
                    single[i].call(ele, event);
                } else {
                    single.splice(i, 1);
                    i--;
                }
            }
        }
    };
    /*第二步:准备与动画相关的方法*/
    function animate(ele, obj, duration) {
        var allBegin = {};//用来保存多个方向begin;
        var allChange = {};//用来保存多个方向的change;
        var flag = 0;//用来记录各个方向的距离是否有效
        for (var attr in obj) {
            var target = obj[attr]
            var begin = getCss(ele, attr);
            var change = target - begin;
            if (change) {//判断一下此方向的运动距离有效,不为0
                allBegin[attr] = begin;
                allChange[attr] = change;
                flag++;
            }
        }
        if (!flag) return; //如果各个方向的运动距离都是0,则结束动画的执行
        var interval = 15;
        var times = 0;
        clearInterval(ele.timer);
        function step() {
            times += interval;
            if (times < duration) {
                for (var attr in allChange) {
                    var change = allChange[attr];
                    var begin = allBegin[attr];
                    var val=times/duration*change+begin;
                    setCss(ele, attr, val);
                }
            } else {
                for (var attr in allChange) {
                    var target = obj[attr];
                    setCss(ele, attr, target);
                }
                clearInterval(ele.timer);
            }
        }
        ele.timer = setInterval(step, interval);
    }
    function getCss(ele, attr) {
        if (window.getComputedStyle) {
            return parseFloat(window.getComputedStyle(ele, null)[attr]);
        } else {
            if (attr == "opacity") {
                //opacity:0.5;
                //filter:Alpha(opacity=50); 
                var filter = ele.currentStyle.filter;
                var reg = /alpha(opacity=(d+(?:.d+)?))/;
                if (reg.test(filter)) {// IE8 以及更早的浏览器
                    return RegExp.$1 / 100;
                } else {
                    return 1;//如果没有给不透明度赋值,则应该把默认值1返回
                }
            } else {
                return parseFloat(ele.currentStyle[attr]);
            }
        }
    }
    function setCss(ele, attr, val) {
        if (attr == "opacity") {
            ele.style.opacity = val;
            ele.style.filter = "alpha(opacity=" + val * 100 + ")";
        } else {
            ele.style[attr] = val + "px";
        }
    }
    function processThis(fn, context) {
        return function (event) {
            fn.call(context, event);
        };
    }
    /*第三步:准备拖拽的类*/
    function Drag(ele) {
        this.minX = null;
        this.minY = null;
        this.maxX = null;
        this.maxY = null;
        this.ele = ele;
        this.selfDown = processThis(this.down, this);
        this.selfMove = processThis(this.move, this);
        this.selfUp = processThis(this.up, this);
        on(this.ele, "mousedown", this.selfDown);
    }
    Drag.prototype.on = function (type, fn) {//把方法订阅给实例
        if (!this["custom" + type]) {
            this["custom" + type] = [];
        }
        var single = this["custom" + type];
        for (var i = 0; i < single.length; i++) {
            if (single[i] == fn)return this;
        }
        single.push(fn);
        return this;
    };
    Drag.prototype.down = function (event) {
        this.minX = this.ele.offsetLeft;
        this.minY = this.ele.offsetTop;
        this.maxX = event.pageX;
        this.maxY = event.pageY;
        if (this.ele.setCapture) {
            this.ele.setCapture();
            on(this.ele, "mousemove", this.selfMove);
            on(this.ele, "mouseup", this.selfUp);
        } else {
            on(document, "mousemove", this.selfMove);
            on(document, "mouseup", this.selfUp);
        }
        event.preventDefault();
        run(this,"custDown", event);
    };
    Drag.prototype.move = function (event) {
        this.ele.style.left = this.minX + (event.pageX - this.maxX) + "px";
        this.ele.style.top = this.minY + (event.pageY - this.maxY) + "px";
        run(this,"custMove", event);
    };
    Drag.prototype.up = function (event) {
        if (this.ele.releaseCapture) {
            this.ele.releaseCapture();
            off(this.ele, "mousemove", this.selfMove);
            off(this.ele, "mouseup", this.selfUp);
        } else {
            off(document, "mousemove", this.selfMove);
            off(document, "mouseup", this.selfUp);
        }
        run(this, "custUp", event);
    };
    /*第四步:碰撞检测*/
    var index = 0;
    var items = document.getElementsByClassName("single");
    for (var i = items.length - 1; i >= 0; i--) {
        //从后往前逐个定位。
        //如果从前往后逐个定位,随着前面的脱离文档流,后面的会移动到前面的位置,最终都叠加到第一张图片的上面。
        var item = items[i];
        item.style.left = (item.left = item.offsetLeft) + "px";
        item.style.top = (item.top = item.offsetTop) + "px";
        item.style.position = "absolute";
        new Drag(item).on("custDown", increaseIndex).on("custMove", testHit).on("custUp", changePosition);
    }
    function increaseIndex() {
        this.ele.style.zIndex = ++index;
    }
    function testHit() {
        var ele = this.ele;
        this.allCover = [];
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            if (item == ele)continue;
            //以下检测item是否在this.ele的右、下、左、上方
            var isRight = item.offsetLeft > ele.offsetLeft + ele.offsetWidth;
            var isBottom = item.offsetTop > ele.offsetTop + ele.offsetHeight;
            var isLeft = ele.offsetLeft > item.offsetLeft + item.offsetWidth;
            var isTop = ele.offsetTop > item.offsetTop + item.offsetHeight;
            if (isRight || isBottom || isLeft || isTop) {
              item.style.backgroundColor = "";
            } else {
              this.allCover.push(item);
              item.style.backgroundColor = "red";
            }  
        }
    }
    function changePosition() {
        var allCover = this.allCover;
        if (allCover && allCover.length) {
            for (var i = 0; i < allCover.length; i++) {
                var item = allCover[i];
                //计算被拖拽的元素和撞上的元素之间的距离,并且把距离保存到distance属性上
                //可以先找一个距离四周图片都相等的位置,然后再移动、看效果
                item.distance = Math.sqrt(Math.pow(this.ele.offsetLeft - item.offsetLeft, 2)
                        + Math.pow(this.ele.offsetTop - item.offsetTop, 2));
                item.style.backgroundColor = "";
            }
            //排序,找出和被拖拽元素距离最短(重合面积最大)的那个元素
            allCover.sort(function (one, two) {
                return one.distance - two.distance
            });
            var shortest = allCover[0];
            shortest.style.backgroundColor = "orange";
            this.ele.style.backgroundColor = "orange";
            //交换位置
            animate(shortest, {left: this.ele.left, top: this.ele.top}, 700);
            animate(this.ele, {left: shortest.left, top: shortest.top}, 700);
            var left = this.ele.left;
            var top = this.ele.top;
            this.ele.left = shortest.left;
            this.ele.top = shortest.top;
            shortest.left = left;
            shortest.top = top;
        } else {//如果没有撞上的元素,则返回原始位置
            animate(this.ele, {left: this.ele.left, top: this.ele.top}, 700);
        }
    }
</script>
三、跑马灯效果
实现原理:将图片复制一份放到第一份图片后面;第一份图片从显示区左边界跑出多少、第二份图片就从显示区右边界跑入多少;第一份图片完全跑出显示区时,第二份图片则完全跑入显示区。此时瞬间切换至轮播开始时的状态。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
        *{
            margin:0;
            padding:0;
            list-style: none;
        }
        div{
            position: relative;
             800px;
            height: 200px;
            border: 5px solid lightgreen;
            margin:10px auto;
            overflow: hidden;
        }
        div ul{
            position: absolute;
            left:0;
            top:0;
        }
        div ul li{
             200px;
            height: 200px;
            float: left;
        }
        div ul li img{
            100%;
            height: 100%;
        }
    </style>
</head>
<body>
<div id="div1">
    <ul>
        <li><img src="http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517838828_mthumb.jpg" alt=""/></li>
        <li><img src="http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517841171_mthumb.jpg" alt=""/></li>
        <li><img src="http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517843343_mthumb.jpg" alt=""/></li>
        <li><img src="http://img.pconline.com.cn/images/upload/upc/tx/photoblog/1509/06/c5/12226915_12226915_1441517845828_mthumb.jpg" alt=""/></li>
    </ul>
</div>
<script>
    var oUl=document.getElementsByTagName('ul')[0];
    var lis=oUl.getElementsByTagName('li');
    oUl.innerHTML+=oUl.innerHTML;
    oUl.style.width=lis.length*lis[0].offsetWidth+'px';
    var left=null;
    var timer=setInterval(function(){
        left-=3;
        if(left<-oUl.offsetWidth/2){
            left=0;
        }
        oUl.style.left=left+'px'
    },20)
</script>
</body>
</html>

四、卷轴展开效果
实现原理:(1)利用绝对定位固定好起始位置;(2)利用遮罩将右轴右侧的部分遮住;(3)让右轴和遮罩同时同速度向右运动!
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>诏书</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }
        #animate {
            margin: 40px auto;
             1100px;
            height: 500px;
            position: relative;
            overflow: hidden;
        }
        #back {
             1100px;
            height: 500px;
            position: absolute;
            left: 40px;
            top: 95px;
        }
        #leftAxis {
            position: absolute;
            left: 0;
        }
        #rightAxis {
            position: absolute;
            left: 16px;
        }
        #rightWhiteMark {
            position: absolute;
            left: 70px;
            top:95px;
        }
    </style>
</head>
<body>
<div id="animate">
    <div id="back"><img src="https://cdn.files.qdfuns.com/article/content/picture/201806/09/145027pf0jh29z4nhlljr5.png"/></div>
    <div id="leftAxis"><img src="https://cdn.files.qdfuns.com/article/content/picture/201806/09/145336cd8g5iq7r78qsk8z.png"/></div>
    <div id="rightWhiteMark"><img src="https://cdn.files.qdfuns.com/article/content/picture/201806/26/193935vzzlvazlrkgcxxv6.png"/></div>
    <div id="rightAxis"><img src="https://cdn.files.qdfuns.com/article/content/picture/201806/09/145336cd8g5iq7r78qsk8z.png"/></div>
</div>
</body>
<script>
    var animate=document.getElementById("animate");
    var rightAxis = document.getElementById("rightAxis");
    var rightWhiteMark = document.getElementById("rightWhiteMark");
    var timer = setInterval(function () {
        var rightAxisLeft=getComputedStyle(rightAxis).left;
        var rightWhiteMarkLeft=getComputedStyle(rightWhiteMark).left;
        if(parseFloat(rightAxisLeft)>=923){
            rightAxisLeft=923+"px";
            clearInterval(timer);
        }
        rightAxis.style.left=(parseFloat(rightAxisLeft)+10)+"px";
        rightWhiteMark.style.left=(parseFloat(rightWhiteMarkLeft)+10)+"px";
    }, 20)
</script>
</html>

五、“几”字形选项卡
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .box{
            612px;
            border:2px red solid;
            margin: 0 auto;
        }
        ul{
            overflow: hidden;
        }
        li{
            list-style: none;
            background:red;
            float: left;
             200px;
            height: 30px;
            line-height: 30px;
            text-align: center;
            border: 2px solid orange;
        }
        li.on{
            background: green;
            border-bottom: none;/*让该卡头的下边框为“none”*/
            height: 32px;/*卡头的内容高度设置为:原内容的高度+卡头下边框的宽度。*/
        }
        .box div{
            background:green;
            display: none;
            612px;
            height:200px;
            font-size: 30px;
            border-top: none;/*在开始写样式时,就把展示区上边框设置成“none”*/
        }
        .box div.on{
            display: block;
        }
    </style>
</head>
<body>
<div class="box" id="box">
    <ul>
        <li>中国</li>
        <li class="on">日本</li>
        <li>韩国</li>
    </ul>
    <div>中国是老大</div>
    <div class="on">日本是老二</div>
    <div>韩国是老三</div>
</div>
<script>
    var box = document.getElementById('box');
    var ul = document.getElementsByTagName('ul')[0];
    var lis = box.getElementsByTagName('li');
    var divs = box.getElementsByTagName('div');
    for(var i=0;i<lis.length;i++){
        lis[i].qiancheng = i;
        lis[i].onmouseover = function(){
            for(var j=0;j<lis.length;j++){
                lis[j].className = '';
                divs[j].className = '';
            }
            this.className = 'on';
            divs[this.qiancheng].className = 'on';
        }
    }
    ul.onmouseout=function () {
        for(var j=0;j<lis.length;j++){
            if(j===1){
                lis[j].className = 'on';
                divs[lis[j].qiancheng].className = 'on';
                continue;
            }
            lis[j].className = '';
            divs[j].className = '';
        }
    }
</script>
</body>
</html>

六、胶卷式放映
图片像电影的胶卷一样,一帧帧地放映,且可以任意删减图片帧数,不会影响放映效果。
所用技术为:CSS3动画和原生JavaScript。
<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>胶卷式放映</title>
  <style type="text/css" id="style1">
    * {
      margin: 0;
      padding: 0;
      font-family:"楷体"
    }
    body{
      background: black;
    }
    #wrap {
       150px;
      height: 120px;
      margin: 200px auto;
      perspective: 2000px;
    }
    #wrap ul {
       100%;
      height: 100%;
      transform-style: preserve-3d;
      animation:move 12s 3.2s infinite ;
    }
    #wrap ul li {
      top: 0;
      left: 0;
      position: absolute;
       148px;
      height: 118px;
      line-height: 118px;
      text-align: center;
      font-size: 118px;
      background: grey;
      border: 1px solid #ccc;
      box-shadow: 1px 1px 3px rgba(255, 255, 255, 0.2);
      border-radius: 5px;
      overflow: hidden;
    }
    .shadow{
       1200px;
      height: 1200px;
      position: absolute;
      left: 50%;
      top: 50%;
      margin-left: -600px;
      margin-top: -600px;
      background: radial-gradient(600px 600px at center,rgba(50,50,50,0.8),rgba(0,0,0,0));
      transform: rotateX(90deg) translateZ(-150px);
    }
  </style>
</head>
<body>
<div id="wrap">
  <ul>
    <li>!</li>
    <li>师</li>
    <li>程</li>
    <li>工</li>
    <li>端</li>
    <li>前</li>
    <li>的</li>
    <li>秀</li>
    <li>优</li>
    <li>最</li>
    <li>上</li>
    <li>史</li>
    <li>历</li>
    <li>类</li>
    <li>人</li>
    <li>是</li>
    <li>成</li>
    <li>钱</li>
  </ul>
  <div class="shadow"></div>
</div>
</body>
</html>
<script>
  var oLis = document.querySelectorAll("#wrap li");
  var oStyle = document.querySelector("#style1");
  var len = oLis.length;
  var aaa = null;
  for (var i = 1; i <= len; i++) {
    (function (i) {
      window.setTimeout(function () {
        oStyle.innerHTML +=
          " #wrap ul li:nth-child(" +
          i +
          "){transform:rotateY(" +
          (len - i) * (360 / len) +
          "deg) translateZ(500px);transition:0.7s;transition-delay:" +
          i * 0.1 +
          "s}";
      }, 100);
    })(i);
  }

  for (i = 0; i <= len; i++) {
    aaa +=
      (100 / len) * i + "%{transform: rotateY(" + (-360 / len) * i + "deg);}";
  }
  oStyle.innerHTML += "@keyframes move {" + aaa + "}";
</script>

七、放大镜
原理:左边阴影在左边图片上从左到右移动的时候,右边大框也在右边大图片上从左到右移动(尽管在视觉、原理和代码上是相反的);所谓放大,其实就是一张原本就很小的图对应一张原本就很大的图。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
  <style>
    *{
      margin:0;
      padding:0;
    }
    .small{
       400px;
      height: 400px;
      position: relative;
      background: url(http://cdn.attach.qdfuns.com/notes/pics/201702/11/214206pk76vdieu5co7uwi.jpg) no-repeat center;
      border: 1px solid #ccc;
    }
    .small .inner{
       100px;
      height: 100px;
      background: yellow;
      opacity: 0.5;
      filter: alpha(opacity=50);
      position: absolute;
      left:0;
      top:0;
      display: none;
    }
    .big{
       400px;
      height: 400px;
      position: absolute;
      left:410px;
      top:0;
      overflow: hidden;
      border: 1px solid #ccc;
      display: none;
    }
    .big img{
       200%;
      height: 200%;
      position: absolute;
      left:0;
      top:0;
    }
  </style>
</head>
<body>
<div id="small" class="small">
  <div class="inner"></div>
</div>
<div id="big" class="big">
  <img src="http://cdn.attach.qdfuns.com/notes/pics/201702/11/214213x2oh86wpuuuzcuuc.jpg" alt=""/>
</div>
<script>
  var small = document.getElementById("small");
  var inner = small.getElementsByTagName("div")[0];
  var big = document.getElementById("big");
  var img = big.getElementsByTagName("img")[0];
  //当鼠标移入small的时候,inner和big显示
  small.onmouseover = function () {
    big.style.display = "block";
    inner.style.display = "block";
  };
  //当鼠标在small移动的时候:1)鼠标在inner的中间 2)inner跟随鼠标移动
  small.onmousemove = function (e) {
    e = e || window.event;
    var left = e.clientX - this.offsetLeft - inner.offsetWidth / 2;
    var top = e.clientY - this.offsetTop - inner.offsetHeight / 2;
    if (left <= 0) {
      left = 0;
    } else if (left >= this.offsetWidth - inner.offsetWidth) {
      left = this.offsetWidth - inner.offsetWidth;
    }
    if (top <= 0) {
      top = 0;
    } else if (top >= this.offsetHeight - inner.offsetHeight) {
      top = this.offsetHeight - inner.offsetHeight;
    }
    inner.style.left = left + "px";
    inner.style.top = top + "px";
    //当inner移动的时候,大图跟着一起移动,并且,大图和inner移动的方向相反;
    //或者理解为:左边阴影在图片上从左到右移动的时候,右边大框也在大图片上从左到右移动(尽管视觉上是相反的)。
    img.style.left =
      (left / (small.offsetWidth - inner.offsetWidth)) *
        (big.offsetWidth - img.offsetWidth) +
      "px";
    img.style.top =
      (top / (small.offsetHeight - inner.offsetHeight)) *
        (big.offsetHeight - img.offsetHeight) +
      "px";
  };
  //当鼠标移出的时候,inner和big隐藏;
  small.onmouseout = function () {
    big.style.display = "none";
    inner.style.display = "none";
  };
</script>
</body>
</html>
 
八、锚点
  <!DOCTYPE html>
  <html lang="en">
  <head>
  <meta charset="UTF-8">
  <title>Document</title>
  </head>
  <body>
  <a href="#5F">点击我,锚点会定位到某个地方。此处a href="#5F";彼处a name="5F"  </a>
  <br/>
  <br/>
  <br/>
  <br/>
  <br/>
  <br/>
  <br/>
  <a name="5F">某个地方哈哈哈哈</a>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
  </body>
  </html>
 
 
 
 
 
原文地址:https://www.cnblogs.com/gushixianqiancheng/p/10967172.html