├── README.md ├── ajax封装 ├── 1.json ├── index.html └── test.php ├── amd模块化实现hash路由 ├── README.md ├── app.js ├── index.html ├── js │ ├── Route.js │ ├── Router.js │ ├── lib │ │ ├── jquery-3.3.1.js │ │ └── require.js │ └── sale │ │ ├── add.js │ │ ├── index.js │ │ └── test.js └── service │ └── serviceSale.js ├── miniVue ├── compile.js ├── index.html ├── vue底层原理关系图.png └── wwvue.js ├── 可拖拽弹窗 ├── dialog.html ├── drag-plugin.js └── drag1.html ├── 拖拽 ├── css │ ├── bootstrap.min.css │ └── reset.min.css ├── drag-plugin.html ├── drag1.html └── js │ ├── bootstrap.min.js │ ├── dialog.js │ ├── drag-plugin.js │ ├── jquery.min.js │ ├── less-2.5.3.min.js │ ├── prefixfree.min.js │ └── zepto.min.js ├── 放大镜 ├── css │ └── reset.min.css ├── follow.html ├── images │ ├── 1.jpg │ ├── 2.jpg │ ├── apple_1.jpg │ ├── apple_1_bigger.jpg │ ├── apple_2.jpg │ ├── apple_2_bigger.jpg │ ├── apple_3.jpg │ ├── apple_3_bigger.jpg │ ├── apple_4.jpg │ └── apple_4_bigger.jpg ├── js │ └── jquery.min.js ├── magnifier.html └── 放大镜.png ├── 树形插件 ├── css │ └── reset.min.css ├── data.json ├── index.html ├── js │ └── ztree-plugin.js └── 递归数据绑定.png ├── 瀑布流 ├── 1-定时器.html ├── 2-函数的防抖和节流.html ├── css │ ├── bootstrap.min.css │ ├── index.css │ └── reset.min.css ├── flex.html ├── img │ ├── 1.jpg │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ ├── 7.jpg │ ├── 8.jpg │ ├── 9.jpg │ └── default.gif ├── index.html ├── js │ ├── index-BT.js │ ├── index.js │ └── jquery-1.11.3.min.js ├── json │ ├── data.json │ └── mocData.js ├── package-lock.json ├── 瀑布流-图片加载问题.png └── 瀑布流.png ├── 腾讯视频 ├── .gitignore ├── css │ ├── index.css │ ├── video.css │ └── video.min.css ├── demo.html ├── img │ ├── .DS_Store │ ├── 1.jpg │ ├── ended.png │ ├── error.png │ ├── fullscreen-exit.png │ ├── fullscreen.png │ ├── loading.gif │ ├── pause.png │ ├── play.png │ ├── volume-off.png │ └── volume.png ├── index.html ├── js │ ├── .DS_Store │ ├── video.js │ └── video.min.js └── myplugin │ ├── css │ ├── index.css │ └── video.css │ ├── img │ ├── .DS_Store │ ├── 1.jpg │ ├── ended.png │ ├── error.png │ ├── fullscreen-exit.png │ ├── fullscreen.png │ ├── loading.gif │ ├── pause.png │ ├── play.png │ ├── volume-off.png │ └── volume.png │ ├── index.html │ └── js │ └── video.js ├── 轮播图 ├── css │ ├── banner.css │ ├── reset.min.css │ └── swiper.min.css ├── images │ ├── banner01.png │ ├── banner02.jpg │ ├── banner03.png │ ├── banner04.png │ ├── banner05.png │ └── icon-slides.png ├── index.html ├── js │ ├── banner.js │ ├── jquery.min.js │ └── swiper.min.js └── json │ ├── bannerData1.json │ └── bannerData2.json └── 选项卡 ├── css └── index.css ├── index.html └── js ├── index.js └── tab.js /README.md: -------------------------------------------------------------------------------- 1 | # mini-framework -------------------------------------------------------------------------------- /ajax封装/1.json: -------------------------------------------------------------------------------- 1 | { 2 | "msg":1, 3 | "data":[{"name":"weizai"},{"name":"weizai2"}] 4 | } -------------------------------------------------------------------------------- /ajax封装/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ajax封装 5 | 6 | 7 | 123 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ajax封装/test.php: -------------------------------------------------------------------------------- 1 | 'weizai' , 'age' =>22); 3 | echo json_encode($data); -------------------------------------------------------------------------------- /amd模块化实现hash路由/README.md: -------------------------------------------------------------------------------- 1 | # 路由实现 AMD模块化 2 | 3 | ## 定义目录 4 | /js 一些类库 5 | /service 服务层:增删查改 6 | 7 | ## 入口 8 | app.js 9 | 入口处定义全局依赖 jquery service 10 | ```js 11 | require.config({ 12 | //文件路径的前缀 13 | baseUrl:"js", 14 | paths:{ 15 | //文件 16 | jquery:"lib/jquery-3.3.1", 17 | //文件夹 18 | service:"../service", 19 | } 20 | }) 21 | 22 | ``` 23 | 24 | ## 路由 25 | router.js 定义路由的实现 26 | > 监听hashchange事件,通过location.hash获取路由数据 27 | > location.hash截取合适的数据substring(1) 格式为/a/b这种 将#截取掉 28 | > push函数实现路由的切换 从路由定义表route.js获取路由路径,路由执行 29 | 30 | route.js 定义路由参数,类似vue-router的router.js 31 | > 需要定义路由对象实例,并且传入配置 有path和component 32 | > 这里component就是一个函数(里面可以实现对页面的渲染) 33 | 34 | ## 层层嵌套问题 35 | 场景: 36 | add.js中调用router.js 37 | router.js中调用add.js 38 | 产生了层层嵌套关系 39 | 解决:add.js中 调用require模块 手动调用require.js模块 -------------------------------------------------------------------------------- /amd模块化实现hash路由/app.js: -------------------------------------------------------------------------------- 1 | require.config({ 2 | baseUrl:"js", 3 | paths:{ 4 | //文件 5 | jquery:"lib/jquery-3.3.1", 6 | //文件夹 7 | service:"../service", 8 | } 9 | }) 10 | 11 | require(["jquery","Router","sale/index"],function($,router,saleIndex){ 12 | //策略模式 13 | let actions = { 14 | "aside-saleman":function(){ 15 | console.log('aside-sale') 16 | router.push({ path:"/sale/index"} ) 17 | }, 18 | "aside-car":function(){ 19 | alert('aside-car') 20 | console.log('aside-car') 21 | }, 22 | "aside-shop":function(){ 23 | alert('aside-shop') 24 | } 25 | } 26 | //默认 27 | saleIndex() 28 | router.push({ path:"/sale/index"} ) 29 | 30 | //事件委托 绑定父即可 31 | $(".aside").click(function(e){ 32 | let className = e.target.className; 33 | if(["aside-saleman","aside-car","aside-shop"].includes(className)){ 34 | actions[className]() 35 | } 36 | }) 37 | 38 | //默认展示第一个菜单栏的内容 39 | $(".aside .aside-item:eq(0)").trigger("click"); 40 | }) -------------------------------------------------------------------------------- /amd模块化实现hash路由/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 30 | 31 | 32 | 33 | 34 | Document 35 | 36 | 37 |
38 |
39 | 44 |
45 |
46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /amd模块化实现hash路由/js/Route.js: -------------------------------------------------------------------------------- 1 | //Route作者编写的部分 2 | define([],function(){ 3 | function Route(option){ 4 | this.routes=option.routes; 5 | this.init(); 6 | } 7 | Route.prototype={ 8 | constructor:Route, 9 | //初始化 10 | init(){ 11 | window.addEventListener("hashchange",()=>{ 12 | var hash=location.hash.substring(1); 13 | console.log('hash',hash) 14 | this.push({path:hash}) 15 | }) 16 | }, 17 | 18 | push({path}){ 19 | console.log('diaoyong push') 20 | var route=this.routes.find(item=>{ 21 | return item.path === path 22 | }); 23 | console.log('push',route) 24 | if(route){ 25 | route.component(); 26 | } 27 | } 28 | } 29 | 30 | return Route; 31 | 32 | }) -------------------------------------------------------------------------------- /amd模块化实现hash路由/js/Router.js: -------------------------------------------------------------------------------- 1 | //用户编写的部分 2 | define(["Route","sale/index","sale/add"],function(Route,saleIndex,saleAdd){ 3 | var router=new Route({ 4 | routes:[ 5 | { path:"/sale/index",component: saleIndex }, 6 | { path:"/sale/add",component: saleAdd }, 7 | ], 8 | }); 9 | 10 | return router; 11 | 12 | }) -------------------------------------------------------------------------------- /amd模块化实现hash路由/js/sale/add.js: -------------------------------------------------------------------------------- 1 | define(['jquery','service/serviceSale','require'],function($,serviceSale,require){ 2 | return function(){ 3 | let router = require("Router") 4 | let str = ` 5 |
6 | name: 7 | age: 8 | 9 |
10 | `; 11 | 12 | let $addstr = $(str) 13 | 14 | $("#main .content").html($addstr) 15 | 16 | $addstr.on('submit',function(e){ 17 | e.preventDefault() 18 | let name = $("input[name=name]").val() 19 | let age = $("input[name=age]").val() 20 | serviceSale.add({name,age}) 21 | console.log('add',router) 22 | router.push({path:'/sale/index'}) 23 | }) 24 | } 25 | }) -------------------------------------------------------------------------------- /amd模块化实现hash路由/js/sale/index.js: -------------------------------------------------------------------------------- 1 | define(['jquery','service/serviceSale',"sale/add","require"],function($,serviceSale,saleAdd,require){ 2 | return function(){ 3 | let router = require("Router") 4 | let str = `
5 |

6 | ${serviceSale.list().map(item=>{ 7 | return `

${item.name}|${item.age}

` 8 | }).join("")} 9 |
`; 10 | //这样确保生成的dom可以被绑定事件 11 | let $index = $(str); 12 | $index.on("click",".add",function(){ 13 | //跳转页面 14 | console.log('clickindex',router) 15 | router.push({path:'/sale/add'}) 16 | }) 17 | $("#main .content").html($index); 18 | } 19 | }) -------------------------------------------------------------------------------- /amd模块化实现hash路由/js/sale/test.js: -------------------------------------------------------------------------------- 1 | define([],function(){ 2 | return function(){ 3 | console.log('test') 4 | } 5 | }) -------------------------------------------------------------------------------- /amd模块化实现hash路由/service/serviceSale.js: -------------------------------------------------------------------------------- 1 | define([],function(){ 2 | //数据 3 | let list = [ 4 | {name:'w1',age:20}, 5 | {name:'w2',age:21}, 6 | {name:'w3',age:22} 7 | ] 8 | //数据的操作 9 | return { 10 | list(){ 11 | return list; 12 | }, 13 | add({name,age}){ 14 | let data = { 15 | name:name, 16 | age:age 17 | } 18 | list.push(data) 19 | } 20 | } 21 | }) -------------------------------------------------------------------------------- /miniVue/compile.js: -------------------------------------------------------------------------------- 1 | // new Compile(el, vm) 2 | 3 | class Compile { 4 | constructor(el, vm) { 5 | this.$vm = vm; 6 | this.$el = document.querySelector(el); 7 | 8 | if (this.$el) { 9 | // 提取宿主中模板内容到Fragment标签,dom操作会提高效率 10 | this.$fragment = this.node2Fragment(this.$el); 11 | // 编译模板内容,同时进行依赖收集 12 | this.compile(this.$fragment); 13 | this.$el.appendChild(this.$fragment); 14 | } 15 | } 16 | 17 | node2Fragment(el) { 18 | const fragment = document.createDocumentFragment(); 19 | let child; 20 | while ((child = el.firstChild)) { 21 | fragment.appendChild(child); 22 | } 23 | return fragment; 24 | } 25 | compile(el) { 26 | const childNodes = el.childNodes; 27 | 28 | Array.from(childNodes).forEach(node => { 29 | // 判断节点类型 30 | if (node.nodeType === 1) { 31 | // element节点 32 | // console.log('编译元素节点'+node.nodeName); 33 | this.compileElement(node); 34 | } else if (this.isInterpolation(node)) { 35 | // 插值表达式 36 | // console.log('编译插值文本'+node.textContent); 37 | this.compileText(node); 38 | } 39 | 40 | // 递归子节点 41 | if (node.childNodes && node.childNodes.length > 0) { 42 | this.compile(node); 43 | } 44 | }); 45 | } 46 | 47 | isInterpolation(node) { 48 | // 是文本且符合{{}} 49 | return node.nodeType === 3 && /\{\{(.*)\}\}/.test(node.textContent); 50 | } 51 | 52 | compileElement(node) { 53 | //
54 | let nodeAttrs = node.attributes; 55 | Array.from(nodeAttrs).forEach(attr => { 56 | const attrName = attr.name; 57 | const exp = attr.value; 58 | if (this.isDirective(attrName)) { 59 | const dir = attrName.substring(2); 60 | this[dir] && this[dir](node, this.$vm, exp); 61 | } 62 | if (this.isEvent(attrName)) { 63 | const dir = attrName.substring(1); 64 | this.eventHandler(node, this.$vm, exp, dir); 65 | } 66 | }); 67 | } 68 | isDirective(attr) { 69 | return attr.indexOf("k-") === 0; 70 | } 71 | 72 | isEvent(attr) { 73 | return attr.indexOf("@") === 0; 74 | } 75 | compileText(node) { 76 | console.log(RegExp.$1); 77 | 78 | this.update(node, this.$vm, RegExp.$1, "text"); 79 | } 80 | 81 | update(node, vm, exp, dir) { 82 | let updatrFn = this[dir + "Updater"]; 83 | updatrFn && updatrFn(node, vm[exp]); 84 | // 依赖收集 85 | new Watcher(vm, exp, function(value) { 86 | updatrFn && updatrFn(node, value); 87 | }); 88 | } 89 | text(node, vm, exp) { 90 | this.update(node, vm, exp, "text"); 91 | } 92 | textUpdater(node, val) { 93 | node.textContent = val; 94 | } 95 | 96 | eventHandler(node, vm, exp, dir) { 97 | const fn = vm.$options.methods && vm.$options.methods[exp]; 98 | if (dir && fn) { 99 | node.addEventListener(dir, fn.bind(vm)); 100 | } 101 | } 102 | 103 | html(node, vm, exp) { 104 | this.update(node, vm, exp, "html"); 105 | } 106 | 107 | model(node, vm, exp) { 108 | // data -> view 109 | this.update(node, vm, exp, "model"); 110 | // view -> data 111 | node.addEventListener("input", e => { 112 | vm[exp] = e.target.value; 113 | }); 114 | } 115 | 116 | htmlUpdater(node, value) { 117 | node.innerHTML = value; 118 | } 119 | 120 | modelUpdater(node, value) { 121 | node.value = value; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /miniVue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 | 11 | 12 |
13 |

{{name}}

14 |

15 |

{{age}}

16 |

17 | {{doubleAge}} 18 |

19 | 20 | 21 |
22 |
23 | 24 | 25 | 26 | 48 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /miniVue/vue底层原理关系图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/miniVue/vue底层原理关系图.png -------------------------------------------------------------------------------- /miniVue/wwvue.js: -------------------------------------------------------------------------------- 1 | // 期待用法 2 | // new KVue({ 3 | // data:{msg:'hello'} 4 | // }) 5 | 6 | class WWVue { 7 | constructor(options) { 8 | this.$options = options; 9 | 10 | //处理data选项 11 | this.$data = options.data; 12 | // 响应化 13 | this.observe(this.$data); 14 | 15 | // new Watcher(); 16 | // this.$data.test; 17 | // new Watcher(); 18 | // this.$data.foo.bar; 19 | 20 | new Compile(options.el, this); 21 | 22 | if (options.created) { 23 | options.created.call(this); 24 | } 25 | } 26 | 27 | observe(value) { 28 | if (!value || typeof value !== 'object') { 29 | return; 30 | } 31 | // 遍历对象 32 | Object.keys(value).forEach(key => { 33 | this.defineReactive(value, key, value[key]) 34 | // 代理到vm上 35 | this.proxyData(key); 36 | }) 37 | } 38 | proxyData(key) { 39 | Object.defineProperty(this, key, { 40 | get(){ 41 | return this.$data[key]; 42 | }, 43 | set(newVal){ 44 | this.$data[key] = newVal; 45 | } 46 | }) 47 | } 48 | defineReactive(obj, key, val) { 49 | const dep = new Dep(); 50 | 51 | Object.defineProperty(obj, key, { 52 | get(){ 53 | // 将Dep.target添加到dep中 54 | Dep.target && dep.addDep(Dep.target) 55 | return val; 56 | }, 57 | set(newVal){ 58 | if (newVal !== val) { 59 | val = newVal; 60 | // console.log(`${key}更新了:${newVal}`); 61 | dep.notify(); 62 | } 63 | } 64 | }) 65 | // 递归 66 | this.observe(val); 67 | } 68 | 69 | } 70 | 71 | class Dep { 72 | constructor(){ 73 | this.deps = []; 74 | } 75 | 76 | addDep(dep) { 77 | this.deps.push(dep) 78 | } 79 | 80 | notify() { 81 | this.deps.forEach(dep => dep.update()) 82 | } 83 | } 84 | 85 | class Watcher { 86 | constructor(vm, key, cb) { 87 | this.vm = vm; 88 | this.key = key; 89 | this.cb = cb; 90 | 91 | Dep.target = this; 92 | this.vm[this.key];// 添加watcher到dep 93 | Dep.target = null; 94 | } 95 | update() { 96 | // console.log('属性更新了'); 97 | this.cb.call(this.vm, this.vm[this.key]) 98 | } 99 | } -------------------------------------------------------------------------------- /可拖拽弹窗/dialog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 115 | 116 | 133 | 134 |
test
135 | 136 | 137 | -------------------------------------------------------------------------------- /可拖拽弹窗/drag-plugin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 简易的拖拽插件 3 | * new Drag([selector],[options]); 4 | * SELECTOR 5 | * 按住谁来实现拖拽 6 | * OPTIONS = {} 7 | * element:拖拽中要移动的元素(默认值:当前按住的元素) 8 | * boundary:是否进行边界校验 (默认值:true,不能超过要移动元素所在容器的范围,需要开发者保证:当前移动的元素是相对于它所在容器定位的) 9 | * 10 | * 声明周期函数(钩子函数) 11 | * dragstart:拖拽开始 12 | * dragmove:拖拽中 13 | * dragend:拖拽结束 14 | */ 15 | ~ function () { 16 | /* 17 | * 拖拽插件封装 18 | */ 19 | class Drag { 20 | constructor(selector, options) { 21 | this.initParams(selector, options); 22 | this._selector.addEventListener('mousedown', this.down.bind(this)); 23 | } 24 | //=>参数初始化(尽可能把一切信息都挂载到实例上,这样在其它方法中,只要能获取到实例,这些信息都可以调用 =>我们尽可能保证每个方法中的THIS都是实例) 25 | initParams(selector, options = {}) { 26 | this._selector = document.querySelector(selector); 27 | 28 | //=>配置项的默认值信息 29 | let defaultParams = { 30 | element: this._selector, 31 | boundary: true, 32 | dragstart: null, 33 | dragmove: null, 34 | dragend: null 35 | }; 36 | defaultParams = Object.assign(defaultParams, options); 37 | 38 | //=>把配置项信息都挂载到实例上 39 | Drag.each(defaultParams, (value, key) => { 40 | this['_' + key] = value; 41 | }); 42 | } 43 | //=>实现拖拽的效果 44 | down(ev) { 45 | let { 46 | _element 47 | } = this; 48 | this.startX = ev.pageX; 49 | this.startY = ev.pageY; 50 | this.startL = Drag.queryCss(_element, 'left'); 51 | this.startT = Drag.queryCss(_element, 'top'); 52 | this._move = this.move.bind(this); 53 | this._up = this.up.bind(this); 54 | document.addEventListener('mousemove', this._move); 55 | document.addEventListener('mouseup', this._up); 56 | //=>钩子函数处理 57 | this._dragstart && this._dragstart(this, ev); 58 | } 59 | move(ev) { 60 | let { 61 | _element, 62 | _boundary, 63 | startX, 64 | startY, 65 | startL, 66 | startT 67 | } = this; 68 | let curL = ev.pageX - startX + startL, 69 | curT = ev.pageY - startY + startT; 70 | if (_boundary) { 71 | //=>处理边界 72 | let parent = _element.parentNode, 73 | minL = 0, 74 | minT = 0, 75 | maxL = parent.offsetWidth - _element.offsetWidth, 76 | maxT = parent.offsetHeight - _element.offsetHeight; 77 | curL = curL < minL ? minL : (curL > maxL ? maxL : curL); 78 | curT = curT < minT ? minT : (curT > maxT ? maxT : curT); 79 | } 80 | _element.style.left = curL + 'px'; 81 | _element.style.top = curT + 'px'; 82 | 83 | //=>钩子函数处理 84 | this._dragmove && this._dragmove(this, curL, curT, ev); 85 | } 86 | up(ev) { 87 | console.log('up....') 88 | console.log(this._move) 89 | document.removeEventListener('mousemove', this._move); 90 | document.removeEventListener('mouseup', this._up); 91 | 92 | //=>钩子函数处理 93 | this._dragend && this._dragend(this, ev); 94 | } 95 | //=>设置工具类的方法(把它当做类[普通对象]的私有属性) 96 | static each(arr, callback) { 97 | if ('length' in arr) { 98 | //=>数组||类数组 99 | for (let i = 0; i < arr.length; i++) { 100 | callback && callback(arr[i], i); 101 | } 102 | return; 103 | } 104 | //=>普通对象 105 | for (let key in arr) { 106 | if (!arr.hasOwnProperty(key)) break; 107 | callback && callback(arr[key], key); 108 | } 109 | } 110 | static queryCss(curEle, attr) { 111 | return parseFloat(window.getComputedStyle(curEle)[attr]); 112 | } 113 | } 114 | window.Drag = Drag; 115 | }(); -------------------------------------------------------------------------------- /可拖拽弹窗/drag1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | weizai 7 | 8 | 30 | 31 | 32 | 33 |
34 |

35 |
36 | 37 | 38 | 44 | 45 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /拖拽/css/reset.min.css: -------------------------------------------------------------------------------- 1 | body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,button,input,textarea,th,td{margin:0;padding:0}body{font-size:12px;font-style:normal;font-family:"\5FAE\8F6F\96C5\9ED1",Helvetica,sans-serif}small{font-size:12px}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4,h5,h6{font-size:100%}ul,ol{list-style:none}a{text-decoration:none;background-color:transparent}a:hover,a:active{outline-width:0;text-decoration:none}table{border-collapse:collapse;border-spacing:0}hr{border:0;height:1px}img{border-style:none}img:not([src]){display:none}svg:not(:root){overflow:hidden}html{-webkit-touch-callout:none;-webkit-text-size-adjust:100%}input,textarea,button,a{-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]),video:not([controls]){display:none;height:0}progress{vertical-align:baseline}mark{background-color:#ff0;color:#000}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}button,input,select,textarea{font-size:100%;outline:0}button,input{overflow:visible}button,select{text-transform:none}textarea{overflow:auto}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.clearfix:after{display:block;height:0;content:"";clear:both} -------------------------------------------------------------------------------- /拖拽/drag-plugin.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 123 7 | 8 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /拖拽/drag1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 123 7 | 8 | 30 | 31 | 32 | 33 |
34 |

35 |
36 | 37 | 38 | 44 | 45 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /拖拽/js/dialog.js: -------------------------------------------------------------------------------- 1 | let $loginBtn = $('#loginBtn'), 2 | $loginModal = $('#loginModal'), 3 | $loginCloseBtn = $('#loginCloseBtn'), 4 | $loginModalBack = $('#loginModalBack'), 5 | $window = $(window); 6 | $loginBtn.click(function () { 7 | $loginModal.css("display", "block"); 8 | $loginModalBack.css('display', 'block'); 9 | $loginModal.css("opacity", 1); 10 | 11 | //=>实现居中 12 | $loginModal.css({ 13 | left: ($window.outerWidth() - $loginModal.outerWidth()) / 2, 14 | top: ($window.outerHeight() - $loginModal.outerHeight()) / 2 15 | }); 16 | }); 17 | $loginCloseBtn.click(function () { 18 | $loginModal.css('opacity', 0).one('transitionend', function () { 19 | $loginModal.css('display', 'none'); 20 | $loginModalBack.css('display', 'none'); 21 | }); 22 | }); 23 | 24 | //=>实现拖拽 25 | /* new Drag('#loginModal .modal-header', { 26 | element: $loginModal.get(0) 27 | }); 28 | */ 29 | 30 | /* let $modalHeade = $loginModal.find('.modal-header'), 31 | $document = $(document), 32 | $window = $(window); 33 | //=>这样处理,当鼠标按下的时候,DOWN方法中的THIS是MODAL-HEAD,但是我们后期要操作整个盒子的样式,我们最好让THIS变为整个盒子(原生JS对象) 34 | // $modalHeade.on('mousedown', down); 35 | $modalHeade.on('mousedown', down.bind($loginModal.get(0))); 36 | 37 | function down(ev) { 38 | let $this = $(this); 39 | this.startX = ev.pageX; 40 | this.startY = ev.pageY; 41 | this.startL = parseFloat($this.css('left')); 42 | this.startT = parseFloat($this.css('top')); 43 | this._move = move.bind(this); 44 | this._up = up.bind(this); 45 | $document.on('mousemove', this._move); 46 | $document.on('mouseup', this._up); 47 | } 48 | 49 | function move(ev) { 50 | let $this = $(this), 51 | curL = ev.pageX - this.startX + this.startL, 52 | curT = ev.pageY - this.startY + this.startT; 53 | let minL = 0, 54 | minT = 0, 55 | maxL = $window.outerWidth() - $this.outerWidth(), 56 | maxT = $window.outerHeight() - $this.outerHeight(); 57 | curL = curL < minL ? minL : (curL > maxL ? maxL : curL); 58 | curT = curT < minT ? minT : (curT > maxT ? maxT : curT); 59 | $this.css({ 60 | top: curT, 61 | left: curL 62 | }); 63 | } 64 | 65 | function up(ev) { 66 | $document.off('mousemove', this._move); 67 | $document.off('mouseup', this._up); 68 | } */ 69 | 70 | /* 71 | * 给元素设置自定义属性 72 | * 1.给内存空间中设置一个属性 73 | * box.myIndex=1; 74 | * $box.myIndex=1; 75 | * 76 | * 2.把自定义属性设置在元素的行内属性上(设置的属性值最后都要变为字符串) 77 | * =>我们在案例中,数据绑定阶段,把一些值存储到元素的行内上,以后要获取的时候只能基于attr/getAttribute获取 78 | * box.setAttribute('myIndex',1); 79 | * $box.attr('myIndex',1); 80 | */ -------------------------------------------------------------------------------- /拖拽/js/drag-plugin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 简易的拖拽插件 3 | * new Drag([selector],[options]); 4 | * SELECTOR 5 | * 按住谁来实现拖拽 6 | * OPTIONS = {} 7 | * element:拖拽中要移动的元素(默认值:当前按住的元素) 8 | * boundary:是否进行边界校验 (默认值:true,不能超过要移动元素所在容器的范围,需要开发者保证:当前移动的元素是相对于它所在容器定位的) 9 | * 10 | * 声明周期函数(钩子函数) 11 | * dragstart:拖拽开始 12 | * dragmove:拖拽中 13 | * dragend:拖拽结束 14 | */ 15 | ~ function () { 16 | /* 17 | * 拖拽插件封装 18 | */ 19 | class Drag { 20 | constructor(selector, options) { 21 | this.initParams(selector, options); 22 | this._selector.addEventListener('mousedown', this.down.bind(this)); 23 | } 24 | //=>参数初始化(尽可能把一切信息都挂载到实例上,这样在其它方法中,只要能获取到实例,这些信息都可以调用 =>我们尽可能保证每个方法中的THIS都是实例) 25 | initParams(selector, options = {}) { 26 | this._selector = document.querySelector(selector); 27 | 28 | //=>配置项的默认值信息 29 | let defaultParams = { 30 | element: this._selector, 31 | boundary: true, 32 | dragstart: null, 33 | dragmove: null, 34 | dragend: null 35 | }; 36 | defaultParams = Object.assign(defaultParams, options); 37 | 38 | //=>把配置项信息都挂载到实例上 39 | Drag.each(defaultParams, (value, key) => { 40 | this['_' + key] = value; 41 | }); 42 | } 43 | //=>实现拖拽的效果 44 | down(ev) { 45 | let { 46 | _element 47 | } = this; 48 | this.startX = ev.pageX; 49 | this.startY = ev.pageY; 50 | this.startL = Drag.queryCss(_element, 'left'); 51 | this.startT = Drag.queryCss(_element, 'top'); 52 | this._move = this.move.bind(this); 53 | this._up = this.up.bind(this); 54 | document.addEventListener('mousemove', this._move); 55 | document.addEventListener('mouseup', this._up); 56 | //=>钩子函数处理 57 | this._dragstart && this._dragstart(this, ev); 58 | } 59 | move(ev) { 60 | let { 61 | _element, 62 | _boundary, 63 | startX, 64 | startY, 65 | startL, 66 | startT 67 | } = this; 68 | let curL = ev.pageX - startX + startL, 69 | curT = ev.pageY - startY + startT; 70 | if (_boundary) { 71 | //=>处理边界 72 | let parent = _element.parentNode, 73 | minL = 0, 74 | minT = 0, 75 | maxL = parent.offsetWidth - _element.offsetWidth, 76 | maxT = parent.offsetHeight - _element.offsetHeight; 77 | curL = curL < minL ? minL : (curL > maxL ? maxL : curL); 78 | curT = curT < minT ? minT : (curT > maxT ? maxT : curT); 79 | } 80 | _element.style.left = curL + 'px'; 81 | _element.style.top = curT + 'px'; 82 | 83 | //=>钩子函数处理 84 | this._dragmove && this._dragmove(this, curL, curT, ev); 85 | } 86 | up(ev) { 87 | console.log('up....') 88 | console.log(this._move) 89 | document.removeEventListener('mousemove', this._move); 90 | document.removeEventListener('mouseup', this._up); 91 | 92 | //=>钩子函数处理 93 | this._dragend && this._dragend(this, ev); 94 | } 95 | //=>设置工具类的方法(把它当做类[普通对象]的私有属性) 96 | static each(arr, callback) { 97 | if ('length' in arr) { 98 | //=>数组||类数组 99 | for (let i = 0; i < arr.length; i++) { 100 | callback && callback(arr[i], i); 101 | } 102 | return; 103 | } 104 | //=>普通对象 105 | for (let key in arr) { 106 | if (!arr.hasOwnProperty(key)) break; 107 | callback && callback(arr[key], key); 108 | } 109 | } 110 | static queryCss(curEle, attr) { 111 | return parseFloat(window.getComputedStyle(curEle)[attr]); 112 | } 113 | } 114 | window.Drag = Drag; 115 | }(); -------------------------------------------------------------------------------- /拖拽/js/prefixfree.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * StyleFix 1.0.3 & PrefixFree 1.0.7 3 | * @author Lea Verou 4 | * MIT license 5 | */ 6 | (function(){function m(a,b){return[].slice.call((b||document).querySelectorAll(a))}if(window.addEventListener){var e=window.StyleFix={link:function(a){var b=a.href||a.getAttribute("data-href");try{if(!b||"stylesheet"!==a.rel||a.hasAttribute("data-noprefix"))return}catch(p){return}var d=b.replace(/[^\/]+$/,""),f=(/^[a-z]{3,10}:/.exec(d)||[""])[0],h=(/^[a-z]{3,10}:\/\/[^\/]+/.exec(d)||[""])[0],k=/^([^?]*)\??/.exec(b)[1],g=a.parentNode,c=new XMLHttpRequest,l;c.onreadystatechange=function(){4===c.readyState&& 7 | l()};l=function(){var b=c.responseText;if(b&&a.parentNode&&(!c.status||400>c.status||600 2 | 3 | 4 | 5 | 6 | 鼠标跟随 7 | 8 | 9 | 50 | 51 | 52 | 53 | 68 | 71 | 72 | 73 | 74 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /放大镜/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/1.jpg -------------------------------------------------------------------------------- /放大镜/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/2.jpg -------------------------------------------------------------------------------- /放大镜/images/apple_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/apple_1.jpg -------------------------------------------------------------------------------- /放大镜/images/apple_1_bigger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/apple_1_bigger.jpg -------------------------------------------------------------------------------- /放大镜/images/apple_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/apple_2.jpg -------------------------------------------------------------------------------- /放大镜/images/apple_2_bigger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/apple_2_bigger.jpg -------------------------------------------------------------------------------- /放大镜/images/apple_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/apple_3.jpg -------------------------------------------------------------------------------- /放大镜/images/apple_3_bigger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/apple_3_bigger.jpg -------------------------------------------------------------------------------- /放大镜/images/apple_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/apple_4.jpg -------------------------------------------------------------------------------- /放大镜/images/apple_4_bigger.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/images/apple_4_bigger.jpg -------------------------------------------------------------------------------- /放大镜/magnifier.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 放大镜 7 | 8 | 9 | 59 | 60 | 61 | 62 |
63 | 64 |
65 | 66 |
67 |
68 | 69 |
70 | 71 |
72 |
73 | 74 | 75 | 76 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /放大镜/放大镜.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/放大镜/放大镜.png -------------------------------------------------------------------------------- /树形插件/css/reset.min.css: -------------------------------------------------------------------------------- 1 | body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,button,input,textarea,th,td{margin:0;padding:0}body{font-size:12px;font-style:normal;font-family:"\5FAE\8F6F\96C5\9ED1",Helvetica,sans-serif}small{font-size:12px}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4,h5,h6{font-size:100%}ul,ol{list-style:none}a{text-decoration:none;background-color:transparent}a:hover,a:active{outline-width:0;text-decoration:none}table{border-collapse:collapse;border-spacing:0}hr{border:0;height:1px}img{border-style:none}img:not([src]){display:none}svg:not(:root){overflow:hidden}html{-webkit-touch-callout:none;-webkit-text-size-adjust:100%}input,textarea,button,a{-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]),video:not([controls]){display:none;height:0}progress{vertical-align:baseline}mark{background-color:#ff0;color:#000}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}button,input,select,textarea{font-size:100%;outline:0}button,input{overflow:visible}button,select{text-transform:none}textarea{overflow:auto}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.clearfix:after{display:block;height:0;content:"";clear:both} -------------------------------------------------------------------------------- /树形插件/data.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "name":"前端开发基础", 3 | "open":true, 4 | "children":[ 5 | { 6 | "name":"HTML5核心知识", 7 | "children":[ 8 | {"name":"新增语义化标签"}, 9 | {"name":"表单元素新特性"}, 10 | {"name":"音视屏处理"}, 11 | {"name":"canvas和webGL"}, 12 | {"name":"新增JS中的API"} 13 | ] 14 | }, 15 | { 16 | "name":"CSS3核心知识", 17 | "children":[ 18 | {"name":"新增选择器"}, 19 | {"name":"字体图标"}, 20 | {"name":"常用的样式属性"}, 21 | {"name":"背景的处理"}, 22 | {"name":"transform变形"}, 23 | { 24 | "name":"CSS3动画", 25 | "children":[ 26 | {"name":"transition过度动画"}, 27 | {"name":"animation帧动画"}, 28 | {"name":"3D动画的处理"} 29 | ] 30 | }, 31 | { 32 | "name":"新盒子模型属性", 33 | "children":[ 34 | {"name":"flex弹性盒子模型"}, 35 | {"name":"box-sizing新盒子模型属性"}, 36 | {"name":"cloumns多列布局"} 37 | ] 38 | } 39 | ] 40 | }, 41 | { 42 | "name":"实战案例和布局技巧", 43 | "children":[ 44 | { 45 | "name":"实战案例练习", 46 | "children":[ 47 | {"name":"居中处理"}, 48 | {"name":"同行排列"}, 49 | {"name":"圣杯布局"}, 50 | {"name":"双飞翼布局"}, 51 | {"name":"滑动门"}, 52 | {"name":"面包屑导航"} 53 | ] 54 | }, 55 | { 56 | "name":"响应式布局开发", 57 | "children":[ 58 | {"name":"viewport和dpi适配"}, 59 | {"name":"@media媒体查询"}, 60 | {"name":"rem等比缩放"}, 61 | {"name":"百分比布局"} 62 | ] 63 | } 64 | ] 65 | } 66 | ] 67 | },{ 68 | "name":"前端开发核心", 69 | "children":[ 70 | { 71 | "name":"JS(ES6)核心", 72 | "children":[ 73 | {"name":"基础知识"}, 74 | {"name":"闭包作用域及堆栈内存"}, 75 | {"name":"面向对象和THIS处理"}, 76 | {"name":"同步异步(事件循环、微任务、宏任务)"}, 77 | {"name":"DOM事件和事件委托"}, 78 | {"name":"设计模式"} 79 | ] 80 | }, 81 | { 82 | "name":"AJAX前后端交互", 83 | "children":[ 84 | {"name":"AJAX基础知识"}, 85 | {"name":"跨域策略请求"}, 86 | {"name":"TCP协议相关基础知识"}, 87 | {"name":"性能和安全的初步优化"}, 88 | {"name":"常用的AJAX库和插件"} 89 | ] 90 | }, 91 | { 92 | "name":"底层原理和高阶JS函数", 93 | "children":[ 94 | {"name":"函数柯里化"}, 95 | {"name":"compos函数"}, 96 | {"name":"惰性思想"}, 97 | {"name":"组件插件封装"}, 98 | {"name":"底层源码解读"} 99 | ] 100 | } 101 | ] 102 | },{ 103 | "name":"前端工程化", 104 | "children":[ 105 | { 106 | "name":"VUE全家桶", 107 | "children":[ 108 | {"name":"基础知识"}, 109 | {"name":"MVVM实现原理"}, 110 | {"name":"路由处理"}, 111 | {"name":"vuex公共状态管理"}, 112 | {"name":"element-ui组件应用和二次封装"} 113 | ] 114 | }, 115 | { 116 | "name":"REACT全家桶", 117 | "children":[ 118 | {"name":"基础知识"}, 119 | {"name":"MVC实现原理"}, 120 | {"name":"DOM DIFF"}, 121 | {"name":"Virtual DOM"}, 122 | {"name":"路由处理"}, 123 | { 124 | "name":"公共状态管理", 125 | "children":[ 126 | {"name":"REACT-REDUX、DAVS/SAGA等"}, 127 | {"name":"compos函数"}, 128 | {"name":"惰性思想"}, 129 | {"name":"组件插件封装"}, 130 | {"name":"底层源码解读"} 131 | ] 132 | }, 133 | {"name":"高阶租价"}, 134 | {"name":"antd组件应用和二次封装"} 135 | ] 136 | }, 137 | { 138 | "name":"底层原理和高阶JS函数", 139 | "children":[ 140 | {"name":"函数柯里化"}, 141 | {"name":"compos函数"}, 142 | {"name":"惰性思想"}, 143 | {"name":"组件插件封装"}, 144 | {"name":"底层源码解读"} 145 | ] 146 | }, 147 | { 148 | "name":"工程化开发部署", 149 | "children":[ 150 | {"name":"webpack"}, 151 | {"name":"git"}, 152 | {"name":"linux"} 153 | ] 154 | } 155 | ] 156 | },{ 157 | "name":"前端开发热门点", 158 | "children":[ 159 | {"name":"TypeScript"}, 160 | {"name":"flutter"}, 161 | {"name":"react native"}, 162 | {"name":"小程序"}, 163 | {"name":"性能和安全的优化"} 164 | ] 165 | }] -------------------------------------------------------------------------------- /树形插件/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | zTree树形结构菜单 7 | 8 | 9 | 65 | 66 | 67 | 68 |
69 |
    70 |
    71 |
    72 |
      73 |
      74 | 75 | 76 | 77 | 78 | 88 | 89 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /树形插件/js/ztree-plugin.js: -------------------------------------------------------------------------------- 1 | ~ function ($) { 2 | function ztree(data) { 3 | let count = 0, 4 | $this = $(this); 5 | 6 | //=>数据绑定 7 | let bindHTML = function (result) { 8 | let str = ``; 9 | result.forEach(item => { 10 | count++; 11 | let { 12 | name, 13 | open, 14 | children 15 | } = item; 16 | str += `
    • 17 | ${name} 18 | ${children?` 19 |
        21 | ${bindHTML(children)} 22 |
      `:``} 23 |
    • `; 24 | count--; 25 | }); 26 | return str; 27 | }; 28 | $this.html(bindHTML(data)); 29 | 30 | //=>基于事件委托实现点击操作 31 | $this.click(function (ev) { 32 | let target = ev.target, 33 | $target = $(target), 34 | $next = $target.next('ul'); 35 | if (target.tagName === 'EM') { 36 | $target.toggleClass('open'); 37 | $next.stop().slideToggle(100); 38 | } 39 | }); 40 | } 41 | 42 | $.fn.extend({ 43 | ztree: ztree 44 | }); 45 | }(jQuery); -------------------------------------------------------------------------------- /树形插件/递归数据绑定.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/树形插件/递归数据绑定.png -------------------------------------------------------------------------------- /瀑布流/1-定时器.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 定时器 7 | 8 | 9 | 10 | 11 | 12 | 13 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /瀑布流/2-函数的防抖和节流.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 函数的防抖和节流 7 | 8 | 9 | 16 | 17 | 18 | 19 | 20 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /瀑布流/css/index.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | background: #E4E4E4; 4 | overflow-x: hidden; 5 | } 6 | 7 | .container { 8 | box-sizing: border-box; 9 | margin: 20px auto; 10 | width: 1000px; 11 | /* display: flex; 基于FLEX实现水平排列,里面的每一项都会保持相同的高度,其中某一项变高,其余所有的项也都跟着变高 */ 12 | } 13 | 14 | .container .column { 15 | box-sizing: border-box; 16 | float: left; 17 | margin-right: 20px; 18 | width: 320px; 19 | } 20 | 21 | .container .column:nth-last-child(1) { 22 | margin-right: 0; 23 | } 24 | 25 | .container .column .item { 26 | display: block; 27 | padding: 10px; 28 | margin-bottom: 10px; 29 | background: #FFF; 30 | box-shadow: 3px 3px 10px #666; 31 | } 32 | 33 | .container .column .item .imgBox { 34 | /* height: 300px; 想要实现图片延迟加载,这块显示默认占位图,事先需要知道图片的高度(从服务获取的数据中有图片高度) */ 35 | background: url("../img/default.gif") no-repeat center center #EEE; 36 | overflow: hidden; 37 | } 38 | 39 | .container .column .item .imgBox img { 40 | display: none; 41 | width: 100%; 42 | } 43 | 44 | .container .column .item p { 45 | margin-top: 10px; 46 | font-size: 12px; 47 | color: #555; 48 | line-height: 20px; 49 | } -------------------------------------------------------------------------------- /瀑布流/css/reset.min.css: -------------------------------------------------------------------------------- 1 | body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,button,input,textarea,th,td{margin:0;padding:0}body{font-size:12px;font-style:normal;font-family:"\5FAE\8F6F\96C5\9ED1",Helvetica,sans-serif}small{font-size:12px}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4,h5,h6{font-size:100%}ul,ol{list-style:none}a{text-decoration:none;background-color:transparent}a:hover,a:active{outline-width:0;text-decoration:none}table{border-collapse:collapse;border-spacing:0}hr{border:0;height:1px}img{border-style:none}img:not([src]){display:none}svg:not(:root){overflow:hidden}html{-webkit-touch-callout:none;-webkit-text-size-adjust:100%}input,textarea,button,a{-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]),video:not([controls]){display:none;height:0}progress{vertical-align:baseline}mark{background-color:#ff0;color:#000}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}button,input,select,textarea{font-size:100%;outline:0}button,input{overflow:visible}button,select{text-transform:none}textarea{overflow:auto}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.clearfix:after{display:block;height:0;content:"";clear:both} -------------------------------------------------------------------------------- /瀑布流/flex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 27 | 28 | 29 | 30 |
      31 |
      呵呵呵
      32 |
      哈哈哈
      33 |
      34 | 35 | 36 | -------------------------------------------------------------------------------- /瀑布流/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/1.jpg -------------------------------------------------------------------------------- /瀑布流/img/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/10.jpg -------------------------------------------------------------------------------- /瀑布流/img/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/11.jpg -------------------------------------------------------------------------------- /瀑布流/img/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/12.jpg -------------------------------------------------------------------------------- /瀑布流/img/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/13.jpg -------------------------------------------------------------------------------- /瀑布流/img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/2.jpg -------------------------------------------------------------------------------- /瀑布流/img/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/3.jpg -------------------------------------------------------------------------------- /瀑布流/img/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/4.jpg -------------------------------------------------------------------------------- /瀑布流/img/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/5.jpg -------------------------------------------------------------------------------- /瀑布流/img/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/6.jpg -------------------------------------------------------------------------------- /瀑布流/img/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/7.jpg -------------------------------------------------------------------------------- /瀑布流/img/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/8.jpg -------------------------------------------------------------------------------- /瀑布流/img/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/9.jpg -------------------------------------------------------------------------------- /瀑布流/img/default.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/img/default.gif -------------------------------------------------------------------------------- /瀑布流/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 花瓣网瀑布流效果 7 | 8 | 9 | 10 | 11 | 12 | 13 |
      14 | 15 |
      16 | 17 | 23 |
      24 |
      25 |
      26 |
      27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /瀑布流/js/index-BT.js: -------------------------------------------------------------------------------- 1 | let flowModule = (function () { 2 | let _DATA = null, 3 | $columns = $('.card-columns'), 4 | $window = $(window), 5 | $imgBoxs = null; 6 | 7 | //=>queryData:从服务器获取数据 8 | function queryData() { 9 | $.ajax({ 10 | url: 'json/data.json', 11 | method: 'GET', 12 | async: false, 13 | success: result => _DATA = result 14 | }); 15 | } 16 | 17 | //=>bindHTML:实现数据绑定 18 | function bindHTML() { 19 | let str = ``; 20 | _DATA.forEach(item => { 21 | let { 22 | pic, 23 | title, 24 | width, 25 | height 26 | } = item; 27 | str += `
      28 |
      29 | 30 |
      31 |
      32 |

      ${title}

      33 |
      34 |
      `; 35 | }); 36 | //=>不是$columns.html(str),因为此方法会把之前的内容也覆盖掉 37 | $columns.append(str); 38 | //=>计算每一个IMG-BOX的高度:IMG-BOX的宽度/图片真实宽度*图片的高度 39 | $imgBoxs = $columns.find('.myImgBox'); 40 | $imgBoxs.each((index, item) => { 41 | let $item = $(item); 42 | $item.css({ 43 | height: $item.innerWidth() / $item.attr('imgW') * $item.attr('imgH') 44 | }); 45 | }); 46 | } 47 | 48 | //=>lazyImgs:实现图片延迟加载 49 | function lazyImgs() { 50 | let B = $window.outerHeight() + $window.scrollTop(); 51 | $imgBoxs.filter("[isLoad!='TRUE']").each((index, item) => { 52 | let $item = $(item), 53 | $img = $item.children('img'), 54 | A = $item.offset().top + $item.outerHeight() / 2; 55 | if (A <= B) { 56 | //=>加载真实图片 57 | $item.attr('isLoad', 'TRUE'); 58 | $img.attr('src', $img.attr('data-img')).on('load', () => { 59 | $img.stop().fadeIn(300); 60 | }); 61 | } 62 | }); 63 | } 64 | 65 | //=>loadMore:实现加载更多数据 66 | function loadMore() { 67 | //=>真实页面的高度 <= 一屏幕高度+卷去的高度+300 68 | //$(document).height() <=> document.documentElement.scrollHeight 69 | let pageH = $(document).height(), 70 | winH = $window.outerHeight(), 71 | scrollT = $window.scrollTop(); 72 | if (pageH <= winH + scrollT + 300) { 73 | //=>加载更多数据 74 | queryData(); 75 | bindHTML(); 76 | setTimeout(lazyImgs, 500); 77 | } 78 | } 79 | 80 | return { 81 | init() { 82 | //=>首次加载页面 83 | queryData(); 84 | bindHTML(); 85 | setTimeout(lazyImgs, 500); 86 | //=>页面滚动期间,加载真实的图片和加载更多的数据 87 | window.onscroll = function () { 88 | lazyImgs(); 89 | loadMore(); 90 | } 91 | } 92 | } 93 | })(); 94 | flowModule.init(); -------------------------------------------------------------------------------- /瀑布流/js/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * debounce:函数防抖 3 | * @params 4 | * func:要执行的函数 5 | * wait:间隔等待时间 6 | * immediate:在开始边界还是结束边界触发执行(TRUE=>在开始边界) 7 | * @return 8 | * 可被调用的函数 9 | * by zhufengpeixun on 2019/08/21 10 | */ 11 | function debounce(func, wait, immediate) { 12 | let result = null, 13 | timeout = null; 14 | return function (...args) { 15 | let context = this, 16 | now = immediate && !timeout; 17 | clearTimeout(timeout); //=>重要:在设置新的定时器之前,我们要把之前设置的定时器都干掉,因为防抖的目的是等待时间内,只执行一次 18 | timeout = setTimeout(() => { 19 | timeout = null; 20 | if (!immediate) result = func.call(context, ...args); 21 | }, wait); 22 | if (now) result = func.call(context, ...args); 23 | return result; 24 | } 25 | } 26 | 27 | let flowModule = (function () { 28 | let $columns = $('.column'), 29 | _DATA = null; 30 | 31 | //=>queryData:基于AJAX从服务器获取数据 32 | let queryData = function () { 33 | $.ajax({ 34 | url: 'json/data.json', 35 | method: 'GET', 36 | async: false, 37 | success: result => { 38 | _DATA = result; 39 | } 40 | }); 41 | }; 42 | 43 | //=>bindHTML:实现页面中的数据绑定 44 | let bindHTML = function () { 45 | //=>瀑布流实现的原理:每一次从_DATA中取出三条数据,按照三列由矮到高的顺序依次插入 46 | for (let i = 0; i < _DATA.length; i += 3) { 47 | //=>把数据按照图片由高到低排序 48 | let group = _DATA.slice(i, i + 3); 49 | if (i !== 0) { 50 | group.sort((A, B) => B.height - A.height); 51 | } 52 | 53 | //=>先按照高度排序(升序) 54 | $columns.sort((A, B) => { 55 | //=>A/B原生JS元素对象,想要使用JQ的方法,需要转换为JQ对象 56 | let $A = $(A), 57 | $B = $(B); 58 | return $A.outerHeight() - $B.outerHeight(); 59 | }).each((index, column) => { 60 | //=>_DATA[i+index] 计算出要往每一列中插入的数据 61 | // let dataItem = _DATA[i + index]; 62 | let dataItem = group[index]; 63 | //=>没有数据,说明数据都已经处理完了,我们结束循环 64 | if (!dataItem) return false; 65 | let { 66 | pic, 67 | height, 68 | title, 69 | link 70 | } = dataItem; 71 | $(column).append(` 72 |
      73 | 74 |
      75 |

      ${title}

      76 |
      `); 77 | }); 78 | } 79 | 80 | //=>实现图片延迟加载:数据绑定完,延迟1000MS加载真实的图片 81 | setTimeout(lazyImgs, 1000); 82 | }; 83 | 84 | //=>lazyImgs:图片延迟加载 85 | let lazyImgs = function () { 86 | let $imgBoxs = $('.container .imgBox[isLoad!="true"]'), 87 | $window = $(window), 88 | B = $window.outerHeight() + $window.scrollTop(); 89 | //=>循环每一个图片(图片盒子),计算其底边距离BODY的偏移,从而验证出是否加载真实图片 90 | $imgBoxs.each((index, imgBox) => { 91 | let $imgBox = $(imgBox), 92 | $img = $imgBox.children('img'), 93 | A = $imgBox.outerHeight() + $imgBox.offset().top; 94 | // if ($imgBox.attr('isLoad') === "true") return; 95 | if (A <= B) { 96 | //=>加载真实图片 97 | $imgBox.attr('isLoad', 'true'); 98 | $img.attr('src', $img.attr('data-img')); 99 | $img.on('load', () => { 100 | // $img.css('display', 'block'); //=>直接显示 101 | $img.stop().fadeIn(); //=>基于JQ动画渐现显示 102 | }); 103 | } 104 | }); 105 | }; 106 | 107 | //=>loadMore:加载更多数据 108 | let loadMore = function () { 109 | //=>滚动到底端(一屏幕高度+卷去的高度+500>=页面真实的高度),加载更多数据 110 | let $window = $(window), 111 | winH = $window.outerHeight(), 112 | scrollT = $window.scrollTop(), 113 | pageH = $(document).height(); 114 | if (winH + scrollT + 500 >= pageH) { 115 | queryData(); 116 | bindHTML(); 117 | } 118 | }; 119 | 120 | return { 121 | init: function () { 122 | queryData(); 123 | bindHTML(); 124 | 125 | //=>滚动条滚动处理一些事情 126 | window.onscroll = _.throttle(function () { 127 | //=>延迟加载图片 128 | lazyImgs(); 129 | //=>加载更多数据 130 | loadMore(); 131 | }, 50); 132 | } 133 | } 134 | })(); 135 | flowModule.init(); -------------------------------------------------------------------------------- /瀑布流/json/data.json: -------------------------------------------------------------------------------- 1 | [{"id":1,"pic":"img/6.jpg","width":300,"height":400,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":2,"pic":"img/10.jpg","width":300,"height":257,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":3,"pic":"img/11.jpg","width":300,"height":408,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":4,"pic":"img/2.jpg","width":300,"height":300,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":5,"pic":"img/10.jpg","width":300,"height":257,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":6,"pic":"img/4.jpg","width":300,"height":451,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":7,"pic":"img/4.jpg","width":300,"height":451,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":8,"pic":"img/12.jpg","width":300,"height":225,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":9,"pic":"img/11.jpg","width":300,"height":408,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":10,"pic":"img/7.jpg","width":300,"height":200,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":11,"pic":"img/3.jpg","width":300,"height":170,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":12,"pic":"img/6.jpg","width":300,"height":400,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":13,"pic":"img/4.jpg","width":300,"height":451,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":14,"pic":"img/13.jpg","width":300,"height":188,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":15,"pic":"img/6.jpg","width":300,"height":400,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":16,"pic":"img/13.jpg","width":300,"height":188,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":17,"pic":"img/3.jpg","width":300,"height":170,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":18,"pic":"img/10.jpg","width":300,"height":257,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":19,"pic":"img/5.jpg","width":300,"height":200,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":20,"pic":"img/4.jpg","width":300,"height":451,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":21,"pic":"img/7.jpg","width":300,"height":200,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":22,"pic":"img/2.jpg","width":300,"height":300,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":23,"pic":"img/1.jpg","width":300,"height":534,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":24,"pic":"img/3.jpg","width":300,"height":170,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":25,"pic":"img/4.jpg","width":300,"height":451,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":26,"pic":"img/3.jpg","width":300,"height":170,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":27,"pic":"img/3.jpg","width":300,"height":170,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":28,"pic":"img/6.jpg","width":300,"height":400,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":29,"pic":"img/5.jpg","width":300,"height":200,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":30,"pic":"img/1.jpg","width":300,"height":534,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":31,"pic":"img/2.jpg","width":300,"height":300,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":32,"pic":"img/4.jpg","width":300,"height":451,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":33,"pic":"img/1.jpg","width":300,"height":534,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":34,"pic":"img/11.jpg","width":300,"height":408,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":35,"pic":"img/2.jpg","width":300,"height":300,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":36,"pic":"img/12.jpg","width":300,"height":225,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":37,"pic":"img/11.jpg","width":300,"height":408,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":38,"pic":"img/10.jpg","width":300,"height":257,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":39,"pic":"img/12.jpg","width":300,"height":225,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":40,"pic":"img/2.jpg","width":300,"height":300,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":41,"pic":"img/3.jpg","width":300,"height":170,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":42,"pic":"img/10.jpg","width":300,"height":257,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":43,"pic":"img/4.jpg","width":300,"height":451,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":44,"pic":"img/4.jpg","width":300,"height":451,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":45,"pic":"img/9.jpg","width":300,"height":433,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":46,"pic":"img/4.jpg","width":300,"height":451,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":47,"pic":"img/11.jpg","width":300,"height":408,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":48,"pic":"img/2.jpg","width":300,"height":300,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":49,"pic":"img/10.jpg","width":300,"height":257,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"},{"id":50,"pic":"img/2.jpg","width":300,"height":300,"title":"泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证","link":"https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89"}] -------------------------------------------------------------------------------- /瀑布流/json/mocData.js: -------------------------------------------------------------------------------- 1 | let fs = require('fs'), 2 | ary = []; 3 | for (let i = 1; i <= 50; i++) { 4 | let ran = Math.round(Math.random() * 12 + 1), 5 | area = [534, 300, 170, 451, 200, 400, 200, 400, 433, 257, 408, 225, 188]; 6 | ary.push({ 7 | id: i, 8 | pic: `img/${ran}.jpg`, 9 | width: 300, 10 | height: area[ran - 1], 11 | title: '泰勒·斯威夫特(Taylor Swift),1989年12月13日出生于美国宾州,美国歌手、演员。2006年出道,同年发行专辑《泰勒·斯威夫特》,该专辑获得美国唱片业协会的白金唱片认证', 12 | link: 'https://baike.sogou.com/v1850208.htm?fromTitle=%E9%9C%89%E9%9C%89' 13 | }); 14 | } 15 | 16 | fs.writeFileSync('./data.json', JSON.stringify(ary), 'utf-8'); -------------------------------------------------------------------------------- /瀑布流/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "underscore": { 6 | "version": "1.5.1", 7 | "resolved": "https://registry.npm.taobao.org/underscore/download/underscore-1.5.1.tgz", 8 | "integrity": "sha1-0r3oF9F2/63olKtxRY5oKhS4bck=" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /瀑布流/瀑布流-图片加载问题.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/瀑布流-图片加载问题.png -------------------------------------------------------------------------------- /瀑布流/瀑布流.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/瀑布流/瀑布流.png -------------------------------------------------------------------------------- /腾讯视频/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependency directories 2 | video/ -------------------------------------------------------------------------------- /腾讯视频/css/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | .wrap { 6 | width: 1080px; 7 | height: 608px; 8 | margin: 200px auto; 9 | } -------------------------------------------------------------------------------- /腾讯视频/css/video.css: -------------------------------------------------------------------------------- 1 | .msw-video div { 2 | box-sizing: border-box; 3 | } 4 | 5 | .msw-video p, 6 | .msw-video h1, 7 | .msw-video h2, 8 | .msw-video h3, 9 | .msw-video h4, 10 | .msw-video h5, 11 | .msw-video h6 { 12 | font-weight: normal; 13 | margin: 0; 14 | } 15 | 16 | .msw-video a { 17 | text-decoration: none; 18 | } 19 | 20 | .msw-video ul { 21 | padding: 0; 22 | margin: 0; 23 | list-style: none; 24 | } 25 | 26 | .msw-video img { 27 | width: 100%; 28 | } 29 | 30 | .msw-video video { 31 | width: 100%; 32 | height: 100%; 33 | } 34 | 35 | .msw-video { 36 | position: relative; 37 | width: 100%; 38 | height: 100%; 39 | background-color: #000; 40 | overflow: hidden; 41 | } 42 | 43 | .msw-video .vid-hd { 44 | position: absolute; 45 | top: 0; 46 | left: 0; 47 | width: 100%; 48 | height: 50px; 49 | background-color: rgba(0, 0, 0, .3); 50 | color: #fff; 51 | line-height: 50px; 52 | padding: 0 15px; 53 | font-size: 18px; 54 | transition: top .5s; 55 | } 56 | 57 | .msw-video .vid-hd.hide { 58 | top: -50px; 59 | } 60 | 61 | .msw-video .control-bar { 62 | position: absolute; 63 | bottom: 0; 64 | left: 0; 65 | width: 100%; 66 | height: 50px; 67 | background-color: #000; 68 | border-top: 1px solid #333; 69 | transition: bottom .5s; 70 | } 71 | 72 | .msw-video .control-bar.hide { 73 | bottom: -47px; 74 | } 75 | 76 | .msw-video .control-bar .progress-bar { 77 | position: absolute; 78 | top: -3px; 79 | left: 0; 80 | width: 100%; 81 | height: 5px; 82 | background-color: #595959; 83 | cursor: pointer; 84 | transition: all .2s; 85 | } 86 | 87 | .msw-video .control-bar .progress-bar:hover { 88 | top: -6px; 89 | height: 8px; 90 | } 91 | 92 | .msw-video .control-bar .progress-bar .play-progress { 93 | position: absolute; 94 | top: 0; 95 | left: 0; 96 | z-index: 2; 97 | width: 0; 98 | height: 100%; 99 | background-color: #ed6d3d; 100 | } 101 | 102 | .msw-video .control-bar .progress-bar .play-progress .round { 103 | position: absolute; 104 | top: -2px; 105 | right: -6px; 106 | width: 12px; 107 | height: 12px; 108 | background-color: #ed6d3d; 109 | border-radius: 50%; 110 | opacity: 0; 111 | transition: all .3s; 112 | cursor: pointer; 113 | } 114 | 115 | .msw-video .control-bar .progress-bar .play-progress .round::before { 116 | content: ""; 117 | display: block; 118 | position: absolute; 119 | top: -4px; 120 | left: -4px; 121 | width: 20px; 122 | height: 20px; 123 | background-color: #ed6d3d; 124 | border-radius: 50%; 125 | opacity: .4; 126 | } 127 | 128 | .msw-video .control-bar .progress-bar:hover .round { 129 | opacity: 1; 130 | } 131 | 132 | .msw-video .control-bar .progress-bar .preload-progress { 133 | position: absolute; 134 | top: 0; 135 | left: 0; 136 | z-index: 1; 137 | width: 0; 138 | height: 100%; 139 | background-color: #999; 140 | } 141 | 142 | .msw-video .control-bar .play-btn-area { 143 | float: left; 144 | width: 50px; 145 | height: 50px; 146 | padding: 13px; 147 | } 148 | 149 | .msw-video .control-bar .time-area { 150 | float: left; 151 | height: 50px; 152 | padding: 0 10px; 153 | color: #fff; 154 | line-height: 50px; 155 | font-size: 12px; 156 | } 157 | 158 | .msw-video .control-bar .time-area .duration { 159 | color: #999; 160 | } 161 | 162 | .msw-video .control-bar .playrate-area { 163 | position: relative; 164 | float: right; 165 | height: 50px; 166 | padding: 0 15px; 167 | } 168 | 169 | .msw-video .control-bar .playrate-area .playrate { 170 | display: block; 171 | width: 50px; 172 | height: 30px; 173 | margin-top: 10px; 174 | font-size: 14px; 175 | line-height: 30px; 176 | text-align: center; 177 | color: #fff; 178 | border-radius: 15px; 179 | } 180 | 181 | .msw-video .control-bar .playrate-area .playrate:hover { 182 | background-color: #ed6d3d; 183 | } 184 | 185 | .msw-video .control-bar .playrate-area .playrate-list { 186 | display: none; 187 | position: absolute; 188 | left: 15px; 189 | top: -198px; 190 | width: 50px; 191 | background-color: rgba(0, 0, 0, .7); 192 | } 193 | 194 | .msw-video .control-bar .playrate-area .playrate-list.show { 195 | display: block; 196 | } 197 | 198 | .msw-video .control-bar .playrate-area .playrate-list .item { 199 | height: 40px; 200 | } 201 | 202 | .msw-video .control-bar .playrate-area .playrate-list .rate-btn { 203 | display: block; 204 | height: 100%; 205 | text-align: center; 206 | line-height: 40px; 207 | color: #fff; 208 | font-size: 14px; 209 | } 210 | 211 | .msw-video .control-bar .playrate-area .playrate-list .rate-btn.current { 212 | color: #ed6d3d; 213 | } 214 | 215 | .msw-video .control-bar .volume-area { 216 | position: relative; 217 | float: right; 218 | width: 50px; 219 | height: 50px; 220 | padding: 13px; 221 | } 222 | 223 | .msw-video .control-bar .volume-area .volume-bar { 224 | z-index:10; 225 | display: none; 226 | position: absolute; 227 | left: 0; 228 | top : -118px; 229 | width: 50px; 230 | height: 120px; 231 | padding: 12px 0; 232 | background-color: rgba(0, 0, 0, .7); 233 | } 234 | 235 | .msw-video .control-bar .volume-area .volume-bar.show { 236 | display: block; 237 | } 238 | 239 | .msw-video .control-bar .volume-area .volume-bar span { 240 | display: block; 241 | } 242 | 243 | .msw-video .control-bar .volume-area .volume-bar .slide-bar { 244 | position: relative; 245 | width: 5px; 246 | height: 96px; 247 | margin-left: 22px; 248 | background-color: #595959; 249 | border-radius: 2px; 250 | } 251 | 252 | .msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide { 253 | position: absolute; 254 | bottom: 0; 255 | left: 0; 256 | width: 5px; 257 | height: 100%; 258 | background-color: #ed6d3d; 259 | border-radius: 2px; 260 | } 261 | 262 | .msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide .round { 263 | display: block; 264 | position: absolute; 265 | top: -4px; 266 | left: -2px; 267 | width: 9px; 268 | height: 9px; 269 | background-color: #fff; 270 | border-radius: 50%; 271 | box-shadow: 0 0 2px #ed6d3d; 272 | cursor: pointer; 273 | } 274 | 275 | .msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide .round::before { 276 | content: ""; 277 | display: none; 278 | position: absolute; 279 | top: -3px; 280 | left: -3px; 281 | width: 15px; 282 | height: 15px; 283 | background-color: #ed6d3d; 284 | border-radius: 50%; 285 | opacity: .4; 286 | } 287 | 288 | .msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide .round:hover::before { 289 | display: block; 290 | } 291 | 292 | .msw-video .control-bar .fullscreen-area { 293 | float: right; 294 | width: 50px; 295 | height: 50px; 296 | } 297 | 298 | .msw-video .control-bar .fullscreen-area .fullscreen-btn { 299 | display: block; 300 | width: 18px; 301 | height: 18px; 302 | margin: 16px 0 0 15px; 303 | } 304 | 305 | .msw-video .video-tip { 306 | position: absolute; 307 | top: 50%; 308 | left: 50%; 309 | margin: -50px 0 0 -50px; 310 | width: 100px; 311 | height: 100px; 312 | background-color: rgba(0, 0, 0, .3); 313 | border-radius: 10px; 314 | color: #fff; 315 | text-align: center; 316 | font-size: 14px; 317 | } 318 | 319 | .msw-video .video-tip img { 320 | width: 50px; 321 | height: 50px; 322 | margin-top: 10px; 323 | } 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | -------------------------------------------------------------------------------- /腾讯视频/css/video.min.css: -------------------------------------------------------------------------------- 1 | .msw-video div{box-sizing:border-box}.msw-video h1,.msw-video h2,.msw-video h3,.msw-video h4,.msw-video h5,.msw-video h6,.msw-video p{font-weight:400;margin:0}.msw-video a{text-decoration:none}.msw-video ul{padding:0;margin:0;list-style:none}.msw-video img{width:100%}.msw-video video{width:100%;height:100%}.msw-video{position:relative;width:100%;height:100%;background-color:#000;overflow:hidden}.msw-video .vid-hd{position:absolute;top:0;left:0;width:100%;height:50px;background-color:rgba(0,0,0,.3);color:#fff;line-height:50px;padding:0 15px;font-size:18px;transition:top .5s}.msw-video .vid-hd.hide{top:-50px}.msw-video .control-bar{position:absolute;bottom:0;left:0;width:100%;height:50px;background-color:#000;border-top:1px solid #333;transition:bottom .5s}.msw-video .control-bar.hide{bottom:-47px}.msw-video .control-bar .progress-bar{position:absolute;top:-3px;left:0;width:100%;height:5px;background-color:#595959;cursor:pointer;transition:all .2s}.msw-video .control-bar .progress-bar:hover{top:-6px;height:8px}.msw-video .control-bar .progress-bar .play-progress{position:absolute;top:0;left:0;z-index:2;width:0;height:100%;background-color:#ed6d3d}.msw-video .control-bar .progress-bar .play-progress .round{position:absolute;top:-2px;right:-6px;width:12px;height:12px;background-color:#ed6d3d;border-radius:50%;opacity:0;transition:all .3s;cursor:pointer}.msw-video .control-bar .progress-bar .play-progress .round::before{content:"";display:block;position:absolute;top:-4px;left:-4px;width:20px;height:20px;background-color:#ed6d3d;border-radius:50%;opacity:.4}.msw-video .control-bar .progress-bar:hover .round{opacity:1}.msw-video .control-bar .progress-bar .preload-progress{position:absolute;top:0;left:0;z-index:1;width:0;height:100%;background-color:#999}.msw-video .control-bar .play-btn-area{float:left;width:50px;height:50px;padding:13px}.msw-video .control-bar .time-area{float:left;height:50px;padding:0 10px;color:#fff;line-height:50px;font-size:12px}.msw-video .control-bar .time-area .duration{color:#999}.msw-video .control-bar .playrate-area{position:relative;float:right;height:50px;padding:0 15px}.msw-video .control-bar .playrate-area .playrate{display:block;width:50px;height:30px;margin-top:10px;font-size:14px;line-height:30px;text-align:center;color:#fff;border-radius:15px}.msw-video .control-bar .playrate-area .playrate:hover{background-color:#ed6d3d}.msw-video .control-bar .playrate-area .playrate-list{display:none;position:absolute;left:15px;top:-198px;width:50px;background-color:rgba(0,0,0,.7)}.msw-video .control-bar .playrate-area .playrate-list.show{display:block}.msw-video .control-bar .playrate-area .playrate-list .item{height:40px}.msw-video .control-bar .playrate-area .playrate-list .rate-btn{display:block;height:100%;text-align:center;line-height:40px;color:#fff;font-size:14px}.msw-video .control-bar .playrate-area .playrate-list .rate-btn.current{color:#ed6d3d}.msw-video .control-bar .volume-area{position:relative;float:right;width:50px;height:50px;padding:13px}.msw-video .control-bar .volume-area .volume-bar{display:none;position:absolute;left:0;top:-118px;width:50px;height:120px;padding:12px 0;background-color:rgba(0,0,0,.7)}.msw-video .control-bar .volume-area .volume-bar.show{display:block}.msw-video .control-bar .volume-area .volume-bar span{display:block}.msw-video .control-bar .volume-area .volume-bar .slide-bar{position:relative;width:5px;height:96px;margin-left:22px;background-color:#595959;border-radius:2px}.msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide{position:absolute;bottom:0;left:0;width:5px;height:100%;background-color:#ed6d3d;border-radius:2px}.msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide .round{display:block;position:absolute;top:-4px;left:-2px;width:9px;height:9px;background-color:#fff;border-radius:50%;box-shadow:0 0 2px #ed6d3d;cursor:pointer}.msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide .round::before{content:"";display:none;position:absolute;top:-3px;left:-3px;width:15px;height:15px;background-color:#ed6d3d;border-radius:50%;opacity:.4}.msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide .round:hover::before{display:block}.msw-video .control-bar .fullscreen-area{float:right;width:50px;height:50px}.msw-video .control-bar .fullscreen-area .fullscreen-btn{display:block;width:18px;height:18px;margin:16px 0 0 15px}.msw-video .video-tip{position:absolute;top:50%;left:50%;margin:-50px 0 0 -50px;width:100px;height:100px;background-color:rgba(0,0,0,.3);border-radius:10px;color:#fff;text-align:center;font-size:14px}.msw-video .video-tip img{width:50px;height:50px;margin-top:10px} -------------------------------------------------------------------------------- /腾讯视频/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | videojs 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 38 | 39 | -------------------------------------------------------------------------------- /腾讯视频/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/.DS_Store -------------------------------------------------------------------------------- /腾讯视频/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/1.jpg -------------------------------------------------------------------------------- /腾讯视频/img/ended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/ended.png -------------------------------------------------------------------------------- /腾讯视频/img/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/error.png -------------------------------------------------------------------------------- /腾讯视频/img/fullscreen-exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/fullscreen-exit.png -------------------------------------------------------------------------------- /腾讯视频/img/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/fullscreen.png -------------------------------------------------------------------------------- /腾讯视频/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/loading.gif -------------------------------------------------------------------------------- /腾讯视频/img/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/pause.png -------------------------------------------------------------------------------- /腾讯视频/img/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/play.png -------------------------------------------------------------------------------- /腾讯视频/img/volume-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/volume-off.png -------------------------------------------------------------------------------- /腾讯视频/img/volume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/img/volume.png -------------------------------------------------------------------------------- /腾讯视频/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 视频播放器 6 | 7 | 8 | 9 | 10 | 11 |
      12 |
      13 |
      14 | 17 |
      18 |
      19 |

      事件代理机制详解

      20 |
      21 |
      22 |
      23 |
      24 | 25 |
      26 |
      27 |
      28 |
      29 | 30 | 31 | 32 |
      33 |
      34 | 00:00:00 / 00:00:00 35 |
      36 |
      37 | 38 | 39 | 40 |
      41 |
      42 | 43 | 44 | 45 |
      46 | 47 | 48 | 49 | 50 | 51 |
      52 |
      53 |
      54 | 倍速 55 | 62 |
      63 |
      64 |
      65 |
      66 | 67 | 68 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /腾讯视频/js/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/js/.DS_Store -------------------------------------------------------------------------------- /腾讯视频/js/video.js: -------------------------------------------------------------------------------- 1 | ;(function (doc) { 2 | var t = null, 3 | dt = null, 4 | pt = null; 5 | 6 | var MswVideo = function (dom, opt) { 7 | this.videoBox = doc.getElementById(dom); 8 | this.vid = this.videoBox.getElementsByClassName('video-tag')[0]; 9 | this.oPlayBtn = this.videoBox.getElementsByClassName('play-img')[0]; 10 | this.oCurrentTime = this.videoBox.getElementsByClassName('current-time')[0]; 11 | this.oDuration = this.videoBox.getElementsByClassName('duration')[0]; 12 | this.oRateArea = this.videoBox.getElementsByClassName('playrate-area')[0]; 13 | this.oRateBtn = this.oRateArea.getElementsByClassName('playrate')[0]; 14 | this.oRateList = this.oRateArea.getElementsByClassName('playrate-list')[0]; 15 | this.oRateBtns = this.oRateList.getElementsByClassName('item'); 16 | this.oVolumeArea = this.videoBox.getElementsByClassName('volume-area')[0]; 17 | this.oVolumeBtn = this.oVolumeArea.getElementsByClassName('volume-img')[0]; 18 | this.oVolumeBar = this.oVolumeArea.getElementsByClassName('volume-bar')[0]; 19 | this.oVolumeSlideBar = this.oVolumeBar.getElementsByClassName('slide-bar')[0]; 20 | this.oVolumeSlider = this.oVolumeBar.getElementsByClassName('volume-slide')[0]; 21 | this.oVolumeRound = this.oVolumeSlider.getElementsByClassName('round')[0]; 22 | this.oFullscreenBtn = this.videoBox.getElementsByClassName('fullscreen-img')[0]; 23 | this.oVidHeader = this.videoBox.getElementsByClassName('vid-hd')[0]; 24 | this.oControlBar = this.videoBox.getElementsByClassName('control-bar')[0]; 25 | this.oProgressBar = this.videoBox.getElementsByClassName('progress-bar')[0]; 26 | this.oPlayProgress = this.oProgressBar.getElementsByClassName('play-progress')[0]; 27 | this.oPreloadProgress = this.oProgressBar.getElementsByClassName('preload-progress')[0]; 28 | this.oPlayRound = this.oPlayProgress.getElementsByClassName('round')[0]; 29 | 30 | this.oRateBtnsLen = this.oRateBtns.length; 31 | 32 | this.src = opt.src; 33 | this.autoplay = opt.autoplay || false; 34 | this.preload = this.autoplay ? false : (opt.preload || false); 35 | this.volume = opt.volume / 100 || 1; 36 | this.loop = opt.loop || false; 37 | 38 | this.muted = false; 39 | this.volumeBarShow = false; 40 | this.isFullScreen = false; 41 | 42 | this.init(); 43 | } 44 | 45 | MswVideo.prototype = { 46 | init: function () { 47 | this.setOptions(); 48 | this.bindEvent(); 49 | this.autoplay && addVideoTip(this.videoBox, 'loading'); 50 | 51 | var _self = this; 52 | 53 | dt = setTimeout(function () { 54 | _self.setControlBar(true); 55 | }, 5000); 56 | }, 57 | 58 | bindEvent: function () { 59 | this.vid.addEventListener('canplay', this._canplay.bind(this), false); 60 | this.vid.addEventListener('playing', this._playing.bind(this), false); 61 | this.vid.addEventListener('waiting', this._waiting.bind(this), false); 62 | this.vid.addEventListener('error', this._error.bind(this), false); 63 | this.vid.addEventListener('ended', this._ended.bind(this), false); 64 | this.vid.addEventListener('loadstart', this._loadstart.bind(this), false); 65 | 66 | this.oPlayBtn.addEventListener('click', this.playVideo.bind(this), false); 67 | this.oRateBtn.addEventListener('click', this.showRateList.bind(this, true), false); 68 | this.oRateArea.addEventListener('mouseleave', this.showRateList.bind(this, false), false); 69 | this.oRateList.addEventListener('click', this.setPlayRate.bind(this), false); 70 | this.oVolumeBtn.addEventListener('click', this.btnSetVolume.bind(this), false); 71 | this.oVolumeArea.addEventListener('mouseleave', this.showVolumeBar.bind(this, false), false); 72 | this.oVolumeRound.addEventListener('mousedown', this.slideVolumeBar.bind(this), false); 73 | this.oFullscreenBtn.addEventListener('click', this.setFullScreen.bind(this), false); 74 | this.videoBox.addEventListener('mousemove', this.showControlBar.bind(this), false); 75 | this.oProgressBar.addEventListener('click', this.progressClick.bind(this), false); 76 | this.oPlayRound.addEventListener('mousedown', this.progressChange.bind(this), false); 77 | 78 | }, 79 | 80 | setOptions: function () { 81 | this.vid.src = this.src; 82 | this.vid.autoplay = this.autoplay; 83 | this.vid.preload = this.preload; 84 | this.vid.loop = this.loop; 85 | this.setVolume(this.volume, true); 86 | }, 87 | 88 | playVideo: function () { 89 | if (this.vid.paused) { 90 | this.oPlayBtn.src = 'img/pause.png'; 91 | this.vid.play(); 92 | } else { 93 | this.oPlayBtn.src = 'img/play.png'; 94 | this.vid.pause(); 95 | } 96 | }, 97 | 98 | showRateList: function (show) { 99 | if (show) { 100 | this.oRateList.className += ' show'; 101 | } else { 102 | this.oRateList.className = 'playrate-list'; 103 | } 104 | }, 105 | 106 | setPlayRate: function (e) { 107 | var e = e || window.event, 108 | tar = e.target || e.srcElement, 109 | className = tar.className, 110 | rateBtn; 111 | 112 | if (className === 'rate-btn') { 113 | for (var i = 0; i < this.oRateBtnsLen; i++) { 114 | rateBtn = this.oRateBtns[i].getElementsByClassName('rate-btn')[0]; 115 | rateBtn.className = 'rate-btn'; 116 | } 117 | 118 | this.vid.playbackRate = tar.getAttribute('data-rate'); 119 | tar.className += ' current'; 120 | this.showRateList(false); 121 | } 122 | }, 123 | 124 | btnSetVolume: function () { 125 | if (!this.muted && !this.volumeBarShow) { 126 | this.showVolumeBar(true); 127 | } else if (!this.muted && this.volumeBarShow) { 128 | this.setMuted(true); 129 | this.setVolume(0, true); 130 | } else { 131 | this.setMuted(false); 132 | this.setVolume(this.volume, true); 133 | } 134 | }, 135 | 136 | showVolumeBar: function (show) { 137 | if (show) { 138 | this.oVolumeBar.className += ' show'; 139 | this.volumeBarShow = true; 140 | } else { 141 | this.oVolumeBar.className = 'volume-bar'; 142 | this.volumeBarShow = false; 143 | } 144 | }, 145 | 146 | setMuted: function (muted) { 147 | if (muted) { 148 | this.vid.muted = true; 149 | this.muted = true; 150 | this.oVolumeBtn.src = 'img/volume-off.png'; 151 | } else { 152 | this.vid.muted = false; 153 | this.muted = false; 154 | this.oVolumeBtn.src = 'img/volume.png'; 155 | } 156 | }, 157 | 158 | setVolume: function (volume, isChangeBar) { 159 | this.vid.volume = volume; 160 | isChangeBar && (this.oVolumeSlider.style.height = (volume * 100) + '%'); 161 | }, 162 | 163 | setFullScreen: function () { 164 | if (!this.isFullScreen) { 165 | if (this.videoBox.requestFullscreen) { 166 | this.videoBox.requestFullscreen(); 167 | } else if (this.videoBox.mozRequestFullscreen) { 168 | this.videoBox.mozRequestFullscreen(); 169 | } else if (this.videoBox.msRequestFullscreen) { 170 | this.videoBox.msRequestFullscreen(); 171 | } else if (this.videoBox.oRequestFullscreen) { 172 | this.videoBox.oRequestFullscreen(); 173 | } else if (this.videoBox.webkitRequestFullscreen) { 174 | this.videoBox.webkitRequestFullscreen(); 175 | } 176 | 177 | this.isFullScreen = true; 178 | this.oFullscreenBtn.src = 'img/fullscreen-exit.png'; 179 | } else { 180 | if (doc.exitFullscreen) { 181 | doc.exitFullscreen(); 182 | } else if (doc.mozExitFullscreen) { 183 | doc.mozExitFullscreen(); 184 | } else if (doc.msExitFullscreen) { 185 | doc.msExitFullscreen(); 186 | } else if (doc.oExitFullscreen) { 187 | doc.oExitFullscreen(); 188 | } else if (doc.webkitExitFullscreen) { 189 | doc.webkitExitFullscreen(); 190 | } 191 | 192 | this.isFullScreen = false; 193 | this.oFullscreenBtn.src = 'img/fullscreen.png'; 194 | } 195 | }, 196 | 197 | setVideoState: function (isPlaying) { 198 | this.oPlayBtn.src = isPlaying ? 'img/pause.png' : 'img/play.png'; 199 | }, 200 | 201 | setSrc: function (src) { 202 | this.vid.src = src; 203 | this.vid.load(); 204 | }, 205 | 206 | showControlBar: function () { 207 | clearTimeout(dt); 208 | dt = null; 209 | this.setControlBar(false); 210 | 211 | var _self = this; 212 | 213 | dt = setTimeout(function () { 214 | _self.setControlBar(true); 215 | }, 5000); 216 | }, 217 | 218 | setControlBar: function (hide) { 219 | if (hide) { 220 | this.oVidHeader.className += ' hide'; 221 | this.oControlBar.className += ' hide'; 222 | } else { 223 | this.oVidHeader.className = 'vid-hd'; 224 | this.oControlBar.className = 'control-bar'; 225 | } 226 | }, 227 | 228 | slideVolumeBar: function (e) { 229 | 230 | var e = e || window.event, 231 | dy = e.pageY, 232 | my = 0, 233 | disY = 0, 234 | sHeight = 0, 235 | slideHeight = this.oVolumeSlider.offsetHeight, 236 | volumeBarHeight = this.oVolumeSlideBar.offsetHeight, 237 | _mousemove = _mouseMove.bind(this), 238 | _mouseup = _mouseUp.bind(this); 239 | 240 | doc.addEventListener('mousemove', _mousemove, false); 241 | doc.addEventListener('mouseup', _mouseup, false); 242 | 243 | function _mouseMove (e) { 244 | var e = e || window.event; 245 | my = e.pageY; 246 | disY = dy - my; 247 | sHeight = slideHeight + disY; 248 | 249 | if (sHeight < volumeBarHeight && sHeight > 0) { 250 | this.oVolumeSlider.style.height = sHeight + 'px'; 251 | this.setMuted(false); 252 | } else if (sHeight >= volumeBarHeight) { 253 | this.oVolumeSlider.style.height = volumeBarHeight + 'px'; 254 | sHeight = volumeBarHeight; 255 | this.setMuted(false); 256 | } else if (sHeight <= 0) { 257 | this.oVolumeSlider.style.height = '0'; 258 | sHeight = 0; 259 | this.setMuted(true); 260 | } 261 | 262 | this.volume = (sHeight / volumeBarHeight).toFixed(1); 263 | this.setVolume(this.volume, false); 264 | this.volume = Number(this.volume) == 0 ? 0.5 : this.volume; 265 | } 266 | 267 | function _mouseUp () { 268 | doc.removeEventListener('mousemove', _mousemove, false); 269 | doc.removeEventListener('mouseup', _mouseup, false); 270 | } 271 | }, 272 | 273 | progressClick: function (e) { 274 | var e = e || window.event; 275 | this.setPlayProgress(e.pageX); 276 | }, 277 | 278 | progressChange: function () { 279 | var _mousemove = _mouseMove.bind(this), 280 | _mouseup = _mouseUp.bind(this); 281 | 282 | doc.addEventListener('mousemove', _mousemove, false); 283 | doc.addEventListener('mouseup', _mouseup, false); 284 | 285 | function _mouseMove (e) { 286 | var e = e || window.event; 287 | this.setPlayProgress(e.pageX); 288 | } 289 | 290 | function _mouseUp () { 291 | doc.removeEventListener('mousemove', _mousemove, false); 292 | doc.removeEventListener('mouseup', _mouseup, false); 293 | } 294 | }, 295 | 296 | setPlayProgress: function (pageX) { 297 | var duration = this.vid.duration, 298 | curProgressBarWidth = pageX - this.videoBox.offsetLeft, 299 | ratio = 0; 300 | 301 | if (curProgressBarWidth <= 0) { 302 | ratio = 0; 303 | } else if (curProgressBarWidth >= this.oProgressBar.offsetWidth) { 304 | ratio = 1; 305 | } else { 306 | ratio = curProgressBarWidth / this.oProgressBar.offsetWidth; 307 | } 308 | 309 | this.vid.currentTime = ratio * duration; 310 | setTime(this.oCurrentTime, this.vid.currentTime); 311 | this.setVideoState(true); 312 | this.vid.play(); 313 | this.oPlayProgress.style.width = ratio * 100 + '%'; 314 | }, 315 | 316 | _waiting: function () { 317 | addVideoTip(this.videoBox, 'loading'); 318 | }, 319 | 320 | _loadstart: function () { 321 | removeVideoTip(this.videoBox); 322 | addVideoTip(this.videoBox, 'loading'); 323 | }, 324 | 325 | _canplay: function () { 326 | setTime(this.oDuration, this.vid.duration); 327 | removeVideoTip(this.videoBox); 328 | 329 | var _self = this, 330 | duration = this.vid.duration, 331 | preloadProgress = 0, 332 | progressBarWidth = this.oProgressBar.offsetWidth; 333 | 334 | pt = setInterval(function () { 335 | preloadProgress = _self.vid.buffered.end(0); 336 | 337 | _self.oPreloadProgress.style.width = (_self.vid.buffered.end(0) / duration) * 100 + '%'; 338 | 339 | if (_self.oPreloadProgress.offsetWidth >= progressBarWidth) { 340 | clearInterval(pt); 341 | pt = null; 342 | } 343 | }, 1000); 344 | }, 345 | 346 | _playing: function () { 347 | this.setVideoState(true); 348 | removeVideoTip(this.videoBox); 349 | 350 | var _self = this, 351 | duration = this.vid.duration, 352 | currentTime = 0, 353 | progressBarWidth = this.oProgressBar.offsetWidth; 354 | 355 | t = setInterval(function () { 356 | currentTime = _self.vid.currentTime; 357 | 358 | setTime(_self.oCurrentTime, currentTime); 359 | _self.oPlayProgress.style.width = (currentTime / duration) * 100 + '%'; 360 | 361 | if (_self.oPlayProgress.offsetWidth >= progressBarWidth) { 362 | clearInterval(t); 363 | t = null; 364 | } 365 | }, 1000); 366 | }, 367 | 368 | _error: function () { 369 | removeVideoTip(this.videoBox); 370 | addVideoTip(this.videoBox, 'error'); 371 | clearInterval(t); 372 | clearInterval(pt); 373 | t = null; 374 | pt = null; 375 | }, 376 | 377 | _ended: function () { 378 | removeVideoTip(this.videoBox); 379 | addVideoTip(this.videoBox, 'ended'); 380 | } 381 | } 382 | 383 | function setTime (dom, time) { 384 | dom.innerText = timeFormat(time); 385 | } 386 | 387 | function addVideoTip (dom, type) { 388 | var icon = '', 389 | text = ''; 390 | 391 | switch (type) { 392 | case 'loading': 393 | icon = 'img/loading.gif'; 394 | text = '加载中'; 395 | break; 396 | case 'error': 397 | icon = 'img/error.png'; 398 | text = '播放错误'; 399 | break; 400 | case 'ended': 401 | icon = 'img/ended.png'; 402 | text = '播放完成'; 403 | break; 404 | default: 405 | break; 406 | } 407 | 408 | var oTip = doc.createElement('div'); 409 | oTip.className = 'video-tip'; 410 | oTip.innerHTML = '

      ' + text + '

      '; 411 | dom.appendChild(oTip); 412 | } 413 | 414 | function removeVideoTip (dom) { 415 | var oTip = doc.getElementsByClassName('video-tip')[0]; 416 | oTip && dom.removeChild(oTip); 417 | } 418 | 419 | function timeFormat (second) { 420 | var h = parseInt(second / 3600), 421 | m = parseInt(parseInt(second % 3600) / 60), 422 | s = parseInt(parseInt(second % 3600) % 60), 423 | time = ''; 424 | 425 | if (h == 0) { 426 | if (m >= 10) { 427 | if (s >= 10) { 428 | time = '00:' + m + ':' + s; 429 | } else { 430 | time = '00:' + m + ':0' + s; 431 | } 432 | } else { 433 | if (s >= 10) { 434 | time = '00:0' + m + ':' + s; 435 | } else { 436 | time = '00:0' + m + ':0' + s; 437 | } 438 | } 439 | } else { 440 | if (h < 10) { 441 | if (m >= 10) { 442 | if (s >= 10) { 443 | time = '0' + h + ':' + m + ':' + s; 444 | } else { 445 | time = '0' + h + ':' + m + ':0' + s; 446 | } 447 | } else { 448 | if (s >= 10) { 449 | time = '0' + h + ':0' + m + ':' + s; 450 | } else { 451 | time = '0' + h + ':0' + m + ':0' + s; 452 | } 453 | } 454 | } else { 455 | if (m >= 10) { 456 | if(s >= 10) { 457 | time = h + ':' + m + ':' + s; 458 | } else { 459 | time = h + ':' + m + ':0' + s; 460 | } 461 | } else { 462 | if(s >= 10) { 463 | time = h + ':0' + m + ':' + s; 464 | } else { 465 | time = h + ':0' + m + ':0' + s; 466 | } 467 | } 468 | } 469 | } 470 | 471 | return time; 472 | } 473 | 474 | window.MswVideo = MswVideo; 475 | })(document); 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | -------------------------------------------------------------------------------- /腾讯视频/js/video.min.js: -------------------------------------------------------------------------------- 1 | !function(e){function t(e,t){e.innerText=o(t)}function s(t,s){var i="",o="";switch(s){case"loading":i="img/loading.gif",o="加载中";break;case"error":i="img/error.png",o="播放错误";break;case"ended":i="img/ended.png",o="播放完成"}var n=e.createElement("div");n.className="video-tip",n.innerHTML='

      '+o+"

      ",t.appendChild(n)}function i(t){var s=e.getElementsByClassName("video-tip")[0];s&&t.removeChild(s)}function o(e){var t=parseInt(e/3600),s=parseInt(parseInt(e%3600)/60),i=parseInt(parseInt(e%3600)%60);return 0==t?s>=10?i>=10?"00:"+s+":"+i:"00:"+s+":0"+i:i>=10?"00:0"+s+":"+i:"00:0"+s+":0"+i:t<10?s>=10?i>=10?"0"+t+":"+s+":"+i:"0"+t+":"+s+":0"+i:i>=10?"0"+t+":0"+s+":"+i:"0"+t+":0"+s+":0"+i:s>=10?i>=10?t+":"+s+":"+i:t+":"+s+":0"+i:i>=10?t+":0"+s+":"+i:t+":0"+s+":0"+i}var n=null,l=null,a=null,r=function(t,s){this.videoBox=e.getElementById(t),this.vid=this.videoBox.getElementsByClassName("video-tag")[0],this.oPlayBtn=this.videoBox.getElementsByClassName("play-img")[0],this.oCurrentTime=this.videoBox.getElementsByClassName("current-time")[0],this.oDuration=this.videoBox.getElementsByClassName("duration")[0],this.oRateArea=this.videoBox.getElementsByClassName("playrate-area")[0],this.oRateBtn=this.oRateArea.getElementsByClassName("playrate")[0],this.oRateList=this.oRateArea.getElementsByClassName("playrate-list")[0],this.oRateBtns=this.oRateList.getElementsByClassName("item"),this.oVolumeArea=this.videoBox.getElementsByClassName("volume-area")[0],this.oVolumeBtn=this.oVolumeArea.getElementsByClassName("volume-img")[0],this.oVolumeBar=this.oVolumeArea.getElementsByClassName("volume-bar")[0],this.oVolumeSlideBar=this.oVolumeBar.getElementsByClassName("slide-bar")[0],this.oVolumeSlider=this.oVolumeBar.getElementsByClassName("volume-slide")[0],this.oVolumeRound=this.oVolumeSlider.getElementsByClassName("round")[0],this.oFullscreenBtn=this.videoBox.getElementsByClassName("fullscreen-img")[0],this.oVidHeader=this.videoBox.getElementsByClassName("vid-hd")[0],this.oControlBar=this.videoBox.getElementsByClassName("control-bar")[0],this.oProgressBar=this.videoBox.getElementsByClassName("progress-bar")[0],this.oPlayProgress=this.oProgressBar.getElementsByClassName("play-progress")[0],this.oPreloadProgress=this.oProgressBar.getElementsByClassName("preload-progress")[0],this.oPlayRound=this.oPlayProgress.getElementsByClassName("round")[0],this.oRateBtnsLen=this.oRateBtns.length,this.src=s.src,this.autoplay=s.autoplay||!1,this.preload=!this.autoplay&&(s.preload||!1),this.volume=s.volume/100||1,this.loop=s.loop||!1,this.muted=!1,this.volumeBarShow=!1,this.isFullScreen=!1,this.init()};r.prototype={init:function(){this.setOptions(),this.bindEvent(),this.autoplay&&s(this.videoBox,"loading");var e=this;l=setTimeout(function(){e.setControlBar(!0)},5e3)},bindEvent:function(){this.vid.addEventListener("canplay",this._canplay.bind(this),!1),this.vid.addEventListener("playing",this._playing.bind(this),!1),this.vid.addEventListener("waiting",this._waiting.bind(this),!1),this.vid.addEventListener("error",this._error.bind(this),!1),this.vid.addEventListener("ended",this._ended.bind(this),!1),this.vid.addEventListener("loadstart",this._loadstart.bind(this),!1),this.oPlayBtn.addEventListener("click",this.playVideo.bind(this),!1),this.oRateBtn.addEventListener("click",this.showRateList.bind(this,!0),!1),this.oRateArea.addEventListener("mouseleave",this.showRateList.bind(this,!1),!1),this.oRateList.addEventListener("click",this.setPlayRate.bind(this),!1),this.oVolumeBtn.addEventListener("click",this.btnSetVolume.bind(this),!1),this.oVolumeArea.addEventListener("mouseleave",this.showVolumeBar.bind(this,!1),!1),this.oVolumeRound.addEventListener("mousedown",this.slideVolumeBar.bind(this),!1),this.oFullscreenBtn.addEventListener("click",this.setFullScreen.bind(this),!1),this.videoBox.addEventListener("mousemove",this.showControlBar.bind(this),!1),this.oProgressBar.addEventListener("click",this.progressClick.bind(this),!1),this.oPlayRound.addEventListener("mousedown",this.progressChange.bind(this),!1)},setOptions:function(){this.vid.src=this.src,this.vid.autoplay=this.autoplay,this.vid.preload=this.preload,this.vid.loop=this.loop,this.setVolume(this.volume,!0)},playVideo:function(){this.vid.paused?(this.oPlayBtn.src="img/pause.png",this.vid.play()):(this.oPlayBtn.src="img/play.png",this.vid.pause())},showRateList:function(e){e?this.oRateList.className+=" show":this.oRateList.className="playrate-list"},setPlayRate:function(e){var t=(e=e||window.event).target||e.srcElement;if("rate-btn"===t.className){for(var s=0;s0?(this.oVolumeSlider.style.height=a+"px",this.setMuted(!1)):a>=h?(this.oVolumeSlider.style.height=h+"px",a=h,this.setMuted(!1)):a<=0&&(this.oVolumeSlider.style.height="0",a=0,this.setMuted(!0)),this.volume=(a/h).toFixed(1),this.setVolume(this.volume,!1),this.volume=0==Number(this.volume)?.5:this.volume}function i(){e.removeEventListener("mousemove",d,!1),e.removeEventListener("mouseup",u,!1)}var o=(t=t||window.event).pageY,n=0,l=0,a=0,r=this.oVolumeSlider.offsetHeight,h=this.oVolumeSlideBar.offsetHeight,d=s.bind(this),u=i.bind(this);e.addEventListener("mousemove",d,!1),e.addEventListener("mouseup",u,!1)},progressClick:function(e){var e=e||window.event;this.setPlayProgress(e.pageX)},progressChange:function(){function t(e){var e=e||window.event;this.setPlayProgress(e.pageX)}function s(){e.removeEventListener("mousemove",i,!1),e.removeEventListener("mouseup",o,!1)}var i=t.bind(this),o=s.bind(this);e.addEventListener("mousemove",i,!1),e.addEventListener("mouseup",o,!1)},setPlayProgress:function(e){var s=this.vid.duration,i=e-this.videoBox.offsetLeft,o=0;o=i<=0?0:i>=this.oProgressBar.offsetWidth?1:i/this.oProgressBar.offsetWidth,this.vid.currentTime=o*s,t(this.oCurrentTime,this.vid.currentTime),this.setVideoState(!0),this.vid.play(),this.oPlayProgress.style.width=100*o+"%"},_waiting:function(){s(this.videoBox,"loading")},_loadstart:function(){i(this.videoBox),s(this.videoBox,"loading")},_canplay:function(){t(this.oDuration,this.vid.duration),i(this.videoBox);var e=this,s=this.vid.duration,o=0,n=this.oProgressBar.offsetWidth;a=setInterval(function(){o=e.vid.buffered.end(0),e.oPreloadProgress.style.width=e.vid.buffered.end(0)/s*100+"%",e.oPreloadProgress.offsetWidth>=n&&(clearInterval(a),a=null)},1e3)},_playing:function(){this.setVideoState(!0),i(this.videoBox);var e=this,s=this.vid.duration,o=0,l=this.oProgressBar.offsetWidth;n=setInterval(function(){o=e.vid.currentTime,t(e.oCurrentTime,o),e.oPlayProgress.style.width=o/s*100+"%",e.oPlayProgress.offsetWidth>=l&&(clearInterval(n),n=null)},1e3)},_error:function(){i(this.videoBox),s(this.videoBox,"error"),clearInterval(n),clearInterval(a),n=null,a=null},_ended:function(){i(this.videoBox),s(this.videoBox,"ended")}},window.MswVideo=r}(document); -------------------------------------------------------------------------------- /腾讯视频/myplugin/css/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | .wrap { 6 | width: 750px; 7 | height: 480px; 8 | margin: 200px auto; 9 | } -------------------------------------------------------------------------------- /腾讯视频/myplugin/css/video.css: -------------------------------------------------------------------------------- 1 | .msw-video div { 2 | box-sizing: border-box; 3 | } 4 | 5 | .msw-video p, 6 | .msw-video h1, 7 | .msw-video h2, 8 | .msw-video h3, 9 | .msw-video h4, 10 | .msw-video h5, 11 | .msw-video h6 { 12 | font-weight: normal; 13 | margin: 0; 14 | } 15 | 16 | .msw-video a { 17 | text-decoration: none; 18 | } 19 | 20 | .msw-video ul { 21 | padding: 0; 22 | margin: 0; 23 | list-style: none; 24 | } 25 | 26 | .msw-video img { 27 | width: 100%; 28 | } 29 | 30 | .msw-video video { 31 | width: 100%; 32 | height: 100%; 33 | } 34 | 35 | .msw-video { 36 | position: relative; 37 | width: 100%; 38 | height: 100%; 39 | background-color: #000; 40 | overflow: hidden; 41 | } 42 | 43 | .msw-video .vid-hd { 44 | position: absolute; 45 | top: 0; 46 | left: 0; 47 | width: 100%; 48 | height: 50px; 49 | background-color: rgba(0, 0, 0, .3); 50 | color: #fff; 51 | line-height: 50px; 52 | padding: 0 15px; 53 | font-size: 18px; 54 | transition: top .5s; 55 | } 56 | 57 | .msw-video .vid-hd.hide { 58 | top: -50px; 59 | } 60 | 61 | .msw-video .control-bar { 62 | position: absolute; 63 | bottom: 0; 64 | left: 0; 65 | width: 100%; 66 | height: 50px; 67 | background-color: #000; 68 | border-top: 1px solid #333; 69 | transition: bottom .5s; 70 | } 71 | 72 | .msw-video .control-bar.hide { 73 | bottom: -47px; 74 | } 75 | 76 | .msw-video .control-bar .progress-bar { 77 | position: absolute; 78 | top: -3px; 79 | left: 0; 80 | width: 100%; 81 | height: 5px; 82 | background-color: #595959; 83 | cursor: pointer; 84 | transition: all .2s; 85 | } 86 | 87 | .msw-video .control-bar .progress-bar:hover { 88 | top: -6px; 89 | height: 8px; 90 | } 91 | 92 | .msw-video .control-bar .progress-bar .play-progress { 93 | position: absolute; 94 | top: 0; 95 | left: 0; 96 | z-index: 2; 97 | width: 0; 98 | height: 100%; 99 | background-color: #ed6d3d; 100 | } 101 | 102 | .msw-video .control-bar .progress-bar .play-progress .round { 103 | position: absolute; 104 | top: -2px; 105 | right: -6px; 106 | width: 12px; 107 | height: 12px; 108 | background-color: #ed6d3d; 109 | border-radius: 50%; 110 | opacity: 0; 111 | transition: all .3s; 112 | cursor: pointer; 113 | } 114 | 115 | .msw-video .control-bar .progress-bar .play-progress .round::before { 116 | content: ""; 117 | display: block; 118 | position: absolute; 119 | top: -4px; 120 | left: -4px; 121 | width: 20px; 122 | height: 20px; 123 | background-color: #ed6d3d; 124 | border-radius: 50%; 125 | opacity: .4; 126 | } 127 | 128 | .msw-video .control-bar .progress-bar:hover .round { 129 | opacity: 1; 130 | } 131 | 132 | .msw-video .control-bar .progress-bar .preload-progress { 133 | position: absolute; 134 | top: 0; 135 | left: 0; 136 | z-index: 1; 137 | width: 0; 138 | height: 100%; 139 | background-color: #999; 140 | } 141 | 142 | .msw-video .control-bar .play-btn-area { 143 | float: left; 144 | width: 50px; 145 | height: 50px; 146 | padding: 13px; 147 | } 148 | 149 | .msw-video .control-bar .time-area { 150 | float: left; 151 | height: 50px; 152 | padding: 0 10px; 153 | color: #fff; 154 | line-height: 50px; 155 | font-size: 12px; 156 | } 157 | 158 | .msw-video .control-bar .time-area .duration { 159 | color: #999; 160 | } 161 | 162 | .msw-video .control-bar .playrate-area { 163 | position: relative; 164 | float: right; 165 | height: 50px; 166 | padding: 0 15px; 167 | } 168 | 169 | .msw-video .control-bar .playrate-area .playrate { 170 | display: block; 171 | width: 50px; 172 | height: 30px; 173 | margin-top: 10px; 174 | font-size: 14px; 175 | line-height: 30px; 176 | text-align: center; 177 | color: #fff; 178 | border-radius: 15px; 179 | } 180 | 181 | .msw-video .control-bar .playrate-area .playrate:hover { 182 | background-color: #ed6d3d; 183 | } 184 | 185 | .msw-video .control-bar .playrate-area .playrate-list { 186 | display: none; 187 | position: absolute; 188 | left: 15px; 189 | top: -198px; 190 | width: 50px; 191 | background-color: rgba(0, 0, 0, .7); 192 | } 193 | 194 | .msw-video .control-bar .playrate-area .playrate-list.show { 195 | display: block; 196 | } 197 | 198 | .msw-video .control-bar .playrate-area .playrate-list .item { 199 | height: 40px; 200 | } 201 | 202 | .msw-video .control-bar .playrate-area .playrate-list .rate-btn { 203 | display: block; 204 | height: 100%; 205 | text-align: center; 206 | line-height: 40px; 207 | color: #fff; 208 | font-size: 14px; 209 | } 210 | 211 | .msw-video .control-bar .playrate-area .playrate-list .rate-btn.current { 212 | color: #ed6d3d; 213 | } 214 | 215 | .msw-video .control-bar .volume-area { 216 | position: relative; 217 | float: right; 218 | width: 50px; 219 | height: 50px; 220 | padding: 13px; 221 | } 222 | 223 | .msw-video .control-bar .volume-area .volume-bar { 224 | z-index:10; 225 | display: none; 226 | position: absolute; 227 | left: 0; 228 | top : -118px; 229 | width: 50px; 230 | height: 120px; 231 | padding: 12px 0; 232 | background-color: rgba(0, 0, 0, .7); 233 | } 234 | 235 | .msw-video .control-bar .volume-area .volume-bar.show { 236 | display: block; 237 | } 238 | 239 | .msw-video .control-bar .volume-area .volume-bar span { 240 | display: block; 241 | } 242 | 243 | .msw-video .control-bar .volume-area .volume-bar .slide-bar { 244 | position: relative; 245 | width: 5px; 246 | height: 96px; 247 | margin-left: 22px; 248 | background-color: #595959; 249 | border-radius: 2px; 250 | } 251 | 252 | .msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide { 253 | position: absolute; 254 | bottom: 0; 255 | left: 0; 256 | width: 5px; 257 | height: 100%; 258 | background-color: #ed6d3d; 259 | border-radius: 2px; 260 | } 261 | 262 | .msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide .round { 263 | display: block; 264 | position: absolute; 265 | top: -4px; 266 | left: -2px; 267 | width: 9px; 268 | height: 9px; 269 | background-color: #fff; 270 | border-radius: 50%; 271 | box-shadow: 0 0 2px #ed6d3d; 272 | cursor: pointer; 273 | } 274 | 275 | .msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide .round::before { 276 | content: ""; 277 | display: none; 278 | position: absolute; 279 | top: -3px; 280 | left: -3px; 281 | width: 15px; 282 | height: 15px; 283 | background-color: #ed6d3d; 284 | border-radius: 50%; 285 | opacity: .4; 286 | } 287 | 288 | .msw-video .control-bar .volume-area .volume-bar .slide-bar .volume-slide .round:hover::before { 289 | display: block; 290 | } 291 | 292 | .msw-video .control-bar .fullscreen-area { 293 | float: right; 294 | width: 50px; 295 | height: 50px; 296 | } 297 | 298 | .msw-video .control-bar .fullscreen-area .fullscreen-btn { 299 | display: block; 300 | width: 18px; 301 | height: 18px; 302 | margin: 16px 0 0 15px; 303 | } 304 | 305 | .msw-video .video-tip { 306 | position: absolute; 307 | top: 50%; 308 | left: 50%; 309 | margin: -50px 0 0 -50px; 310 | width: 100px; 311 | height: 100px; 312 | background-color: rgba(0, 0, 0, .3); 313 | border-radius: 10px; 314 | color: #fff; 315 | text-align: center; 316 | font-size: 14px; 317 | } 318 | 319 | .msw-video .video-tip img { 320 | width: 50px; 321 | height: 50px; 322 | margin-top: 10px; 323 | } 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/.DS_Store -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/1.jpg -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/ended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/ended.png -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/error.png -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/fullscreen-exit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/fullscreen-exit.png -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/fullscreen.png -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/loading.gif -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/pause.png -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/play.png -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/volume-off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/volume-off.png -------------------------------------------------------------------------------- /腾讯视频/myplugin/img/volume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/腾讯视频/myplugin/img/volume.png -------------------------------------------------------------------------------- /腾讯视频/myplugin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 视频播放器 6 | 7 | 8 | 9 | 10 | 11 |
      12 |
      13 |
      14 | 17 |
      18 |
      19 |

      事件代理机制详解

      20 |
      21 |
      22 |
      23 |
      24 | 25 |
      26 |
      27 |
      28 |
      29 | 30 | 31 | 32 |
      33 |
      34 | 00:00:00 / 00:00:00 35 |
      36 |
      37 | 38 | 39 | 40 |
      41 |
      42 | 43 | 44 | 45 |
      46 | 47 | 48 | 49 | 50 | 51 |
      52 |
      53 |
      54 | 倍速 55 | 62 |
      63 |
      64 |
      65 |
      66 | 67 | 68 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /腾讯视频/myplugin/js/video.js: -------------------------------------------------------------------------------- 1 | ;(function(doc){ 2 | var t = null, 3 | dt = null, 4 | pt = null; 5 | var MswVideo = function (dom, opt) { 6 | this.videoBox = doc.getElementById(dom); 7 | this.vid = this.videoBox.getElementsByClassName('video-tag')[0]; 8 | this.oPlayBtn = this.videoBox.getElementsByClassName('play-img')[0]; 9 | this.oCurrentTime = this.videoBox.getElementsByClassName('current-time')[0]; 10 | this.oDuration = this.videoBox.getElementsByClassName('duration')[0]; 11 | this.oRateArea = this.videoBox.getElementsByClassName('playrate-area')[0]; 12 | this.oRateBtn = this.oRateArea.getElementsByClassName('playrate')[0]; 13 | this.oRateList = this.oRateArea.getElementsByClassName('playrate-list')[0]; 14 | this.oRateBtns = this.oRateList.getElementsByClassName('item'); 15 | this.oVolumeArea = this.videoBox.getElementsByClassName('volume-area')[0]; 16 | this.oVolumeBtn = this.oVolumeArea.getElementsByClassName('volume-img')[0]; 17 | this.oVolumeBar = this.oVolumeArea.getElementsByClassName('volume-bar')[0]; 18 | this.oVolumeSlideBar = this.oVolumeBar.getElementsByClassName('slide-bar')[0]; 19 | this.oVolumeSlider = this.oVolumeBar.getElementsByClassName('volume-slide')[0]; 20 | this.oVolumeRound = this.oVolumeSlider.getElementsByClassName('round')[0]; 21 | this.oFullscreenBtn = this.videoBox.getElementsByClassName('fullscreen-img')[0]; 22 | this.oVidHeader = this.videoBox.getElementsByClassName('vid-hd')[0]; 23 | this.oControlBar = this.videoBox.getElementsByClassName('control-bar')[0]; 24 | this.oProgressBar = this.videoBox.getElementsByClassName('progress-bar')[0]; 25 | this.oPlayProgress = this.oProgressBar.getElementsByClassName('play-progress')[0]; 26 | this.oPreloadProgress = this.oProgressBar.getElementsByClassName('preload-progress')[0]; 27 | this.oPlayRound = this.oPlayProgress.getElementsByClassName('round')[0]; 28 | 29 | this.oRateBtnsLen = this.oRateBtns.length; 30 | 31 | this.src = opt.src; 32 | this.autoplay = opt.autoplay || false; 33 | this.preload = this.autoplay ? false : (opt.preload || false); 34 | this.volume = opt.volume / 100 || 1; 35 | this.loop = opt.loop || false; 36 | 37 | this.muted = false; 38 | this.volumeBarShow = false; 39 | this.isFullScreen = false; 40 | 41 | 42 | this.init() 43 | } 44 | 45 | MswVideo.prototype = { 46 | init:function(){ 47 | this.setOptions() 48 | this.bindEvent() 49 | this.autoplay && addVideoTip(this.videoBox,'loading'); 50 | //过5s隐藏 51 | var _self = this 52 | dt = setTimeout(function(){ 53 | _self.setControlBar(true) 54 | },5000) 55 | }, 56 | setOptions:function(){ 57 | this.vid.src = this.src; 58 | this.vid.autoplay = this.autoplay; 59 | this.vid.preload = this.preload; 60 | this.vid.loop = this.loop; 61 | }, 62 | bindEvent:function(){ 63 | //video自带事件 64 | //结束|正在播放 65 | this.vid.addEventListener('canplay', this._canplay.bind(this), false); 66 | this.vid.addEventListener('playing', this._playing.bind(this), false); 67 | this.vid.addEventListener('waiting', this._waiting.bind(this), false); 68 | this.vid.addEventListener('error', this._error.bind(this), false); 69 | this.vid.addEventListener('ended', this._ended.bind(this), false); 70 | this.vid.addEventListener('loadstart', this._loadstart.bind(this), false); 71 | 72 | this.oPlayBtn.addEventListener('click', this.playVideo.bind(this), false); 73 | this.oRateBtn.addEventListener('click', this.showRateList.bind(this, true), false); 74 | this.oRateArea.addEventListener('mouseleave', this.showRateList.bind(this, false), false); 75 | //委托 76 | this.oRateList.addEventListener('click', this.setPlayRate.bind(this), false); 77 | this.oVolumeBtn.addEventListener('click', this.btnSetVolume.bind(this), false); 78 | this.oVolumeArea.addEventListener('mouseleave', this.showVolumeBar.bind(this,false), false); 79 | this.oVolumeRound.addEventListener('mousedown', this.slideVolumeBar.bind(this), false); 80 | this.oFullscreenBtn.addEventListener('click', this.setFullScreen.bind(this), false); 81 | this.videoBox.addEventListener('mousemove', this.showControlBar.bind(this), false); 82 | this.oProgressBar.addEventListener('click', this.progressClick.bind(this), false); 83 | this.oPlayRound.addEventListener('mousedown', this.progressChange.bind(this), false); 84 | }, 85 | progressChange:function(e){ 86 | var _mousemove = _mouseMove.bind(this), 87 | _mouseup = _mouseUp.bind(this); 88 | doc.addEventListener('mousemove',_mousemove,false); 89 | doc.addEventListener('mouseup',_mouseup,false); 90 | function _mouseMove(e){ 91 | var e = e || window.event; 92 | this.setPlayProgress(e.pageX) 93 | } 94 | function _mouseUp(){ 95 | doc.removeEventListener('mousemove',_mousemove,false); 96 | doc.removeEventListener('mouseup',_mouseup,false); 97 | } 98 | }, 99 | progressClick:function(e){ 100 | var e = e || window.event; 101 | this.setPlayProgress(e.pageX) 102 | }, 103 | //设置进度条封装 104 | setPlayProgress:function(pageX){ 105 | var duration = this.vid.duration, 106 | curProgressBarWidth = pageX - this.videoBox.offsetLeft, 107 | ratio = 0; 108 | if(curProgressBarWidth <= 0){ 109 | ratio = 0 110 | }else if(curProgressBarWidth >= this.oProgressBar.offsetWidth){ 111 | ratio = 1 112 | }else{ 113 | ratio = curProgressBarWidth/this.oProgressBar.offsetWidth 114 | } 115 | this.vid.currentTime = ratio * duration; 116 | setTime(this.oCurrentTime,this.vid.currentTime) 117 | this.setVideoState(true) 118 | this.vid.play() 119 | this.oPlayProgress.style.width = ratio * 100 + '%' 120 | }, 121 | showControlBar:function(){ 122 | //鼠标移入过一会隐藏 防抖 123 | //先显示 124 | clearTimeout(dt) 125 | dt = null; 126 | this.setControlBar(false) 127 | var _self = this; 128 | 129 | dt = setTimeout(function () { 130 | _self.setControlBar(true); 131 | }, 5000); 132 | }, 133 | setControlBar: function (hide) { 134 | if (hide) { 135 | this.oVidHeader.className += ' hide'; 136 | this.oControlBar.className += ' hide'; 137 | } else { 138 | this.oVidHeader.className = 'vid-hd'; 139 | this.oControlBar.className = 'control-bar'; 140 | } 141 | }, 142 | setFullScreen:function(){ 143 | //兼容不同浏览器 144 | if(!this.isFullScreen){ 145 | if (this.videoBox.requestFullscreen) { 146 | this.videoBox.requestFullscreen(); 147 | } else if (this.videoBox.mozRequestFullscreen) { 148 | this.videoBox.mozRequestFullscreen(); 149 | } else if (this.videoBox.msRequestFullscreen) { 150 | this.videoBox.msRequestFullscreen(); 151 | } else if (this.videoBox.oRequestFullscreen) { 152 | this.videoBox.oRequestFullscreen(); 153 | } else if (this.videoBox.webkitRequestFullscreen) { 154 | this.videoBox.webkitRequestFullscreen(); 155 | } 156 | this.isFullScreen = true 157 | this.oFullscreenBtn.src = 'img/fullscreen-exit.png'; 158 | }else { 159 | if (doc.exitFullscreen) { 160 | doc.exitFullscreen(); 161 | } else if (doc.mozExitFullscreen) { 162 | doc.mozExitFullscreen(); 163 | } else if (doc.msExitFullscreen) { 164 | doc.msExitFullscreen(); 165 | } else if (doc.oExitFullscreen) { 166 | doc.oExitFullscreen(); 167 | } else if (doc.webkitExitFullscreen) { 168 | doc.webkitExitFullscreen(); 169 | } 170 | 171 | this.isFullScreen = false; 172 | this.oFullscreenBtn.src = 'img/fullscreen.png'; 173 | } 174 | }, 175 | slideVolumeBar:function(e){ 176 | //点击拖拽滑动 177 | var e = e || window.event, 178 | dy = e.pageY, 179 | my = 0, 180 | disY = 0, 181 | sHeight = 0, 182 | slideHeight = this.oVolumeSlider.offsetHeight, 183 | volumeBarHeight = this.oVolumeSlideBar.offsetHeight, 184 | _mousemove = _mouseMove.bind(this) 185 | _mouseup = _mouseUp.bind(this); 186 | 187 | doc.addEventListener('mousemove',_mousemove,false) 188 | doc.addEventListener('mouseup',_mouseup,false) 189 | 190 | function _mouseMove(e){ 191 | //移动的时候得出最新移动距离 192 | //=之前的距离差 + 现在的距离 193 | var e = e || window.event; 194 | my = e.pageY; 195 | //鼠标第一次 - 第二次 距离 196 | disY = dy - my; 197 | sHeight = slideHeight + disY 198 | if(sHeight < volumeBarHeight && sHeight > 0){ 199 | this.oVolumeSlider.style.height = sHeight + 'px' 200 | }else if(sHeight >= volumeBarHeight){ 201 | this.oVolumeSlider.style.height = volumeBarHeight + 'px' 202 | sHeight = volumeBarHeight; 203 | }else if(sHeight <= 0){ 204 | this.oVolumeSlider.style.height = '0'; 205 | sHeight = 0 206 | } 207 | this.volume = (sHeight/volumeBarHeight).toFixed(1); 208 | //true的话会卡顿 209 | this.setVolume(this.volume, false); 210 | //滑动底变0.5 this.volume 211 | //这样记录了值 212 | this.volume = Number(this.volume) == 0 ? 0.5 : this.volume; 213 | } 214 | function _mouseUp(){ 215 | doc.removeEventListener('mousemove',_mousemove,false) 216 | doc.removeEventListener('mouseup',_mouseup,false) 217 | } 218 | 219 | }, 220 | setVolume(volume, isChangeBar){ 221 | this.vid.volume = volume; 222 | //再点击音量滑块的时候不要再次去 223 | //改变style.height不然会卡顿 224 | isChangeBar && (this.oVolumeSlider.style.height = (volume * 100) + '%'); 225 | }, 226 | playVideo:function(){ 227 | if(this.vid.paused){ 228 | this.oPlayBtn.src = 'img/pause.png'; 229 | this.vid.play() 230 | }else{ 231 | this.oPlayBtn.src = 'img/play.png'; 232 | this.vid.pause() 233 | } 234 | }, 235 | btnSetVolume:function(){ 236 | //使用锁 237 | //1.显示音量框 没有禁音 238 | //2.显示音量框 有禁音 -> 239 | //3.没有音量框 没有禁音->显示音量框 240 | //3.没有音量框 有禁音 ->音量恢复0.5 241 | if(!this.muted && !this.volumeBarShow){ 242 | this.showVolumeBar(true) 243 | }else if(!this.muted && this.volumeBarShow){ 244 | this.setMuted(true) 245 | //设置true表示 slider跟着变化 246 | //但是slider move事件的是不不需要 247 | this.setVolume(0, true); 248 | }else{ 249 | //设置静音后 音量滑块显示.5 250 | this.setMuted(false); 251 | this.setVolume(this.volume, true); 252 | } 253 | }, 254 | setMuted: function (muted) { 255 | if (muted) { 256 | this.vid.muted = true; 257 | this.muted = true; 258 | this.oVolumeBtn.src = 'img/volume-off.png'; 259 | } else { 260 | this.vid.muted = false; 261 | this.muted = false; 262 | this.oVolumeBtn.src = 'img/volume.png'; 263 | } 264 | }, 265 | showVolumeBar:function(show){ 266 | if(show){ 267 | this.oVolumeBar.className += ' show'; 268 | this.volumeBarShow = true; 269 | }else{ 270 | this.oVolumeBar.className = ' volume-bar'; 271 | this.volumeBarShow = false; 272 | } 273 | }, 274 | setPlayRate:function(e){ 275 | //点击的时候事件委托 276 | var e = e || window.event, 277 | tar = e.target || e.srcElement, 278 | className = tar.className, 279 | rateBtn; 280 | if(className === 'rate-btn'){ 281 | //先初始化所有 282 | for(let i=0;i= progressBarWidth) { 325 | clearInterval(pt); 326 | pt = null; 327 | } 328 | }, 1000); 329 | }, 330 | //视频加载等待。 331 | //当视频由于需要缓冲下一帧而停止,等待时触发 332 | _waiting:function(){ 333 | addVideoTip(this.videoBox, 'loading'); 334 | }, 335 | //播放错误 336 | _error:function(){ 337 | removeVideoTip(this.videoBox) 338 | addVideoTip(this.videoBox,'error') 339 | clearInterval(t); 340 | clearInterval(pt); 341 | t = null; 342 | pt = null; 343 | }, 344 | // loadstart:视频查找。当浏览器开始寻找指定的 345 | // 音频/视频时触发,也就是当加载过程开始时 346 | _loadstart:function(){ 347 | removeVideoTip(this.videoBox); 348 | addVideoTip(this.videoBox, 'loading'); 349 | }, 350 | _playing:function(){ 351 | console.log('playing') 352 | //播放的时候手动要按钮切换 353 | this.setVideoState(true) 354 | removeVideoTip(this.videoBox); 355 | 356 | var _self = this, 357 | duration = this.vid.duration, //视频时间 358 | currentTime = 0, 359 | progressBarWidth = this.oProgressBar.offsetWidth; 360 | //定时器记录bar变化 361 | t = setInterval(function(){ 362 | currentTime = _self.vid.currentTime 363 | setTime(_self.oCurrentTime, currentTime); 364 | _self.oPlayProgress.style.width = (currentTime / duration)*100 + '%' 365 | if(_self.oPlayProgress.offsetWidth >= progressBarWidth){ 366 | clearInterval(t); 367 | t = null; 368 | } 369 | },1000) 370 | } 371 | } 372 | 373 | function setTime(dom, time){ 374 | dom.innerText = timeFormat(time) 375 | } 376 | 377 | function timeFormat (second) { 378 | var h = parseInt(second / 3600), 379 | m = parseInt(parseInt(second % 3600) / 60), 380 | s = parseInt(parseInt(second % 3600) % 60), 381 | time = ''; 382 | 383 | if (h == 0) { 384 | if (m >= 10) { 385 | if (s >= 10) { 386 | time = '00:' + m + ':' + s; 387 | } else { 388 | time = '00:' + m + ':0' + s; 389 | } 390 | } else { 391 | if (s >= 10) { 392 | time = '00:0' + m + ':' + s; 393 | } else { 394 | time = '00:0' + m + ':0' + s; 395 | } 396 | } 397 | } else { 398 | if (h < 10) { 399 | if (m >= 10) { 400 | if (s >= 10) { 401 | time = '0' + h + ':' + m + ':' + s; 402 | } else { 403 | time = '0' + h + ':' + m + ':0' + s; 404 | } 405 | } else { 406 | if (s >= 10) { 407 | time = '0' + h + ':0' + m + ':' + s; 408 | } else { 409 | time = '0' + h + ':0' + m + ':0' + s; 410 | } 411 | } 412 | } else { 413 | if (m >= 10) { 414 | if(s >= 10) { 415 | time = h + ':' + m + ':' + s; 416 | } else { 417 | time = h + ':' + m + ':0' + s; 418 | } 419 | } else { 420 | if(s >= 10) { 421 | time = h + ':0' + m + ':' + s; 422 | } else { 423 | time = h + ':0' + m + ':0' + s; 424 | } 425 | } 426 | } 427 | } 428 | 429 | return time; 430 | } 431 | 432 | function removeVideoTip(dom){ 433 | var oTip = doc.getElementsByClassName('video-tip')[0]; 434 | oTip && dom.removeChild(oTip) 435 | } 436 | 437 | function addVideoTip(dom, type){ 438 | var icon = '', 439 | text = ''; 440 | switch (type) { 441 | case 'loading': 442 | icon = 'img/loading.gif'; 443 | text = '加载中'; 444 | break; 445 | case 'error': 446 | icon = 'img/error.png'; 447 | text = '播放错误'; 448 | break; 449 | case 'ended': 450 | icon = 'img/ended.png'; 451 | text = '播放完成'; 452 | break; 453 | default: 454 | break; 455 | } 456 | var oTip = doc.createElement('div') 457 | oTip.className = 'video-tip' 458 | oTip.innerHTML = '

      ' + text + '

      '; 459 | dom.appendChild(oTip); 460 | } 461 | 462 | window.MswVideo = MswVideo; 463 | 464 | })(document) -------------------------------------------------------------------------------- /轮播图/css/banner.css: -------------------------------------------------------------------------------- 1 | .container { 2 | box-sizing: border-box; 3 | position: relative; 4 | margin: 20px auto; 5 | width: 1226px; 6 | height: 460px; 7 | overflow: hidden; 8 | } 9 | 10 | .container .wrapper { 11 | position: relative; 12 | height: 100%; 13 | } 14 | 15 | .container .wrapper .slide { 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | box-sizing: border-box; 20 | width: 100%; 21 | height: 100%; 22 | /* 所有SLIDE默认样式 */ 23 | z-index: 0; 24 | opacity: 0; 25 | } 26 | 27 | .container .wrapper .slide:nth-child(1) { 28 | /* 默认第一个展示 */ 29 | z-index: 1; 30 | opacity: 1; 31 | } 32 | 33 | .container .wrapper .slide img { 34 | width: 100%; 35 | height: 100%; 36 | } 37 | 38 | .container .pagination { 39 | position: absolute; 40 | right: 20px; 41 | bottom: 20px; 42 | z-index: 999; 43 | font-size: 0; 44 | } 45 | 46 | .container .pagination span { 47 | display: inline-block; 48 | margin: 0 4px; 49 | width: 6px; 50 | height: 6px; 51 | background: rgba(0, 0, 0, .4); 52 | border: 2px solid rgba(255, 255, 255, .4); 53 | border-radius: 50%; 54 | cursor: pointer; 55 | } 56 | 57 | .container .pagination span.active { 58 | background: rgba(255, 255, 255, .4); 59 | border-color: rgba(0, 0, 0, .4); 60 | } 61 | 62 | .container .button-prev, 63 | .container .button-next { 64 | position: absolute; 65 | top: 50%; 66 | margin-top: -35px; 67 | z-index: 999; 68 | width: 40px; 69 | height: 70px; 70 | background: url("../images/icon-slides.png") no-repeat; 71 | } 72 | 73 | .container .button-prev { 74 | left: 0; 75 | background-position: -83px 0; 76 | } 77 | 78 | .container .button-prev:hover { 79 | background-position: 0 0; 80 | } 81 | 82 | .container .button-next { 83 | right: 0; 84 | background-position: -124px 0; 85 | } 86 | 87 | .container .button-next:hover { 88 | background-position: -41px 0; 89 | } -------------------------------------------------------------------------------- /轮播图/css/reset.min.css: -------------------------------------------------------------------------------- 1 | body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,button,input,textarea,th,td{margin:0;padding:0}body{font-size:12px;font-style:normal;font-family:"\5FAE\8F6F\96C5\9ED1",Helvetica,sans-serif}small{font-size:12px}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4,h5,h6{font-size:100%}ul,ol{list-style:none}a{text-decoration:none;background-color:transparent}a:hover,a:active{outline-width:0;text-decoration:none}table{border-collapse:collapse;border-spacing:0}hr{border:0;height:1px}img{border-style:none}img:not([src]){display:none}svg:not(:root){overflow:hidden}html{-webkit-touch-callout:none;-webkit-text-size-adjust:100%}input,textarea,button,a{-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]),video:not([controls]){display:none;height:0}progress{vertical-align:baseline}mark{background-color:#ff0;color:#000}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}button,input,select,textarea{font-size:100%;outline:0}button,input{overflow:visible}button,select{text-transform:none}textarea{overflow:auto}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.clearfix:after{display:block;height:0;content:"";clear:both} -------------------------------------------------------------------------------- /轮播图/css/swiper.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Swiper 4.5.0 3 | * Most modern mobile touch slider and framework with hardware accelerated transitions 4 | * http://www.idangero.us/swiper/ 5 | * 6 | * Copyright 2014-2019 Vladimir Kharlampidi 7 | * 8 | * Released under the MIT License 9 | * 10 | * Released on: February 22, 2019 11 | */ 12 | .swiper-container{margin:0 auto;position:relative;overflow:hidden;list-style:none;padding:0;z-index:1}.swiper-container-no-flexbox .swiper-slide{float:left}.swiper-container-vertical>.swiper-wrapper{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-transition-property:-webkit-transform;transition-property:-webkit-transform;-o-transition-property:transform;transition-property:transform;transition-property:transform,-webkit-transform;-webkit-box-sizing:content-box;box-sizing:content-box}.swiper-container-android .swiper-slide,.swiper-wrapper{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.swiper-container-multirow>.swiper-wrapper{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.swiper-container-free-mode>.swiper-wrapper{-webkit-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out;margin:0 auto}.swiper-slide{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;width:100%;height:100%;position:relative;-webkit-transition-property:-webkit-transform;transition-property:-webkit-transform;-o-transition-property:transform;transition-property:transform;transition-property:transform,-webkit-transform}.swiper-slide-invisible-blank{visibility:hidden}.swiper-container-autoheight,.swiper-container-autoheight .swiper-slide{height:auto}.swiper-container-autoheight .swiper-wrapper{-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;-webkit-transition-property:height,-webkit-transform;transition-property:height,-webkit-transform;-o-transition-property:transform,height;transition-property:transform,height;transition-property:transform,height,-webkit-transform}.swiper-container-3d{-webkit-perspective:1200px;perspective:1200px}.swiper-container-3d .swiper-cube-shadow,.swiper-container-3d .swiper-slide,.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top,.swiper-container-3d .swiper-wrapper{-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-container-3d .swiper-slide-shadow-left{background-image:-webkit-gradient(linear,right top,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-right{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-top{background-image:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-bottom{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-wp8-horizontal,.swiper-container-wp8-horizontal>.swiper-wrapper{-ms-touch-action:pan-y;touch-action:pan-y}.swiper-container-wp8-vertical,.swiper-container-wp8-vertical>.swiper-wrapper{-ms-touch-action:pan-x;touch-action:pan-x}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:27px;height:44px;margin-top:-22px;z-index:10;cursor:pointer;background-size:27px 44px;background-position:center;background-repeat:no-repeat}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-prev,.swiper-container-rtl .swiper-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");left:10px;right:auto}.swiper-button-next,.swiper-container-rtl .swiper-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");right:10px;left:auto}.swiper-button-prev.swiper-button-white,.swiper-container-rtl .swiper-button-next.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-white,.swiper-container-rtl .swiper-button-prev.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-prev.swiper-button-black,.swiper-container-rtl .swiper-button-next.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-black,.swiper-container-rtl .swiper-button-prev.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-lock{display:none}.swiper-pagination{position:absolute;text-align:center;-webkit-transition:.3s opacity;-o-transition:.3s opacity;transition:.3s opacity;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-container-horizontal>.swiper-pagination-bullets,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullets-dynamic{overflow:hidden;font-size:0}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{-webkit-transform:scale(.33);-ms-transform:scale(.33);transform:scale(.33);position:relative}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev{-webkit-transform:scale(.66);-ms-transform:scale(.66);transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev{-webkit-transform:scale(.33);-ms-transform:scale(.33);transform:scale(.33)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next{-webkit-transform:scale(.66);-ms-transform:scale(.66);transform:scale(.66)}.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next{-webkit-transform:scale(.33);-ms-transform:scale(.33);transform:scale(.33)}.swiper-pagination-bullet{width:8px;height:8px;display:inline-block;border-radius:100%;background:#000;opacity:.2}button.swiper-pagination-bullet{border:none;margin:0;padding:0;-webkit-box-shadow:none;box-shadow:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-bullet-active{opacity:1;background:#007aff}.swiper-container-vertical>.swiper-pagination-bullets{right:10px;top:50%;-webkit-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.swiper-container-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:6px 0;display:block}.swiper-container-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:8px}.swiper-container-vertical>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{display:inline-block;-webkit-transition:.2s top,.2s -webkit-transform;transition:.2s top,.2s -webkit-transform;-o-transition:.2s transform,.2s top;transition:.2s transform,.2s top;transition:.2s transform,.2s top,.2s -webkit-transform}.swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 4px}.swiper-container-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic{left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);white-space:nowrap}.swiper-container-horizontal>.swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{-webkit-transition:.2s left,.2s -webkit-transform;transition:.2s left,.2s -webkit-transform;-o-transition:.2s transform,.2s left;transition:.2s transform,.2s left;transition:.2s transform,.2s left,.2s -webkit-transform}.swiper-container-horizontal.swiper-container-rtl>.swiper-pagination-bullets-dynamic .swiper-pagination-bullet{-webkit-transition:.2s right,.2s -webkit-transform;transition:.2s right,.2s -webkit-transform;-o-transition:.2s transform,.2s right;transition:.2s transform,.2s right;transition:.2s transform,.2s right,.2s -webkit-transform}.swiper-pagination-progressbar{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progressbar .swiper-pagination-progressbar-fill{background:#007aff;position:absolute;left:0;top:0;width:100%;height:100%;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transform-origin:left top;-ms-transform-origin:left top;transform-origin:left top}.swiper-container-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill{-webkit-transform-origin:right top;-ms-transform-origin:right top;transform-origin:right top}.swiper-container-horizontal>.swiper-pagination-progressbar,.swiper-container-vertical>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite{width:100%;height:4px;left:0;top:0}.swiper-container-horizontal>.swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,.swiper-container-vertical>.swiper-pagination-progressbar{width:4px;height:100%;left:0;top:0}.swiper-pagination-white .swiper-pagination-bullet-active{background:#fff}.swiper-pagination-progressbar.swiper-pagination-white{background:rgba(255,255,255,.25)}.swiper-pagination-progressbar.swiper-pagination-white .swiper-pagination-progressbar-fill{background:#fff}.swiper-pagination-black .swiper-pagination-bullet-active{background:#000}.swiper-pagination-progressbar.swiper-pagination-black{background:rgba(0,0,0,.25)}.swiper-pagination-progressbar.swiper-pagination-black .swiper-pagination-progressbar-fill{background:#000}.swiper-pagination-lock{display:none}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-container-horizontal>.swiper-scrollbar{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-container-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-scrollbar-lock{display:none}.swiper-zoom-container{width:100%;height:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;text-align:center}.swiper-zoom-container>canvas,.swiper-zoom-container>img,.swiper-zoom-container>svg{max-width:100%;max-height:100%;-o-object-fit:contain;object-fit:contain}.swiper-slide-zoomed{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;-webkit-transform-origin:50%;-ms-transform-origin:50%;transform-origin:50%;-webkit-animation:swiper-preloader-spin 1s steps(12,end) infinite;animation:swiper-preloader-spin 1s steps(12,end) infinite}.swiper-lazy-preloader:after{display:block;content:'';width:100%;height:100%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-position:50%;background-size:100%;background-repeat:no-repeat}.swiper-lazy-preloader-white:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}@-webkit-keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.swiper-container .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-container-fade.swiper-container-free-mode .swiper-slide{-webkit-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out}.swiper-container-fade .swiper-slide{pointer-events:none;-webkit-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.swiper-container-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide-active,.swiper-container-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube{overflow:visible}.swiper-container-cube .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1;visibility:hidden;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%}.swiper-container-cube .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-cube.swiper-container-rtl .swiper-slide{-webkit-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-next,.swiper-container-cube .swiper-slide-next+.swiper-slide,.swiper-container-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-container-cube .swiper-slide-shadow-bottom,.swiper-container-cube .swiper-slide-shadow-left,.swiper-container-cube .swiper-slide-shadow-right,.swiper-container-cube .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0;width:100%;height:100%;background:#000;opacity:.6;-webkit-filter:blur(50px);filter:blur(50px);z-index:0}.swiper-container-flip{overflow:visible}.swiper-container-flip .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-container-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-flip .swiper-slide-active,.swiper-container-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-flip .swiper-slide-shadow-bottom,.swiper-container-flip .swiper-slide-shadow-left,.swiper-container-flip .swiper-slide-shadow-right,.swiper-container-flip .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-coverflow .swiper-wrapper{-ms-perspective:1200px} -------------------------------------------------------------------------------- /轮播图/images/banner01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/轮播图/images/banner01.png -------------------------------------------------------------------------------- /轮播图/images/banner02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/轮播图/images/banner02.jpg -------------------------------------------------------------------------------- /轮播图/images/banner03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/轮播图/images/banner03.png -------------------------------------------------------------------------------- /轮播图/images/banner04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/轮播图/images/banner04.png -------------------------------------------------------------------------------- /轮播图/images/banner05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/轮播图/images/banner05.png -------------------------------------------------------------------------------- /轮播图/images/icon-slides.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/weizaicv/mini-framework/99162e17f5d65d9e8ae12619ae853689393208d0/轮播图/images/icon-slides.png -------------------------------------------------------------------------------- /轮播图/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 渐隐渐现版轮播图 7 | 8 | 9 | 10 | 11 | 12 | 13 |
      14 | 15 |
      16 | 19 |
      20 | 21 | 25 | 26 | 27 | 28 |
      29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /轮播图/js/banner.js: -------------------------------------------------------------------------------- 1 | function throttle(func, wait) { 2 | let timer = null, 3 | result = null, 4 | previous = 0; 5 | return function anonymous(...args) { 6 | let context = this, 7 | now = new Date, 8 | spanTime = wait - (now - previous); 9 | if (spanTime <= 0) { 10 | result = func.call(context, ...args); 11 | clearTimeout(timer); 12 | timer = null; 13 | previous = now; 14 | } else if (!timer) { 15 | timer = setTimeout(() => { 16 | result = func.call(context, ...args); 17 | timer = null; 18 | previous = new Date; 19 | }, spanTime); 20 | } 21 | return result; 22 | } 23 | } 24 | 25 | function debounce(func, wait, immediate) { 26 | let timer = null, 27 | result = null; 28 | return function anonymous(...args) { 29 | let context = this, 30 | now = immediate && !timer; 31 | clearTimeout(timer); 32 | timer = setTimeout(() => { 33 | timer = null; 34 | !immediate ? result = func.call(context, ...args) : null; 35 | }, wait); 36 | now ? result = func.call(context, ...args) : null; 37 | return result; 38 | } 39 | } 40 | 41 | let bannerModule = (function () { 42 | let $container = $('.container'), 43 | $wrapper = $container.find('.wrapper'), 44 | $pagination = $container.find('.pagination'), 45 | $slideList = null; 46 | 47 | let autoTimer = null, 48 | interval = 1000, 49 | speed = 300, 50 | activeIndex = 0, 51 | count = 0; 52 | 53 | //=>queryData:获取数据 54 | let queryData = function (callBack) { 55 | $.ajax({ 56 | url: 'json/bannerData1.json', 57 | method: 'get', 58 | async: true, 59 | success: result => { 60 | callBack && callBack(result); 61 | } 62 | }); 63 | }; 64 | 65 | //=>bindHTML:数据绑定 66 | let bindHTML = function (data) { 67 | let str1 = ``, 68 | str2 = ``; 69 | data.forEach((item, index) => { 70 | str1 += `
      71 | 72 |
      `; 73 | 74 | str2 += ``; 75 | }); 76 | $wrapper.html(str1); 77 | $pagination.html(str2); 78 | //=>获取结构内容 79 | $slideList = $wrapper.children('.slide'); 80 | }; 81 | 82 | //=>autoMove:自动轮播 83 | let change = function () { 84 | let $active = $slideList.eq(activeIndex), 85 | $siblings = $active.siblings(); 86 | $active.css('transition', `opacity ${speed}ms`); 87 | $siblings.css('transition', `opacity 0ms`); 88 | $active.css('z-index', 1); 89 | $siblings.css('z-index', 0); 90 | $active.css('opacity', 1).on('transitionend', function () { 91 | $siblings.css('opacity', 0); 92 | }); 93 | 94 | $pagination.children('span').each((index, item) => { 95 | let $item = $(item); 96 | if (index === activeIndex) { 97 | $item.addClass('active'); 98 | return; 99 | } 100 | $item.removeClass('active'); 101 | }); 102 | }; 103 | let autoMove = function () { 104 | activeIndex++; 105 | activeIndex >= count ? activeIndex = 0 : null; 106 | change(); 107 | }; 108 | 109 | return { 110 | init() { 111 | queryData(function anonymous(data) { 112 | bindHTML(data); 113 | count = data.length; 114 | autoTimer = setInterval(autoMove, interval); 115 | }); 116 | $container.mouseenter(function () { 117 | clearInterval(autoTimer); 118 | }).mouseleave(function () { 119 | autoTimer = setInterval(autoMove, interval); 120 | }).click(function (ev) { 121 | //=>基于事件委托实现焦点和左右按钮点击 122 | let target = ev.target, 123 | $target = $(target); 124 | //=>事件源:焦点 125 | if (target.tagName === "SPAN" && $target.parent().hasClass('pagination')) { 126 | activeIndex = $target.index(); 127 | change(); 128 | return; 129 | } 130 | //=>事件源:前进后退按钮 131 | if (target.tagName === 'A') { 132 | if ($target.hasClass('button-prev')) { 133 | activeIndex--; 134 | activeIndex < 0 ? activeIndex = count - 1 : null; 135 | change(); 136 | return; 137 | } 138 | if ($target.hasClass('button-next')) { 139 | autoMove(); 140 | return; 141 | } 142 | } 143 | }); 144 | //=>在真实项目中,如果要操作的元素是基于JS动态绑定的,那么“相关事件行为触发做些事情”的处理操作,我们尽可能基于事件委托来处理(事件委托可以给动态绑定的元素绑定事件) 145 | } 146 | } 147 | })(); 148 | bannerModule.init(); -------------------------------------------------------------------------------- /轮播图/json/bannerData1.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "id": 1, 3 | "pic": "images/banner01.png" 4 | }, { 5 | "id": 2, 6 | "pic": "images/banner02.jpg" 7 | }, { 8 | "id": 3, 9 | "pic": "images/banner03.png" 10 | }, { 11 | "id": 4, 12 | "pic": "images/banner04.png" 13 | }, { 14 | "id": 5, 15 | "pic": "images/banner05.png" 16 | }] -------------------------------------------------------------------------------- /轮播图/json/bannerData2.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "id": 1, 3 | "pic": "images/banner01.png" 4 | }, { 5 | "id": 2, 6 | "pic": "images/banner02.jpg" 7 | }, { 8 | "id": 3, 9 | "pic": "images/banner03.png" 10 | }] -------------------------------------------------------------------------------- /选项卡/css/index.css: -------------------------------------------------------------------------------- 1 | *{ 2 | padding: 0; 3 | margin: 0; 4 | } 5 | 6 | a{ 7 | text-decoration: none; 8 | color: black; 9 | } 10 | 11 | ul{ 12 | list-style: none; 13 | } 14 | 15 | body{ 16 | margin: 60px; 17 | } 18 | 19 | /*-----------------------------*/ 20 | #tab{ 21 | width: 498px; 22 | height: 130px; 23 | /*边框*/ 24 | border:1px solid #9d9d9d; 25 | 26 | /*处理超出的内容*/ 27 | /*overflow: hidden;*/ 28 | } 29 | 30 | 31 | /*-----------------------------*/ 32 | #tab-header{ 33 | height: 33px; 34 | background-color: #e8e8e8; 35 | 36 | /*定位*/ 37 | position: relative; 38 | } 39 | 40 | #tab-header ul{ 41 | width: 501px; 42 | /*定位*/ 43 | position: relative; 44 | left: -1px; 45 | } 46 | 47 | #tab-header ul li{ 48 | float: left; 49 | width: 98px; 50 | height: 33px; 51 | /*background-color: red;*/ 52 | 53 | /*文字的水平和垂直居中*/ 54 | text-align: center; 55 | line-height: 33px; 56 | 57 | /*设置内边距,先占满空间*/ 58 | padding: 0 1px; 59 | 60 | /*下边框*/ 61 | border-bottom: 1px solid #9d9d9d; 62 | 63 | cursor: pointer; 64 | } 65 | 66 | /*拿到头部选中的li标签*/ 67 | #tab-header ul li.selected{ 68 | background-color: white; 69 | /*去除下边框*/ 70 | border-bottom: 0; 71 | /*设置左右边框*/ 72 | border-left: 1px solid #9d9d9d; 73 | border-right: 1px solid #9d9d9d; 74 | 75 | /*释放先前的空间*/ 76 | padding: 0; 77 | } 78 | 79 | /*伪类*/ 80 | #tab-header ul li:hover{ 81 | color: orangered; 82 | font-weight: bolder; 83 | } 84 | 85 | 86 | /*-----------------------------*/ 87 | #tab-content{ 88 | padding-top: 15px; 89 | } 90 | 91 | #tab-content .dom{ 92 | /*隐藏所有*/ 93 | display: none; 94 | } 95 | 96 | #tab-content .dom ul li{ 97 | float: left; 98 | width: 220px; 99 | text-align: center; 100 | margin:5px 0; 101 | } 102 | 103 | #tab-content .dom ul li a:hover{ 104 | color: orange; 105 | } -------------------------------------------------------------------------------- /选项卡/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tab选项卡的切换 6 | 7 | 8 | 9 | 10 |
      11 | 12 |
      13 |
        14 |
      • 公告
      • 15 |
      • 规则
      • 16 |
      • 论坛
      • 17 |
      • 公益
      • 18 |
      • 安全
      • 19 |
      20 |
      21 | 22 |
      23 |
      24 | 38 |
      39 |
      40 | 54 |
      55 |
      56 | 70 |
      71 |
      72 | 86 |
      87 |
      88 | 96 |
      97 |
      98 |
      99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /选项卡/js/index.js: -------------------------------------------------------------------------------- 1 | /*window.onload =function () { 2 | // 1.1 获取需要的标签 3 | var lis = document.getElementById('tab-header').getElementsByTagName('li'); 4 | var contents = document.getElementById('tab-content').getElementsByClassName('dom'); 5 | 6 | // 1.2 遍历 7 | for(var i=0; i