├── README.md ├── autocomplete ├── README.md ├── css │ └── autocomplete.css ├── demo.html └── js │ └── autocomplete.js ├── dragMove ├── README.md ├── demo.html └── js │ └── dragMove.js ├── face ├── README.md ├── css │ └── face.css ├── demo.html ├── js │ ├── face.js │ └── scrollbar.js └── src │ ├── dang │ ├── 0.png │ ├── 1.png │ ├── 10.png │ ├── 11.png │ ├── 12.png │ ├── 13.png │ ├── 14.png │ ├── 15.png │ ├── 16.png │ ├── 17.png │ ├── 18.png │ ├── 19.png │ ├── 2.png │ ├── 20.png │ ├── 21.png │ ├── 22.png │ ├── 23.png │ ├── 24.png │ ├── 25.png │ ├── 26.png │ ├── 27.png │ ├── 28.png │ ├── 29.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ └── 9.png │ ├── wang │ ├── 0.bmp │ ├── 0.gif │ ├── 1.bmp │ ├── 1.gif │ ├── 10.bmp │ ├── 10.gif │ ├── 11.bmp │ ├── 11.gif │ ├── 12.bmp │ ├── 12.gif │ ├── 13.bmp │ ├── 13.gif │ ├── 14.bmp │ ├── 14.gif │ ├── 15.bmp │ ├── 15.gif │ ├── 16.bmp │ ├── 16.gif │ ├── 17.bmp │ ├── 17.gif │ ├── 18.bmp │ ├── 18.gif │ ├── 19.bmp │ ├── 19.gif │ ├── 2.bmp │ ├── 2.gif │ ├── 20.bmp │ ├── 20.gif │ ├── 21.bmp │ ├── 21.gif │ ├── 22.bmp │ ├── 22.gif │ ├── 23.bmp │ ├── 23.gif │ ├── 24.bmp │ ├── 24.gif │ ├── 25.bmp │ ├── 25.gif │ ├── 26.bmp │ ├── 26.gif │ ├── 27.bmp │ ├── 27.gif │ ├── 28.bmp │ ├── 28.gif │ ├── 29.bmp │ ├── 29.gif │ ├── 3.bmp │ ├── 3.gif │ ├── 30.bmp │ ├── 30.gif │ ├── 31.bmp │ ├── 31.gif │ ├── 32.bmp │ ├── 32.gif │ ├── 33.bmp │ ├── 33.gif │ ├── 34.bmp │ ├── 34.gif │ ├── 35.bmp │ ├── 35.gif │ ├── 36.bmp │ ├── 36.gif │ ├── 37.bmp │ ├── 37.gif │ ├── 38.bmp │ ├── 38.gif │ ├── 39.bmp │ ├── 39.gif │ ├── 4.bmp │ ├── 4.gif │ ├── 5.bmp │ ├── 5.gif │ ├── 6.bmp │ ├── 6.gif │ ├── 7.bmp │ ├── 7.gif │ ├── 8.bmp │ ├── 8.gif │ ├── 9.bmp │ └── 9.gif │ ├── wx.zip │ ├── wx │ ├── 0.gif │ ├── 0.png │ ├── 1.gif │ ├── 1.png │ ├── 10.gif │ ├── 10.png │ ├── 100.gif │ ├── 100.png │ ├── 101.gif │ ├── 101.png │ ├── 102.gif │ ├── 102.png │ ├── 103.gif │ ├── 103.png │ ├── 104.gif │ ├── 104.png │ ├── 11.gif │ ├── 11.png │ ├── 12.gif │ ├── 12.png │ ├── 13.gif │ ├── 13.png │ ├── 14.gif │ ├── 14.png │ ├── 15.gif │ ├── 15.png │ ├── 16.gif │ ├── 16.png │ ├── 17.gif │ ├── 17.png │ ├── 18.gif │ ├── 18.png │ ├── 19.gif │ ├── 19.png │ ├── 2.gif │ ├── 2.png │ ├── 20.gif │ ├── 20.png │ ├── 21.gif │ ├── 21.png │ ├── 22.gif │ ├── 22.png │ ├── 23.gif │ ├── 23.png │ ├── 24.gif │ ├── 24.png │ ├── 25.gif │ ├── 25.png │ ├── 26.gif │ ├── 26.png │ ├── 27.gif │ ├── 27.png │ ├── 28.gif │ ├── 28.png │ ├── 29.gif │ ├── 29.png │ ├── 3.gif │ ├── 3.png │ ├── 30.gif │ ├── 30.png │ ├── 31.gif │ ├── 31.png │ ├── 32.gif │ ├── 32.png │ ├── 33.gif │ ├── 33.png │ ├── 34.gif │ ├── 34.png │ ├── 35.gif │ ├── 35.png │ ├── 36.gif │ ├── 36.png │ ├── 37.gif │ ├── 37.png │ ├── 38.gif │ ├── 38.png │ ├── 39.gif │ ├── 39.png │ ├── 4.gif │ ├── 4.png │ ├── 40.gif │ ├── 40.png │ ├── 41.gif │ ├── 41.png │ ├── 42.gif │ ├── 42.png │ ├── 43.gif │ ├── 43.png │ ├── 44.gif │ ├── 44.png │ ├── 45.gif │ ├── 45.png │ ├── 46.gif │ ├── 46.png │ ├── 47.gif │ ├── 47.png │ ├── 48.gif │ ├── 48.png │ ├── 49.gif │ ├── 49.png │ ├── 5.gif │ ├── 5.png │ ├── 50.gif │ ├── 50.png │ ├── 51.gif │ ├── 51.png │ ├── 52.gif │ ├── 52.png │ ├── 53.gif │ ├── 53.png │ ├── 54.gif │ ├── 54.png │ ├── 55.gif │ ├── 55.png │ ├── 56.gif │ ├── 56.png │ ├── 57.gif │ ├── 57.png │ ├── 58.gif │ ├── 58.png │ ├── 59.gif │ ├── 59.png │ ├── 6.gif │ ├── 6.png │ ├── 60.gif │ ├── 60.png │ ├── 61.gif │ ├── 61.png │ ├── 62.gif │ ├── 62.png │ ├── 63.gif │ ├── 63.png │ ├── 64.gif │ ├── 64.png │ ├── 65.gif │ ├── 65.png │ ├── 66.gif │ ├── 66.png │ ├── 67.gif │ ├── 67.png │ ├── 68.gif │ ├── 68.png │ ├── 69.gif │ ├── 69.png │ ├── 7.gif │ ├── 7.png │ ├── 70.gif │ ├── 70.png │ ├── 71.gif │ ├── 71.png │ ├── 72.gif │ ├── 72.png │ ├── 73.gif │ ├── 73.png │ ├── 74.gif │ ├── 74.png │ ├── 75.gif │ ├── 75.png │ ├── 76.gif │ ├── 76.png │ ├── 77.gif │ ├── 77.png │ ├── 78.gif │ ├── 78.png │ ├── 79.gif │ ├── 79.png │ ├── 8.gif │ ├── 8.png │ ├── 80.gif │ ├── 80.png │ ├── 81.gif │ ├── 81.png │ ├── 82.gif │ ├── 82.png │ ├── 83.gif │ ├── 83.png │ ├── 84.gif │ ├── 84.png │ ├── 85.gif │ ├── 85.png │ ├── 86.gif │ ├── 86.png │ ├── 87.gif │ ├── 87.png │ ├── 88.gif │ ├── 88.png │ ├── 89.gif │ ├── 89.png │ ├── 9.gif │ ├── 9.png │ ├── 90.gif │ ├── 90.png │ ├── 91.gif │ ├── 91.png │ ├── 92.gif │ ├── 92.png │ ├── 93.gif │ ├── 93.png │ ├── 94.gif │ ├── 94.png │ ├── 95.gif │ ├── 95.png │ ├── 96.gif │ ├── 96.png │ ├── 97.gif │ ├── 97.png │ ├── 98.gif │ ├── 98.png │ ├── 99.gif │ └── 99.png │ └── yun │ ├── 0.png │ ├── 1.png │ ├── 10.png │ ├── 11.png │ ├── 12.png │ ├── 13.png │ ├── 14.png │ ├── 15.png │ ├── 16.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ └── 9.png ├── gulpfile.js ├── h5Crop ├── README.md └── demo.html ├── h5Upload ├── README.md ├── demo.html └── js │ └── h5Upload.js ├── images ├── 108x108.png ├── 123.png ├── 28x28.png ├── 456.png ├── a1.png ├── a2.png ├── a3.png ├── a4.png └── reload.gif ├── index.html ├── input ├── README.md ├── demo.html └── js │ └── input.js ├── js ├── base.js ├── jquery-1.11.3.min.js └── jquery.mousewheel.all.min.js └── scrollbar ├── README.md ├── demo.html └── js └── scrollbar.js /README.md: -------------------------------------------------------------------------------- 1 | # jquery-plugins 2 | * 编写的一些实用插件集合 3 | * 每个插件的功能在下方有简单的介绍,具体的使用介绍请查看相关插件内部的README.md 4 | 5 | # [插件列表](http://demo.vcxiaohan.com/jquery-plugins/index.html) 6 | 7 | #### [自动补全插件-autocomplete](https://github.com/vcxiaohan/jquery-plugins/tree/master/autocomplete)---[demo](http://demo.vcxiaohan.com/jquery-plugins/autocomplete/demo.html)---完成100% 8 | 9 | #### [拖动插件-dragMove](https://github.com/vcxiaohan/jquery-plugins/tree/master/dragMove)---[demo](http://demo.vcxiaohan.com/jquery-plugins/dragMove/demo.html)---完成100% 10 | 11 | #### [表情插件-face](https://github.com/vcxiaohan/jquery-plugins/tree/master/face)---[demo](http://demo.vcxiaohan.com/jquery-plugins/face/demo.html)---完成100% 12 | 13 | #### [裁剪头像插件-h5Crop](https://github.com/vcxiaohan/jquery-plugins/tree/master/h5Crop)---[demo](http://demo.vcxiaohan.com/jquery-plugins/h5Crop/demo.html)---完成50% 14 | 15 | #### [输入框提示插件-input](https://github.com/vcxiaohan/jquery-plugins/tree/master/input)---[demo](http://demo.vcxiaohan.com/jquery-plugins/input/demo.html)---完成50% 16 | 17 | #### [滚动条插件-scrollbar](https://github.com/vcxiaohan/jquery-plugins/tree/master/scrollbar)---[demo](http://demo.vcxiaohan.com/jquery-plugins/scrollbar/demo.html)---完成100% 18 | 19 | #### [拖拽预览上传插件-h5Upload](https://github.com/vcxiaohan/jquery-plugins/tree/master/h5Upload)---[demo](http://demo.vcxiaohan.com/jquery-plugins/h5Upload/demo.html)---完成90% 20 | -------------------------------------------------------------------------------- /autocomplete/README.md: -------------------------------------------------------------------------------- 1 | #### autocomplete 说明文档 2 | 3 | * ###### demo 示例 4 | 1. [http://demo.vcxiaohan.com/jquery-plugins/autocomplete/demo.html](http://demo.vcxiaohan.com/jquery-plugins/autocomplete/demo.html) 5 | 6 | * ###### 功能简介 7 | 1. 输入框提示插件 8 | 2. 支持方向键上下选中 9 | 3. 可以配置最多提示条数 10 | 4. 请注意要修改为符合自己后台返回的格式要求 11 | 12 | 13 | * ###### 使用说明 14 | 1. 内部名词解释 15 | * 在输入框中输入文字,默认延时500ms后显示提示的文字 16 | 2. 调用示例 17 | 18 | $('.input').autocomplete({ 19 | prefix: '/',//[string] 20 | url: 'servlet/AQ?s=ig',//[string] 21 | targetEl: $('.inputCtn'),//参照物(用于appendTo和定位) 22 | posAttr: ['0px', '0px'],//外边框的定位[left bottom] 23 | itemNum: 10,//[int] 默认全部显示 24 | callback: function(data) {//获取文本后的回调函数 25 | $('.showCtn').append(data); 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /autocomplete/css/autocomplete.css: -------------------------------------------------------------------------------- 1 | /* jquery.autocomplete.css */ 2 | 3 | 4 | .AU_outerCtn { 5 | border-radius: 5px 5px 0 0; 6 | background: #fff; 7 | position: absolute; 8 | border: 1px solid #d9d9d9; 9 | box-shadow: 0 0 20px 0 rgba(0, 0, 0, .15); 10 | z-index: 100000; 11 | width: 100%; 12 | } 13 | 14 | .AU_innerCtn { 15 | cursor: pointer; 16 | } 17 | 18 | .AU_innerCtn_focus { 19 | background: #e3f8ff; 20 | } 21 | 22 | .AU_txt { 23 | padding: 0 8px; 24 | line-height: 26px; 25 | } 26 | 27 | .AU_replaceTip { 28 | color: #f00; 29 | } 30 | -------------------------------------------------------------------------------- /autocomplete/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | demo 12 | 13 | 44 | 45 | 46 |
47 |
48 |
49 |
50 | 51 |
52 |
53 |
54 | 55 | 77 | -------------------------------------------------------------------------------- /autocomplete/js/autocomplete.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.autocomplete.js 3 | * 4 | * Copyright (c) 2016/5/20 Han Wenbo 5 | * 6 | **/ 7 | 8 | ;(function($, window, document, undefined) { 9 | var plugName = "autocomplete", 10 | defaults = { 11 | prefix: '../../',//接口路径前缀(不能写根路径) 12 | url: '',//[string] 13 | jsonp: false,//是否跨域 14 | targetEl: null,//参照物(用于appendTo和定位) 15 | posAttr: ['0px', '0px'],//外边框的定位[left bottom] 要写单位 16 | itemNum: 0,//[int] 默认全部显示 17 | keyupDelay: 5,//[int] 默认keyup之后,延时500ms后发送请求 18 | callback: function(data) {},//获取文本后的回调函数 19 | }; 20 | 21 | function Autocomplete($el, options) { 22 | this.plugName = plugName; 23 | this.$el = $el; 24 | this.prop = {}; 25 | this.obj = {}; 26 | this.$obj = {}; 27 | this.defaults = defaults; 28 | this.options = $.extend({}, defaults, options); 29 | this.init(); 30 | } 31 | 32 | Autocomplete.prototype = { 33 | init: function() { 34 | this.baseProp();//$el的基础属性 35 | this.baseEl();//生成外边框 36 | this.event();//绑定事件 37 | }, 38 | //基础属性 39 | baseProp: function() { 40 | this.prop.winW = $(window).width(); 41 | this.prop.winH = $(window).height(); 42 | 43 | this.prop.outerWidth = this.$el.outerWidth(); 44 | this.prop.outerHeight = this.$el.outerHeight(); 45 | this.prop.position = this.$el.position(); 46 | this.prop.offset = this.$el.offset(); 47 | 48 | this.prop.bottom = this.prop.winH - this.prop.offset.top; 49 | this.prop.boxSizing = this.$el.css('boxSizing'); 50 | 51 | //是否rem 52 | this.prop.baseRem = parseInt($('html').css('fontSize')); 53 | }, 54 | //生成外边框 55 | baseEl: function() { 56 | //rem 57 | if(this.options.posAttr.join(',').indexOf('rem') != -1) {//rem 58 | for(var i=0; i').css({ 64 | left: this.options.posAttr[0], 65 | bottom: this.options.posAttr[1], 66 | boxSizing: this.prop.boxSizing, 67 | }).hide().appendTo(this.options.targetEl); 68 | }, 69 | //绑定事件 70 | event: function() { 71 | var This = this; 72 | 73 | /*This.eventType = 'click'; 74 | if(!Base.isPC()) {// hack ios 点击document不失去焦点 75 | This.eventType = 'touchend'; 76 | }*/ 77 | 78 | This.obj.curIndex = 0;//当前选中的div 79 | 80 | //文本改变(兼容ie9删除文本) 81 | This.$el.on('input.AU, propertychange.AU, keyup.AU', function(e) { 82 | if(e.type=='keyup') { 83 | if(e.keyCode==8 && Base.ieVersion==9) {//ie9下退格键 84 | This.outerCtnEvent(); 85 | } 86 | if(e.keyCode==38) {//上移 87 | if(This.obj.curIndex == 0.5) { 88 | This.obj.curIndex = This.obj.maxIndex; 89 | }else { 90 | if(This.obj.curIndex > 0) { 91 | This.obj.curIndex--; 92 | }else { 93 | This.obj.curIndex = This.obj.maxIndex; 94 | } 95 | } 96 | $('.AU_innerCtn').eq(This.obj.curIndex).addClass('AU_innerCtn_focus').siblings().removeClass('AU_innerCtn_focus'); 97 | } 98 | if(e.keyCode==40) {//下移 99 | if(This.obj.curIndex == 0.5) { 100 | This.obj.curIndex = 0; 101 | }else { 102 | This.obj.curIndex = parseInt(This.obj.curIndex); 103 | if(This.obj.curIndex < This.obj.maxIndex) { 104 | This.obj.curIndex++; 105 | }else { 106 | This.obj.curIndex = 0; 107 | } 108 | } 109 | $('.AU_innerCtn').eq(This.obj.curIndex).addClass('AU_innerCtn_focus').siblings().removeClass('AU_innerCtn_focus'); 110 | } 111 | if(e.keyCode==27) {//取消 112 | This.$obj.$AU_outerCtn.empty().hide(); 113 | } 114 | if(e.keyCode==108 || e.keyCode== 13) {//确定 115 | $('.AU_txt').eq(This.obj.curIndex).trigger('click'); 116 | This.$obj.$AU_outerCtn.empty().hide(); 117 | } 118 | }else { 119 | This.outerCtnEvent(); 120 | } 121 | }); 122 | 123 | //选定 124 | $(document).on('mouseover.AU', '.AU_innerCtn', function(e) { 125 | if(e.type == 'mouseover') { 126 | $(this).addClass('AU_innerCtn_focus').siblings().removeClass('AU_innerCtn_focus'); 127 | 128 | This.getCurIndex(); 129 | } 130 | }); 131 | 132 | //取消 133 | $(document).on('click.AU', function(e) { 134 | if(e.target != This.$el[0]) {//输入框 135 | if($(e.target).is('.AU_txt')) {//选项 136 | var data = $(e.target).text().match(/^\d+\. (.+)/)[1]; 137 | 138 | This.$el.val(data); 139 | This.options.callback(data); 140 | } 141 | This.$obj.$AU_outerCtn.empty().hide(); 142 | } 143 | }); 144 | 145 | }, 146 | //外框事件 147 | outerCtnEvent: function() { 148 | var This = this; 149 | 150 | This.obj.timerIndex = 0; 151 | clearInterval(This.obj.timer); 152 | This.obj.timer = setInterval(function() { 153 | This.obj.timerIndex++; 154 | if(This.obj.timerIndex == This.options.keyupDelay) { 155 | var pattern = new RegExp(This.$el.val(), 'g'); 156 | Base.request({ 157 | prefix: This.options.prefix,//接口路径前缀(不能写根路径) 158 | url: This.options.url, 159 | params: { 160 | q: This.$el.val(), 161 | }, 162 | dataType: This.options.jsonp ? 'jsonp' : 'json',//默认json 163 | callback: function(data) { 164 | if(data.status) {//1 165 | layer.msg(data.message, { 166 | shift: 0, 167 | area: This.getSuitSize() 168 | }); 169 | }else {//0 170 | var html = ''; 171 | if(data.list) { 172 | if(data.list[0]) { 173 | var len = This.options.itemNum ? (This.options.itemNum>data.list.length?data.list.length:This.options.itemNum) : data.list.length; 174 | for(var i=0; i'+ This.$el.val() +'') +''; 176 | 177 | } 178 | This.obj.curIndex = 0.5;//恢复0 179 | This.obj.maxIndex = len-1;//最大index 180 | This.$obj.$AU_outerCtn.empty().append(html).show(); 181 | $('.AU_innerCtn').eq(Math.floor(This.obj.curIndex)).addClass('AU_innerCtn_focus').siblings().removeClass('AU_innerCtn_focus'); 182 | }else { 183 | This.$obj.$AU_outerCtn.empty().hide(); 184 | } 185 | } 186 | } 187 | }, 188 | }); 189 | clearInterval(This.obj.timer); 190 | } 191 | }, 100); 192 | }, 193 | //获取当前选中的div 194 | getCurIndex: function() { 195 | var This = this; 196 | 197 | $('.AU_innerCtn').each(function(key, val) { 198 | if($(val).is('.AU_innerCtn_focus')) { 199 | This.obj.curIndex = key; 200 | } 201 | }); 202 | }, 203 | // 获取提示框合适的大小 204 | getSuitSize: function() { 205 | return Base.isPC()?'400px':'0.8rem'; 206 | }, 207 | } 208 | 209 | $.fn.extend({ 210 | autocomplete: function(options) { 211 | return this.each(function() { 212 | new Autocomplete($(this), options); 213 | }) 214 | } 215 | }) 216 | })(jQuery, window, document); 217 | -------------------------------------------------------------------------------- /dragMove/README.md: -------------------------------------------------------------------------------- 1 | #### dragMove 说明文档 2 | 3 | * ###### demo示例 4 | [http://demo.vcxiaohan.com/jquery-plugins/dragMove/demo.html](http://demo.vcxiaohan.com/jquery-plugins/dragMove/demo.html) 5 | 6 | * ###### 功能简介 7 | 1. 该 *demo* 已包含插件本身和使用示例,您也可以将插件单独抽出,引用使用 8 | 2. 该拖动效果的实现思路是通过拖动子元素,来移动父元素 9 | 3. 效果分为2种: 10 | * 单纯的拖动 11 | * 拖动交换位置 12 | 4. *demo* 效果介绍 13 | * 第一组可以和第二组交换 14 | * 第三组只能组内交换 15 | * 第四组是单纯的拖动 16 | * 后添加的元素都要加上 *DR_mid* 的类名(防止位置对不齐) 17 | 18 | * ###### 使用说明 19 | 1. 内部名词解释 20 | * 类名 *DR_drag* 是用来分组的,是我们主动拖动的子元素-必需 21 | * 类名 *DR_replace* (0-单纯拖动-非必需 1-交换位置-必需) 是用来识别当前元素是否可与同组内元素交换位置 22 | * 类名 *drag* 是我们拖动的子元素,可配置-必需 23 | 2. 调用示例 24 | 25 | $('body').dragMove({ 26 | limit: true,// 限制在窗口内 27 | callback: function($move, $replace) { 28 | console.log('拖动了'+ $('p', $move).text() +'跟'+ $('p', $replace).text() +'进行交换'); 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /dragMove/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | demo 10 | 11 | 50 | 51 | 52 |

第一组:

53 |
54 |
55 |

111

56 | 57 | 58 |
59 |
60 |

222

61 | 62 | 63 |
64 |
65 |

333

66 | 67 | 68 |
69 |
70 |

第二组:

71 |
72 |
73 |

444

74 | 75 | 76 |
77 |
78 |

555

79 | 80 | 81 |
82 |
83 |

第三组:

84 |
85 |
86 |

666

87 | 88 | 89 |
90 |
91 |

777

92 | 93 | 94 |
95 |
96 |

第四组:

97 |
98 |
99 |

888

100 | 101 | 102 |
103 |
104 |

999

105 | 106 | 107 |
108 |
109 |
110 | 111 | 112 | 133 | 134 | -------------------------------------------------------------------------------- /dragMove/js/dragMove.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.dragMove.js plugin 3 | */ 4 | ;(function($, window, document, undefined) { 5 | 6 | var plugName = "dragMove", 7 | defaults = { 8 | childClass: '.drag',// 9 | limit: false,// 限制在窗口内 10 | callback: function($move, $replace) {}// 交换位置成功后的回调 11 | }; 12 | 13 | function Drag($this, options) { 14 | this.name = plugName; 15 | this.defaults = defaults; 16 | this.options = $.extend({}, defaults, options); 17 | this.init(); 18 | } 19 | 20 | Drag.prototype = { 21 | init: function() { 22 | this.handle(); 23 | }, 24 | handle: function() { 25 | var This = this; 26 | 27 | // 拖动时禁止选择文本 28 | $('').appendTo('head'); 29 | $('[DR_drag]').addClass('DR_mid'); 30 | 31 | $(document).on('mousedown.DR', This.options.childClass, function(e) { 32 | if($('[DR_move]').length) return false; 33 | var $p = $(this).parent(); 34 | $p.attr('DR_move', true); 35 | var posX = $(this).position().left,// inner左上点相对outer左上点的位置 36 | posY = $(this).position().top, 37 | offX = e.offsetX,// 鼠标相对inner内部的位置 38 | offY = e.offsetY, 39 | mouseX = e.clientX,// 鼠标位置 40 | mouseY = e.clientY, 41 | oWidth = $p.width(), 42 | oHeight = $p.height(); 43 | 44 | $p.css({ 45 | width: $p.width(), 46 | height: $p.height() 47 | }); 48 | if(+$p.attr('DR_replace')) {// 拖动交换 49 | window.DR_replace = true; 50 | // 占位 51 | $('').css({ 52 | width: $p.outerWidth(), 53 | height: $p.outerHeight() 54 | }).addClass($('[DR_move]')[0].className).insertBefore($('[DR_move]')); 55 | }else {// 单纯拖动 56 | window.DR_replace = false; 57 | } 58 | 59 | $('body').addClass('DR_select'); 60 | $('[DR_move]').addClass('DR_maxIndex DR_fixed'); 61 | if(window.DR_replace) { 62 | $('[DR_move]').css({ 63 | left: mouseX - posX - offX, 64 | top: mouseY - posY - offY 65 | }); 66 | } 67 | 68 | $(document).on('mousemove.DR', function(e) { 69 | mouseX = e.clientX; 70 | mouseY = e.clientY; 71 | 72 | var diffX = mouseX - posX - offX, 73 | diffY = mouseY - posY - offY, 74 | maxW = $(window).width() - $('[DR_move]').outerWidth(); 75 | maxH = $(window).height() - $('[DR_move]').outerHeight(); 76 | 77 | // 限制范围 78 | if(This.options.limit) { 79 | if(diffX <= 0) { 80 | diffX = 0; 81 | } 82 | if(diffX >= maxW) { 83 | diffX = maxW; 84 | } 85 | if(diffY <= 0) { 86 | diffY = 0; 87 | } 88 | if(diffY >= maxH) { 89 | diffY = maxH; 90 | } 91 | } 92 | 93 | $('[DR_move]').css({'left': diffX, 'top': diffY}); 94 | }); 95 | }); 96 | 97 | $(document).on('mouseup.DR', function() { 98 | if(!$('[DR_move]').length) return false; 99 | if(window.DR_replace) {// 拖动交换 100 | window.DR_replace = false; 101 | var $that = $('[DR_move]'), 102 | DR_drag = $that.attr('DR_drag'), 103 | $all = $(This.options.childClass).parent('[DR_drag='+ DR_drag +']:not([DR_move])');// 相同的组才可交换位置 104 | if($all[0]) {// >=1 105 | $all.each(function(i) { 106 | var $obj = $(this), 107 | col_c = $that.offset().left + $that.outerWidth()/2, 108 | row_c = $that.offset().top + $that.outerHeight()/2, 109 | left = $obj.offset().left, 110 | left_w = $obj.offset().left + $obj.outerWidth(), 111 | top = $obj.offset().top, 112 | top_h = $obj.offset().top + $obj.outerHeight(); 113 | if(leftcol_c && toprow_c) { 114 | window.$DR_obj = $obj; 115 | // 删除虚线框 116 | $obj.after($('.DR_holder').clone().addClass('DR_holder_clone')); 117 | $('.DR_holder:not(.DR_holder_clone)').replaceWith($obj); 118 | 119 | $that.stop().animate({ 120 | left: $('.DR_holder_clone').offset().left, 121 | top: $('.DR_holder_clone').offset().top 122 | }, 100, function() { 123 | window.$DR_obj && This.options.callback($that, window.$DR_obj); 124 | window.$DR_obj = null; 125 | $('.DR_holder_clone').replaceWith($that); 126 | $that.removeAttr('style').removeAttr('DR_move'); 127 | $that.removeClass('DR_maxIndex DR_fixed'); 128 | }); 129 | }else { 130 | $that.stop().animate({ 131 | left: $('.DR_holder').offset().left, 132 | top: $('.DR_holder').offset().top 133 | }, 100, function() { 134 | window.$DR_obj && This.options.callback($that, window.$DR_obj); 135 | window.$DR_obj = null; 136 | $('.DR_holder').replaceWith($that); 137 | $that.removeAttr('style').removeAttr('DR_move'); 138 | $that.removeClass('DR_maxIndex DR_fixed'); 139 | }); 140 | } 141 | }); 142 | }else {// 0 143 | $that.stop().animate({ 144 | left: $('.DR_holder').offset().left, 145 | top: $('.DR_holder').offset().top 146 | }, 300, function() { 147 | $('.DR_holder').replaceWith($that); 148 | $that.removeAttr('style').removeAttr('DR_move'); 149 | $that.removeClass('DR_maxIndex DR_fixed'); 150 | 151 | }); 152 | } 153 | }else {// 单纯拖动 154 | $('[DR_move]').removeAttr('DR_move'); 155 | } 156 | 157 | $('body').removeClass('DR_select'); 158 | $(document).off('mousemove.DR'); 159 | }); 160 | }, 161 | } 162 | 163 | $.fn.extend({ 164 | dragMove: function(options) { 165 | return this.each(function() { 166 | new Drag($(this), options); 167 | }) 168 | } 169 | }) 170 | })(jQuery, window, document); -------------------------------------------------------------------------------- /face/README.md: -------------------------------------------------------------------------------- 1 | #### face说明文档 2 | 3 | * ###### demo示例 4 | [http://demo.vcxiaohan.com/jquery-plugins/face/demo.html](http://demo.vcxiaohan.com/jquery-plugins/face/demo.html) 5 | 6 | * ###### 功能简介 7 | 1. 该 *demo* 供用户选择的表情有2种,用户也可以根据需求拓展自定义表情 8 | 2. [微信表情压缩包下载](http://demo.vcxiaohan.com/jquery-plugins/face/src/wx.zip) 9 | 3. 该插件需[滚动条插件](https://github.com/vcxiaohan/jquery-plugins/tree/master/scrollbar)的支持 10 | 4. 完全支持手机端 11 | 5. 支持rem响应设计 12 | 13 | 14 | * ###### 使用说明 15 | 1. 选择好预使用的表情,点击“点击加载”按钮 16 | 2. 调用示例 17 | 18 | var Face = $('.textarea').face({ 19 | src: 'src/yun/',//表情路径 20 | rowNum: 7,//每行最多显示数量,此属性不适用于常用语 21 | ctnAttr: ['0rem', '0rem', '0.133rem', '0.122rem'],//[left bottom width height] 表情框相对targetEl位置和里面的表情格子宽高 要写单位 22 | triggerEl: $('.faceBtn'),//触发按钮(不存在则自己生成,不要由a包裹) 23 | targetEl: $('.editHide'),//父级参照物(用于appendTo和定位) 24 | hideAdv: true,//是否隐藏广告 25 | callback: function(data) {// 选择表情后回调 26 | console.log(data); 27 | }, 28 | }); -------------------------------------------------------------------------------- /face/css/face.css: -------------------------------------------------------------------------------- 1 | /* jquery.face.css */ 2 | .FA_backCtn { 3 | position: absolute; 4 | background: #fff; 5 | border-radius: 5px; 6 | border: 1px solid #d9d9d9; 7 | box-shadow: 0 0 20px 0 rgba(0, 0, 0, .15); 8 | padding: 10px; 9 | } 10 | 11 | .FA_ScrollCtn { 12 | position: relative; 13 | overflow: hidden; 14 | outline: 1px solid #DFEDFA; 15 | } 16 | 17 | .FA_faceCtn { 18 | position: absolute; 19 | top: 0; 20 | left: 0; 21 | } 22 | 23 | .FA_triBtn { 24 | background: url(../images/head_robot.png) no-repeat center; 25 | position: absolute; 26 | cursor: pointer; 27 | } 28 | 29 | .FA_moodCtn { 30 | float: left; 31 | text-align: center; 32 | background: #fff; 33 | cursor: pointer; 34 | outline: 1px solid #DFEDFA; 35 | } 36 | 37 | .FA_srcCtn { 38 | display: table-cell; 39 | vertical-align: middle; 40 | } 41 | 42 | .FA_moodCtn:hover { 43 | background: #e7f6ff; 44 | } 45 | 46 | .FA_moodCtn img { 47 | display: inline-block; 48 | vertical-align: middle; 49 | max-width: 100%; 50 | max-height: 100%; 51 | } 52 | 53 | .FA_advCtn {/*配置广告*/ 54 | height: 50px; 55 | background: #E7FAE0 url(../images/logo.png) no-repeat center; 56 | background-size: contain; 57 | margin-bottom: 10px; 58 | position: relative; 59 | } 60 | 61 | .FA_advCtn:hover .FA_closeAdvCtn {/*配置广告*/ 62 | display: block; 63 | } 64 | 65 | .FA_closeAdvCtn { 66 | position: absolute; 67 | width: 15px; 68 | height: 15px; 69 | line-height: 15px; 70 | top: 5px; 71 | right: 5px; 72 | background: #616161; 73 | border-radius: 100px; 74 | cursor: pointer; 75 | color: #fff; 76 | text-align: center; 77 | display: none; 78 | } 79 | 80 | .FA_switchCtn { 81 | margin-top: 15px; 82 | font-size: 0; 83 | background: #E4E5E5; 84 | } 85 | 86 | .FA_switchBtn { 87 | display: inline-block; 88 | width: 30px; 89 | height: 30px; 90 | cursor: pointer; 91 | } 92 | 93 | .FA_switchBtn_1 { 94 | background: url(../images/head_robot.png) no-repeat center; 95 | } 96 | .FA_switchBtn_2 { 97 | background: url(../images/head_smile.png) no-repeat center; 98 | } 99 | .FA_switchBtn_3 { 100 | background: url(../images/head_message.png) no-repeat center; 101 | } 102 | 103 | .FA_switchBtn_focus { 104 | background-color: #E4E5E5; 105 | position: relative; 106 | } 107 | 108 | .FA_switchBtn_focus:after { 109 | content: ''; 110 | display: block; 111 | position: absolute; 112 | top: -6px; 113 | left: 0; 114 | width: 0; 115 | height: 0; 116 | border-left: 15px solid transparent; 117 | border-right: 15px solid transparent; 118 | border-bottom: 6px solid #E4E5E5; 119 | } 120 | 121 | .FA_tipScrollCtn { 122 | position: absolute; 123 | outline: 1px solid #DFEDFA; 124 | overflow: hidden; 125 | } 126 | 127 | .FA_tipMoodCtn { 128 | position: absolute; 129 | top: 0; 130 | left: 0; 131 | } 132 | 133 | .FA_countLenCtn { 134 | position: absolute; 135 | background: red; 136 | overflow: auto; 137 | word-break: break-all; 138 | word-wrap: break-word; 139 | } 140 | 141 | .FA_markPos { 142 | display: inline-block; 143 | width: 2px; 144 | height: 18px; 145 | position: absolute; 146 | background: yellow; 147 | } 148 | -------------------------------------------------------------------------------- /face/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | demo 14 | 15 | 64 | 65 | 66 |
67 |
68 | 69 | 70 | 71 | 72 | 73 |

警告:旺旺表情禁止商用!

74 |
75 |
76 |
77 |
78 | 79 | 80 | 81 |
82 |
83 |
84 | 85 | 113 | -------------------------------------------------------------------------------- /face/js/face.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.face.js 3 | * 4 | * Copyright (c) 2016/5/24 Han Wenbo 5 | * 6 | **/ 7 | 8 | ;(function($, window, document, undefined) { 9 | var plugName = "face", 10 | defaults = { 11 | open: true,//默认开启功能 12 | src: 'src/yun/',//表情路径 13 | rowNum: 5,//每行最多显示数量,此属性不适用于常用语 14 | btnAttr: ['0px', '5px', '20px', '20px'],//[left bottom width height] 触发按钮相对targetEl的位置和宽高 要写单位 15 | ctnAttr: ['0px', '30px', '40px', '40px'],//[left bottom width height] 表情框相对targetEl位置和里面的表情格子宽高 要写单位 16 | triggerEl: null,//触发按钮(不存在则自己生成,不要由a包裹) 17 | targetEl: null,//父级参照物(用于appendTo和定位) 18 | hideAdv: false,//是否隐藏广告 19 | advClass: 'FA_advCtn',//广告样式 20 | callback: function(data) {},//获取表情符后的回调函数 21 | }; 22 | 23 | function Face($el, options) { 24 | this.plugName = plugName; 25 | this.$el = $el; 26 | this.prop = {}; 27 | this.obj = {}; 28 | this.$obj = {}; 29 | this.defaults = defaults; 30 | this.options = $.extend({}, defaults, options); 31 | this.init(); 32 | } 33 | 34 | Face.prototype = { 35 | init: function() { 36 | this.variable();//声明变量 37 | if(this.options.open) { 38 | this.baseProp();//$el的基础属性 39 | this.baseEl();//生成外边框 40 | this.event();//绑定事件 41 | } 42 | }, 43 | //声明变量 44 | variable: function() { 45 | this.obj.face = {//表情包 46 | '旺旺表情': [ 47 | ['[微笑]', '/::)'], 48 | ['[撇嘴]', '/::~'], 49 | ['[色]', '/::B'], 50 | ['[发呆]', '/::|'], 51 | ['[得意]', '/:8-)'], 52 | ['[流泪]', '/::<'], 53 | ['[害羞]', '/::$'], 54 | ['[闭嘴]', '/::X'], 55 | ['[尴尬]', '/::-|'], 56 | ['[发怒]', '/::@'],//10 57 | ['[调皮]', '/::P'], 58 | ['[呲牙]', '/::D'], 59 | ['[惊讶]', '/::O'], 60 | ['[难过]', '/::('], 61 | ['[酷]', '/::+'], 62 | ['[吐]', '/::T'], 63 | ['[偷笑]', '/:,@P'], 64 | ['[愉快]', '/:,@-D'], 65 | ['[困]', '/:|-)'], 66 | ['[惊恐]', '/::!'],//10 67 | ['[流汗]', '/::L'], 68 | ['[憨笑]', '/::>'], 69 | ['[奋斗]', '/:,@f'], 70 | ['[疑问]', '/:?'], 71 | ['[嘘]', '/:,@x'], 72 | ['[晕]', '/:,@@'], 73 | ['[衰]', '/:,@!'], 74 | ['[骷髅]', '/:!!!'], 75 | ['[再见]', '/:bye'], 76 | ['[糗大了]', '/:&-('],//10 77 | ['[坏笑]', '/:B-)'], 78 | ['[鄙视]', '/:>-|'], 79 | ['[委屈]', '/:P-('], 80 | ['[亲亲]', '/::*'], 81 | ['[可怜]', '/:8*'], 82 | ['[玫瑰]', '/:rose'], 83 | ['[凋谢]', '/:fade'], 84 | ['[嘴唇]', '/:showlove'], 85 | ['[爱心]', '/:heart'], 86 | ['[心碎]', '/:break']//10 87 | ], 88 | '微信表情': [ 89 | ["[微笑]", "/::)"], 90 | ["[撇嘴]", "/::~"], 91 | ["[色]", "/::B"], 92 | ["[发呆]", "/::|"], 93 | ["[得意]", "/:8-)"], 94 | ["[流泪]", "/::<"], 95 | ["[害羞]", "/::$"], 96 | ["[闭嘴]", "/::X"], 97 | ["[睡]", "/::Z"], 98 | ["[大哭]", "/::'("],//10 99 | ["[尴尬]", "/::-|"], 100 | ["[发怒]", "/::@"], 101 | ["[调皮]", "/::P"], 102 | ["[呲牙]", "/::D"], 103 | ["[惊讶]", "/::O"], 104 | ["[难过]", "/::("], 105 | ["[酷]", "/::+"], 106 | ["[冷汗]", "/:--b"], 107 | ["[抓狂]", "/::Q"], 108 | ["[吐]", "/::T"],//10 109 | ["[偷笑]", "/:,@P"], 110 | ["[愉快]", "/:,@-D"], 111 | ["[白眼]", "/::d"], 112 | ["[傲慢]", "/:,@o"], 113 | ["[饥饿]", "/::g"], 114 | ["[困]", "/:|-)"], 115 | ["[惊恐]", "/::!"], 116 | ["[流汗]", "/::L"], 117 | ["[憨笑]", "/::>"], 118 | ["[悠闲]", "/::,@"],//10 119 | ["[奋斗]", "/:,@f"], 120 | ["[咒骂]", "/::-S"], 121 | ["[疑问]", "/:?"], 122 | ["[嘘]", "/:,@x"], 123 | ["[晕]", "/:,@@"], 124 | ["[疯了]", "/::8"], 125 | ["[哀]", "/:,@!"], 126 | ["[骷髅]", "/:!!!"], 127 | ["[敲打]", "/:xx"], 128 | ["[再见]", "/:bye"],//10 129 | ["[擦汗]", "/:wipe"], 130 | ["[抠鼻]", "/:dig"], 131 | ["[鼓掌]", "/:handclap"], 132 | ["[糗大了]", "/:&-("], 133 | ["[坏笑]", "/:B-)"], 134 | ["[左哼哼]", "/:<@"], 135 | ["[右哼哼]", "/:@>"], 136 | ["[哈欠]", "/::-O"], 137 | ["[鄙视]", "/:>-|"], 138 | ["[委屈]", "/:P-("],//10 139 | ["[快哭了]", "/::'|"], 140 | ["[阴险]", "/:X-)"], 141 | ["[亲亲]", "/::*"], 142 | ["[吓]", "/:@x"], 143 | ["[可怜]", "/:8*"], 144 | ["[菜刀]", "/:pd"], 145 | ["[西瓜]", "/:"], 146 | ["[啤酒]", "/:beer"], 147 | ["[篮球]", "/:basketb"], 148 | ["[乒乓]", "/:oo"],//10 149 | ["[咖啡]", "/:coffee"], 150 | ["[饭]", "/:eat"], 151 | ["[猪头]", "/:pig"], 152 | ["[玫瑰]", "/:rose"], 153 | ["[凋谢]", "/:fade"], 154 | ["[嘴唇]", "/:showlove"], 155 | ["[爱心]", "/:heart"], 156 | ["[心碎]", "/:break"], 157 | ["[蛋糕]", "/:cake"], 158 | ["[闪电]", "/:li"],//10 159 | ["[炸弹]", "/:bome"], 160 | ["[刀]", "/:kn"], 161 | ["[足球]", "/:footb"], 162 | ["[瓢虫]", "/:ladybug"], 163 | ["[便便]", "/:shit"], 164 | ["[月亮]", "/:moon"], 165 | ["[太阳]", "/:sun"], 166 | ["[礼物]", "/:gift"], 167 | ["[拥抱]", "/:hug"], 168 | ["[强]", "/:strong"],//10 169 | ["[弱]", "/:weak"], 170 | ["[握手]", "/:share"], 171 | ["[胜利]", "/:v"], 172 | ["[抱拳]", "/:@)"], 173 | ["[勾引]", "/:jj"], 174 | ["[拳头]", "/:@@"], 175 | ["[差劲]", "/:bad"], 176 | ["[爱你]", "/:lvu"], 177 | ["[NO]", "/:no"], 178 | ["[OK]", "/:ok"],//10 179 | ["[爱情]", "/:love"], 180 | ["[飞吻]", "/:"], 181 | ["[跳跳]", "/:jump"], 182 | ["[发抖]", "/:shake"], 183 | ["[怄火]", "/:"], 184 | ["[转圈]", "/:circle"], 185 | ["[磕头]", "/:kotow"], 186 | ["[回头]", "/:turn"], 187 | ["[跳绳]", "/:skip"], 188 | ["[投降]", "/:oY"],//10 189 | ["[激动]", "/:#-0"], 190 | ["[乱舞]", "/:hiphot"], 191 | ["[献吻]", "/:kiss"], 192 | ["[左太极]", "/:<&"], 193 | ["[右太极]", "/:&>"] 194 | ] 195 | } 196 | this.obj.faceType = []; 197 | if(this.options.src.indexOf('wang')+1) {//旺旺表情 198 | this.obj.faceType[0] = '旺旺表情'; 199 | this.obj.faceType[1] = 'bmp'; 200 | this.obj.faceType[2] = 'gif'; 201 | } 202 | if(this.options.src.indexOf('wx')+1) {//微信表情 203 | this.obj.faceType[0] = '微信表情'; 204 | this.obj.faceType[1] = 'png'; 205 | this.obj.faceType[2] = 'gif'; 206 | } 207 | this.obj.maxNum_y = Math.ceil(this.obj.face[this.obj.faceType[0]].length/this.options.rowNum);//云问表情最大行数 208 | 209 | this.obj.showTip = false;//是否显示提示框 210 | this.obj.lastStrLen = 1;// 211 | }, 212 | //基础属性 213 | baseProp: function() { 214 | this.prop.winW = $(window).width(); 215 | this.prop.winH = $(window).height(); 216 | 217 | this.prop.width = this.$el.width(); 218 | this.prop.height = this.$el.height(); 219 | this.prop.outerWidth = this.$el.outerWidth(); 220 | this.prop.outerHeight = this.$el.outerHeight(); 221 | 222 | this.prop.zIndex = this.$el.css('zIndex'); 223 | 224 | this.prop.paddingLeft = parseInt(this.$el.css('paddingLeft')); 225 | this.prop.paddingTop = parseInt(this.$el.css('paddingTop')); 226 | this.prop.borderWidth = parseInt(this.$el.css('borderTopWidth')); 227 | 228 | this.prop.position = this.$el.position(); 229 | this.prop.offset = this.$el.offset(); 230 | 231 | this.prop.bottom = this.prop.winH - this.prop.offset.top; 232 | 233 | //是否rem 234 | this.prop.baseRem = parseInt($('html').css('fontSize')); 235 | }, 236 | //生成触发按钮和表情框 237 | baseEl: function() { 238 | var This = this, 239 | isRem = false; 240 | 241 | //rem 242 | if(This.options.ctnAttr.join(',').indexOf('rem') != -1) {//rem 243 | isRem = true; 244 | 245 | for(var i=0; i').css({ 256 | width: this.options.btnAttr[2], 257 | height: this.options.btnAttr[3], 258 | }).appendTo(this.options.targetEl); 259 | 260 | //触发按钮定位 261 | this.$obj.$FA_triBtn.css({ 262 | left: this.options.btnAttr[0], 263 | bottom: this.options.btnAttr[1], 264 | }); 265 | } 266 | 267 | //背景框 268 | this.$obj.$FA_backCtn = $('
').hide().css({ 269 | }).appendTo(this.options.targetEl); 270 | 271 | //滚动框 272 | this.$obj.$FA_ScrollCtn = $('
').css({ 273 | width: parseFloat(this.options.ctnAttr[2])*this.options.rowNum, 274 | height: parseFloat(this.options.ctnAttr[3])*4, 275 | }).appendTo(this.$obj.$FA_backCtn); 276 | 277 | //rem 278 | if(isRem) {//rem 279 | //背景框padding 280 | This.$obj.$FA_backCtn.css({ 281 | padding: (This.prop.baseRem - This.$obj.$FA_ScrollCtn.outerWidth())/2, 282 | }); 283 | } 284 | 285 | //表情框 286 | this.$obj.$FA_faceCtn = $('
').appendTo(this.$obj.$FA_ScrollCtn); 287 | 288 | //广告框 289 | this.$obj.$FA_advCtn = $('
').addClass(this.options.advClass).insertBefore(this.$obj.$FA_ScrollCtn); 290 | 291 | //关闭广告框 292 | this.$obj.$FA_closeAdvCtn = $('
×
').appendTo(this.$obj.$FA_advCtn); 293 | 294 | if(this.options.hideAdv) {//隐藏广告 295 | this.$obj.$FA_advCtn.hide(); 296 | } 297 | 298 | this.obj.moodIndex = 0; 299 | for(var key in this.obj.face) { 300 | this.obj.moodIndex++; 301 | if(key == this.obj.faceType[0]) {//选择表情 302 | var mood = this.obj.face[key], 303 | html = ''; 304 | for(var i=0; i'; 311 | title = mood[i][0]; 312 | mark = mood[i][1]; 313 | } 314 | 315 | html += '
'+ srcHtml +'
'; 316 | } 317 | this.$obj.$FA_faceCtn.append(html); 318 | } 319 | } 320 | 321 | //背景框定位 322 | this.$obj.$FA_backCtn.css({ 323 | left: this.options.ctnAttr[0], 324 | bottom: this.options.ctnAttr[1], 325 | }); 326 | 327 | //提示表情滚动框 328 | this.$obj.$FA_tipScrollCtn = $('
').css({ 329 | width: this.options.ctnAttr[2]+50, 330 | height: this.options.ctnAttr[3]*4, 331 | }).appendTo('body'); 332 | 333 | var $allMood = $('.FA_moodCtn[group=云问表情]').clone(); 334 | 335 | $allMood.each(function() { 336 | var mark = $(this).attr('mark'); 337 | 338 | $(this).find('.FA_srcCtn').css({ 339 | textIndent: 5, 340 | textAlign: 'left', 341 | width: This.options.ctnAttr[2]+50, 342 | }).find('img').after(''+ mark +''); 343 | }); 344 | 345 | //提示表情框 346 | this.$obj.$FA_tipMoodCtn = $('
').append($allMood).appendTo(this.$obj.$FA_tipScrollCtn); 347 | 348 | //计算文字框 349 | this.$obj.$FA_countLenCtn = $('
').css({ 350 | width: this.prop.width, 351 | height: this.prop.height, 352 | left: this.prop.offset.left+15, 353 | bottom: this.prop.bottom-this.prop.outerHeight-30, 354 | padding: this.prop.paddingTop +'px '+ this.prop.paddingLeft +'px', 355 | border: this.prop.borderWidth +'px solid blue', 356 | opacity: 0, 357 | zIndex: -999, 358 | }).hide().appendTo('body'); 359 | 360 | //计算文字标识符 361 | this.$obj.$FA_markPos = $('').css({ 362 | }).appendTo(this.$obj.$FA_countLenCtn); 363 | 364 | }, 365 | //绑定事件 366 | event: function() { 367 | var This = this; 368 | 369 | //调用滚动插件(表情框) 370 | This.obj.scrollbar = This.$obj.$FA_ScrollCtn.scrollbar({ 371 | }); 372 | This.$obj.$FA_tipScrollCtn.hide();//调用滚动插件后才能隐藏 373 | 374 | //选择表情 375 | This.options.targetEl.on('click.FA', '.FA_moodCtn', function() { 376 | var val = This.$el.val(), 377 | cursortPos = Base.getCursortPos(This.$el[0]), 378 | fromVal = val.substr(0, cursortPos), 379 | toVal = val.substr(cursortPos, val.length-1), 380 | mark = $(this).attr('mark'); 381 | 382 | This.$el.val(fromVal + mark + toVal); 383 | Base.setCaretPos(This.$el[0], cursortPos+mark.length); 384 | This.options.callback(This.$el.val()); 385 | This.$obj.$FA_backCtn.hide(); 386 | }); 387 | 388 | //初始化切换按钮状态 389 | $('.FA_switchBtn').eq(0).addClass('FA_switchBtn_focus').siblings().removeClass('FA_switchBtn_focus'); 390 | 391 | //点击切换 392 | $('body').on('click.FA', '.FA_switchBtn', function() { 393 | $(this).addClass('FA_switchBtn_focus').siblings().removeClass('FA_switchBtn_focus'); 394 | if($(this).is('.FA_switchBtn_1')) {//云问表情 395 | This.obj.scrollbar.scrollTo(This.obj.top1); 396 | } 397 | }); 398 | 399 | //显隐 400 | $(document).on('click.FA', function(e) { 401 | if(e.target == This.$obj.$FA_triBtn[0]) { 402 | $('[FA-src]').each(function() {//避免首次加载表情文件 403 | $(this).attr('src', $(this).attr('FA-src')).removeAttr('FA-src'); 404 | }); 405 | 406 | This.$obj.$FA_backCtn.stop().show(); 407 | 408 | This.obj.scrollbar.update(); 409 | This.obj.scrollbar.scrollTo('top'); 410 | 411 | //显示后才能获取top 412 | This.obj.top1 = 0; 413 | }else if($(e.target).is(This.$obj.$FA_backCtn) || $(e.target).parents('.FA_backCtn')[0]) { 414 | return false; 415 | }else { 416 | This.$obj.$FA_backCtn.stop().hide(); 417 | } 418 | }); 419 | 420 | //关闭广告 421 | This.$obj.$FA_closeAdvCtn.on('click.FA', function() { 422 | This.$obj.$FA_advCtn.stop().fadeOut(); 423 | }); 424 | 425 | This.$el.on('keydown.FA', function(e) { 426 | if(e.keyCode == 8) { 427 | This.obj.bindInput = false; 428 | }else { 429 | This.obj.bindInput = true; 430 | } 431 | }); 432 | }, 433 | update: function() { 434 | this.obj.scrollbar.update(); 435 | }, 436 | //转义表情 437 | replaceFace: function(data) { 438 | var src = this.options.src, 439 | faceType = this.obj.faceType, 440 | face = this.obj.face; 441 | 442 | for(var i in face) { 443 | if(i == faceType[0]) { 444 | for(var j=0; j'+ str2; 451 | } 452 | } 453 | } 454 | } 455 | return data; 456 | } 457 | } 458 | 459 | $.fn.extend({ 460 | face: function(options) { 461 | return new Face($(this), options); 462 | } 463 | }) 464 | })(jQuery, window, document); 465 | -------------------------------------------------------------------------------- /face/js/scrollbar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.scrollbar.js 3 | * 4 | * Copyright (c) 2016/5/25 Han Wenbo 5 | * 6 | **/ 7 | 8 | ;(function($, window, document, undefined) { 9 | var plugName = "scrollbar", 10 | defaults = { 11 | backClass: 'SC_backClass', 12 | frontClass: 'SC_frontClass', 13 | autoBottom: true,//内容改变,是否自动滚动到底部 14 | moveCallback: function(top, direction) {},//运动时事件回调 15 | stopCallback: function(top, direction) {},//停止时事件回调 16 | }; 17 | 18 | function Scrollbar($el, options) { 19 | this.plugName = plugName; 20 | this.$el = $el; 21 | this.prop = {}; 22 | this.child = {}; 23 | this.el = {}; 24 | this.defaults = defaults; 25 | this.options = $.extend({}, defaults, options); 26 | this.init(); 27 | } 28 | 29 | Scrollbar.prototype = { 30 | init: function() { 31 | this.variable();//声明变量 32 | this.baseEl();//生成滚动条的背景栏和拖动按钮 33 | this.event();//绑定事件 34 | }, 35 | //声明变量 36 | variable: function() { 37 | this.winW = $(window).width(); 38 | this.winH = $(window).height(); 39 | 40 | this.el.width = this.$el.width(); 41 | this.el.height = this.$el.height(); 42 | this.el.outerWidth = this.$el.outerWidth(); 43 | this.el.outerHeight = this.$el.outerHeight(); 44 | this.el.pos = this.$el.position(); 45 | this.el.position = this.$el.position(); 46 | this.el.borderWidth = parseInt(this.$el.css('borderTopWidth')); 47 | 48 | this.$child = this.$el.children(':not(script):eq(0)'); 49 | this.child.width = this.$child.width(); 50 | this.child.height = this.$child.height(); 51 | this.child.outerWidth = this.$child.outerWidth(); 52 | this.child.outerHeight = this.$child.outerHeight(); 53 | if(this.child.outerHeight'+ style +''); 111 | if(this.$el.css('position')=='static') { 112 | this.$el.css('position', 'relative'); 113 | } 114 | this.$el.addClass('SC_outer'); 115 | this.$child.addClass('SC_inner'); 116 | //背景栏 117 | this.$SC_backCtn = $('
').addClass(this.options.backClass).hide().appendTo(this.$el); 118 | 119 | //拖动块 120 | this.$SC_frontCtn = $('
').addClass(this.options.frontClass).appendTo(this.$SC_backCtn); 121 | 122 | this.frontLeft = (parseInt(this.$SC_backCtn.width())-parseInt(this.$SC_frontCtn.width()))/2; 123 | 124 | this.$SC_frontCtn.css({ 125 | left: this.frontLeft, 126 | }); 127 | this.maxTop = this.el.height-this.$SC_frontCtn.height();//拖动块最大top 128 | this.ratio = this.maxScroll/this.maxTop;//比率 129 | }, 130 | //绑定事件 131 | event: function() { 132 | var This = this, 133 | oldX = 0, 134 | oldY = 0, 135 | diffX = 0, 136 | diffY = 0, 137 | touchTimer = null; 138 | 139 | if(document.addEventListener) {//手机端(防止IE8-报错) 140 | This.$el[0].addEventListener('touchstart', function(e) { 141 | var targetTouches = e.targetTouches[0]; 142 | oldX = targetTouches.pageX; 143 | oldY = targetTouches.pageY; 144 | }); 145 | 146 | This.$el[0].addEventListener('touchmove', function(e) { 147 | clearInterval(touchTimer); 148 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeIn(); 149 | e.preventDefault();//阻止页面滚动 150 | 151 | var targetTouches = e.targetTouches[0]; 152 | 153 | var newX = targetTouches.pageX, 154 | newY = targetTouches.pageY; 155 | 156 | diffX = newX - oldX; 157 | diffY = newY - oldY; 158 | 159 | var childTop = This.$child.position().top, 160 | elH = This.$el.outerHeight(), 161 | childH = This.$child.outerHeight(); 162 | 163 | if(childTop<0 && childH>elH-childTop) { 164 | This.$child.css({'top': '+='+ diffY}); 165 | This.$SC_frontCtn.css({'top': -(This.$child.position().top)/This.ratio}); 166 | }else { 167 | This.$child.css({'top': '+='+ diffY/3}); 168 | } 169 | 170 | oldX = newX; 171 | oldY = newY; 172 | }); 173 | 174 | This.$el[0].addEventListener('touchend', function(e) { 175 | var targetTouches = e.targetTouches[0]; 176 | 177 | var childTop = This.$child.position().top, 178 | elH = This.$el.outerHeight(), 179 | childH = This.$child.outerHeight(); 180 | 181 | if(childTop>=0) {//上出现空白 182 | This.$child.stop().animate({'top': '0'}, 300, function() { 183 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeOut(); 184 | }); 185 | This.options.stopCallback(parseInt(This.$child.css('top')), -1); 186 | }else if(childH<=elH-childTop) { 187 | if(childH < elH) {//下出现空白 188 | This.$child.stop().animate({'top': '0'}, 300, function() { 189 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeOut(); 190 | }); 191 | }else { 192 | This.$child.stop().animate({'top': elH-childH}, 300, function() { 193 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeOut(); 194 | }); 195 | } 196 | This.options.stopCallback(parseInt(This.$child.css('top')), 1); 197 | }else {//缓动停止 198 | clearInterval(touchTimer); 199 | touchTimer = setInterval(function() { 200 | childTop = This.$child.position().top;//更新childTop 201 | 202 | if(childTop>=0) {//上出现空白 203 | This.$child.css({'top': '0'}); 204 | clearInterval(touchTimer); 205 | This.options.stopCallback(parseInt(This.$child.css('top')), -1); 206 | }else if(childH<=elH-childTop) {//下出现空白 207 | This.$child.css({'top': elH-childH}); 208 | clearInterval(touchTimer); 209 | This.options.stopCallback(parseInt(This.$child.css('top')), 1); 210 | }else {//运动中 211 | if(Math.abs(diffY)>1) { 212 | This.$child.css({'top': '+='+ diffY}); 213 | This.$SC_frontCtn.css({'top': -(This.$child.position().top)/This.ratio}); 214 | diffY *= .95; 215 | }else { 216 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeOut(); 217 | clearInterval(touchTimer); 218 | } 219 | This.options.moveCallback(parseInt(This.$child.css('top')), -diffY<0?-1:1); 220 | } 221 | }, 20); 222 | } 223 | 224 | }); 225 | } 226 | 227 | //鼠标滚动(手机端无滚轮) 228 | This.$el.add(This.$SC_backCtn).add(This.$SC_frontCtn).on('mousewheel.SC', function(event, delta) { 229 | This.delta = -delta;// 230 | 231 | if(This.delta<0) {//向上滚 232 | var top = Math.abs(parseInt(This.$child.css('top'))), 233 | once = Math.abs(This.delta*This.deltaFactor); 234 | 235 | if(top0) {//向下滚 249 | var top = Math.abs(parseInt(This.$child.css('top'))), 250 | bottom = Math.abs(parseInt(This.maxScroll-top)), 251 | once = Math.abs(This.delta*This.deltaFactor); 252 | 253 | if(bottom= This.maxTop) {// 292 | endTop = This.maxTop; 293 | } 294 | 295 | This.$SC_frontCtn.css({//拖动按钮滚动 296 | top: endTop, 297 | }); 298 | 299 | This.$child.css({//div滚动 300 | top: -endTop*This.ratio, 301 | }); 302 | This.options.moveCallback(parseInt(This.$child.css('top')), diffClientY<0?-1:1); 303 | }); 304 | }); 305 | 306 | //取消拖动 307 | $(document).on('mouseup.SC', function() { 308 | $(this).off('mousemove.SC'); 309 | $(document).off('selectstart.SC'); 310 | $('body').removeClass('SC_select_no'); 311 | }); 312 | 313 | //监听内容变化(兼容性不好) 314 | /*This.$child.on('DOMNodeInserted.SC', function() { 315 | This.update();//更新 316 | });*/ 317 | 318 | This.text = This.$el.text(); 319 | 320 | This.timer = setInterval(function() { 321 | var newtext = This.$el.text(); 322 | 323 | if(This.text != newtext) { 324 | This.update(); 325 | This.text = This.$el.text(); 326 | if(This.options.autoBottom) { 327 | This.scrollTo('bottom'); 328 | } 329 | } 330 | }, 100); 331 | 332 | //浏览器缩放 333 | $(window).on('resize.SC', function() { 334 | This.update();//更新 335 | }); 336 | 337 | //渐隐渐显 338 | This.$el.hover(function() { 339 | This.$SC_backCtn.stop().fadeIn(); 340 | }, function() { 341 | This.$SC_backCtn.stop().fadeOut(); 342 | }); 343 | }, 344 | //更新 345 | update: function() { 346 | this.el.height = this.$el.height(); 347 | this.el.outerHeight = this.$el.outerHeight(); 348 | this.child.outerHeight = this.$child.outerHeight(); 349 | 350 | if(this.child.outerHeight 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | demo 10 | 11 | 29 | 30 | 31 |

请尽量上传大一点的文件,方便查看过程(图片资源会自动显示预览图)

32 | 33 |
34 | 35 | 64 | -------------------------------------------------------------------------------- /h5Upload/js/h5Upload.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.h5Upload.js 3 | * 4 | * Copyright (c) 2017/4/25 Han Wenbo 5 | * 6 | **/ 7 | 8 | ;(function($, window, document, undefined) { 9 | var plugName = "h5Upload", 10 | defaults = { 11 | url: '',// 上传接口,后台接口须支持接收多文件 12 | maxNum: 0,// 单次最大上传数量 13 | $trigger: null,// 触发上传的input 14 | $drag: $(document),// 上传进度和图片预览显示的框 15 | startcall: function(ran) {},// 开始上传时的回调 16 | callback: function(data, ran) {},// 上传结束后的回调 17 | type: '',// 允许上传的文件格式,如:gif|jpeg|bmp|jpg|png 为空时不限制格式 18 | typecall: function(noSuit) {},// 不符合文件类型时的回调 19 | }; 20 | 21 | function H5Upload($el, options) { 22 | this.plugName = plugName; 23 | this.$el = $el; 24 | this.defaults = defaults; 25 | this.options = $.extend({}, defaults, options); 26 | this.init(); 27 | } 28 | 29 | H5Upload.prototype = { 30 | init: function() { 31 | this.variable();// 声明变量 32 | this.event();// 绑定事件 33 | }, 34 | // 声明变量 35 | variable: function() { 36 | var style = 37 | '.upFileMask {'+ 38 | 'width: 100%;'+ 39 | 'height: 100%;'+ 40 | 'top: 0;'+ 41 | 'left: 0;'+ 42 | 'background: rgba(0, 0, 0, 0.4);'+ 43 | 'position: fixed;'+ 44 | 'z-index: 19930606;'+ 45 | '}'+ 46 | '.upFileCtn {'+ 47 | 'padding: 10px;'+ 48 | 'text-align: center;'+ 49 | 'position: absolute;'+ 50 | 'top: 50%;'+ 51 | 'left: 50%;'+ 52 | 'transform: translate(-50%, -50%);'+ 53 | 'max-height: 80%;'+ 54 | 'overflow: auto;'+ 55 | '}'+ 56 | '.upFileItem {'+ 57 | 'display: inline-block;'+ 58 | 'padding: 0 5px;'+ 59 | '}'+ 60 | '.upFileImg {'+ 61 | 'border: 0;'+ 62 | 'max-height: 200px;'+ 63 | '}'+ 64 | '.upFileName {'+ 65 | 'color: #fff;'+ 66 | 'font-size: 12px;'+ 67 | 'text-align: center;'+ 68 | 'margin-bottom: 5px;'+ 69 | '}'+ 70 | '.upFileAbort {'+ 71 | 'position: absolute;'+ 72 | 'right: 0;'+ 73 | 'top: 0;'+ 74 | 'background: #3d3f40;'+ 75 | 'color: #fff;'+ 76 | 'border-radius: 100%;'+ 77 | 'font-size: 12px;'+ 78 | 'cursor: pointer;'+ 79 | 'width: 15px;'+ 80 | 'height: 15px;'+ 81 | 'line-height: 15px;'+ 82 | '}'+ 83 | '.upFileOuter {'+ 84 | 'height: 5px;'+ 85 | 'background: #1a1a1a;'+ 86 | 'position: relative;'+ 87 | 'border-radius: 5px;'+ 88 | 'overflow: hidden;'+ 89 | '}'+ 90 | '.upFileInner {'+ 91 | 'display: inline-block;'+ 92 | 'height: 100%;'+ 93 | 'background: #5e90d6;'+ 94 | 'position: absolute;'+ 95 | 'top: 0;'+ 96 | 'left: 0;'+ 97 | '}'; 98 | 99 | if(!$('[UP]')[0]) { 100 | $('head').append(''); 101 | } 102 | 103 | // 无法预览base64 104 | this.base64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABYCAYAAABiQnDAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkI1Q0NBQjg1NUExNzExRTY5RTEzREZFNTRENzc4RkFGIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkI1Q0NBQjg2NUExNzExRTY5RTEzREZFNTRENzc4RkFGIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QjVDQ0FCODM1QTE3MTFFNjlFMTNERkU1NEQ3NzhGQUYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QjVDQ0FCODQ1QTE3MTFFNjlFMTNERkU1NEQ3NzhGQUYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4+S+GgAAAGC0lEQVR42uyc2ys9WxzAZ7vnkvs1xAsKDxIexAOhlGd/zvmdP8eLlFI8SHlAEuUSItcQQrnk7vRZne8+s8dmX2ZfHPv7rdWePbPWrLU+63ub2TPbc3Jy8mEllngiebIkK/Hkr0ieLEU2ysvLfzW109NT2fzz7+ffqoHhy59IaWKiAowYxEQGGBGIiQ7QNUQF6BKiAnQJUQG6hKgAXUJUgC4hKkCXEBWgS4gK0CVEBegSogJ0CVEBuoSoAF1CVIAuISYMwLS0tGhA/EgYgLm5udGA+N9vIr9dUlJSrMLCwoidT35jiZsGPj4+um7/8RH/X2TjApCJ39zcWO/v72G1px3tf4LEBeDr66uBeH9/H1Z72tGe8yQkwKenJ1dmLO3lM6EA2jXv7e0tbA22a2JCAXTj+36iL4wYwLu7u2+1gWPX19c+ZktqEW5KYo/GnDdQ34wvKulRJE3z/PzcysrKsjIyMswkxdHjqzA3p+alp6eH1RftXl5efCAG6jszM/NnA2TwDPT29taUQOLxeEwbN33ZtY7F+apvN33FzISTkpKsvLy8oOtTlzY/va+YBhHMJz8/36z4d5pHHer+X/qK6bUwgy0pKTEmhm/CDzER/BK+C1OKlDbEsq+Y3kxg0Dk5OaZEPY2IYV8/5krkN4kCVIAKUAEqQBUFGC+J+49KJMDPz88mCeb+INe39iJXFPaSnJxskmV+ZYvmVYZqYCJoIBoUby1SDVSAClABqihABagAFaCKAlSAClABqihABagAFaBKMOKZn5//UAyqgXET7y396upqpRGCHB4eqgaqCSvAX+QDYyEPDw/mafqamppPx2ZnZ63S0lKrrq7OZz9P4zvfBUlNTTX7v3pVjGei/T1DfXFxYR0fH1stLS1me3Nz02ptbXX1BH/IALe3t63l5eWg6gKDwYrs7e1Za2tr1sbGhtXW1mYVFxd7j52cnFjZ2dmfzgG86enpT/uLioqsy8tLv/3SpwCU8Q4PD5v3SfjOcUDSZ0FBgVkQkdraWp/vEQfIQ9t2KAgDZEJVVVWf6tqlsbHRPNO8uLhotIfCYx0iV1dXZoLSFsCUgYEBrwajqfRv19SxsTHzH7AdHR1Bz+Pg4MA8R80nY5CXsQEYVQ2USTkBAs9pfl+1HxwcNNsTExM+73WgUaJVnEv62dra8r7gjPlzDBO0a+b+/r4pCNr2nVCPF3BYmNXVVbOvq6srPj4QrQi23tLSktXQ0OAFIyCRkZGRTyYvgmaJKaIt9reUmpqavCaHiQrE74R6LARm3tzcbE1OTlrr6+vGQqIKEJ+BCfkTJufPN4q5ibmiNV+BCsbnMobR0VHjMhBxCZgwZu8EWFlZaXwrGgt4nuZnH9vsE60Oxe+FDZBo5Zz40dGR1+y+84NoXW9vrwHChPwFI/aJD0SGhoYMIDTQHgBoV1ZW9mUQcY6ZgGHvy19QCvcPKUIC6C89AKBERCJaID/IccyZFZfF2NnZMb7Qbo6SrgDA2SfOH7ChCgsiPpWFlXOMj4/HJ5HGBADn1LpAMjMzYzQKmJgT8DAjfBATYz/Fn1mhve3t7T777FE0kDZS0GT6l+9xuRLBh+B70IavQj+O2RlkGDzAxLTRBgRnLjmf3Yz9WUFFRYWByycgiKicD4jsCyboEdXFB8YcIPDm5+cNCLTBn6ZQh6QZ/2MfPEk0k8QnAkz8GucQAPirQG+iA5KrCMwfF7K7u2sK+5yCqZKm0P/c3JxZdMYOfKSnp8eqr68PKoK7TmPoZGVlxaw6zt2+4vZEWC6z7Mk0ORftmCSAMWUEqM6AQl3JzcTk7AshVzVE1e7ubu/5pqamrP7+fq9pUpeCryaDoD7H8XuMUbSQBVtYWAhKi8MGKJ0wiM7OTp+EWqKjPTKKptl9FYFCJsc/CTFg/BpvVkqRqMnEqSuRHj/Jd2CdnZ2ZPuXSi9LX12csg36oR3uAsmiMhQUROPhYZ9RHk0OBh3hv6Qd7QxWIobzs7M+0A+Vc1KFE4jV9ifjh5nmBbqiGbMJu4ElqEkydSE04Wv+VoPcDFaAC/F13pMUpqqgGxlT+EWAAIaBk3UBJfHwAAAAASUVORK5CYII='; 105 | this.fileData = [];// fileData 为数组 106 | }, 107 | // 绑定事件 108 | event: function() { 109 | var This = this; 110 | 111 | This.options.$drag.on('drop.UP', function(e) { 112 | e.stopPropagation(); 113 | This.fileData = e.originalEvent.dataTransfer.files; 114 | This.autoUpload(This.options.url, This.options.$trigger, This.options.startcall, This.options.callback, This.options.type, This.options.typecall); 115 | return false; 116 | }).on('dragleave.UP dragenter.UP dragover.UP', function(e) { 117 | e.stopPropagation(); 118 | return false; 119 | }) 120 | This.h5Upload(This.options.url, This.options.maxNum, This.options.$trigger, This.options.startcall, This.options.callback, This.options.type, This.options.typecall); 121 | }, 122 | // 上传方法 123 | h5Upload: function(url, maxNum, $trigger, startcall, callback, type, typecall) { 124 | var This = this; 125 | 126 | $trigger.on('change.UP', function() { 127 | This.fileData = []; 128 | try { 129 | var len = maxNum ? (maxNum>$trigger[0].files.length?$trigger[0].files.length:maxNum) : $trigger[0].files.length; 130 | for(var i=0; i'), 174 | $upFileAbort = $('×'), 175 | $upFileOuter = $('
'), 176 | $upFileInner = $(''); 177 | 178 | for(var i=0,len=This.fileData.length; i'), 181 | $upFileName = $('

'+ This.fileData[i].name +'

'); 182 | 183 | $upFileName.appendTo($upFileItem); 184 | $upFileItem.appendTo($upFileCtn); 185 | 186 | try { 187 | var reader = new FileReader();//IE9-不支持FileReader 188 | if(This.fileData[i].type.indexOf('image')+1) {//可预览 189 | reader.readAsDataURL(This.fileData[i]); 190 | reader.onload = function(e) { 191 | var $upFileImg = $(''); 192 | var $upFileName = $('.upFileName'); 193 | for(var j=0,len=$upFileName.length; j'); 203 | $upFileImg.insertBefore($upFileName); 204 | } 205 | }catch(e) {} 206 | } 207 | } 208 | 209 | var $upFileMask = $('
'); 210 | $upFileCtn.append($upFileAbort); 211 | $upFileCtn.append($upFileOuter); 212 | $upFileOuter.append($upFileInner); 213 | $upFileCtn.append($upFileOuter); 214 | $upFileMask.append($upFileCtn); 215 | 216 | $('body').append($upFileMask); 217 | 218 | //取消上传 219 | $upFileAbort.on('click', function() { 220 | xhr.abort(); 221 | $upFileMask.remove(); 222 | $('.FA_'+ ran).parents('.MN_ask').remove(); 223 | }); 224 | $trigger[0].value = null;//清空文件路径 225 | }, 226 | progress: function(e, ran, xhr) { 227 | if (e.lengthComputable) { 228 | var $upFileInner = $('.'+ ran +' em'); 229 | 230 | $upFileInner.width(e.loaded/e.total*100 +'%'); 231 | } 232 | }, 233 | load: function(e, ran) { 234 | var $upFileMask = $('.'+ ran).remove(); 235 | callback && callback(JSON.parse(e.currentTarget.response), ran); 236 | } 237 | }); 238 | }, 239 | // 上传文件 240 | uploadFile: function(options) { 241 | var form = new FormData(),//FormData 对象 242 | ran = ('ran'+ Math.random()).replace(/\./, ''),//唯一标识符 243 | formData = options.data;// 表单数据载体数组 244 | 245 | formData = options.beforeload(formData); 246 | 247 | var formLen = false; 248 | for(var key in formData) { 249 | var val = formData[key]; 250 | if(val instanceof Array) {//hack数组对象 251 | for(var i=0,len=val.length; i 2 | 3 | 4 | 5 | 6 | 7 | 8 | demo 9 | 10 | 22 | 23 | 24 |
25 |

选择相应的插件

26 | 49 |
50 | 51 | 53 | 54 | -------------------------------------------------------------------------------- /input/README.md: -------------------------------------------------------------------------------- 1 | #### dragMove 说明文档 2 | 3 | * ###### demo示例 4 | [http://demo.vcxiaohan.com/jquery-plugins/scrollbar/demo.html](http://demo.vcxiaohan.com/jquery-plugins/scrollbar/demo.html) 5 | 6 | * ###### 功能简介 7 | 1. 该 *demo* 已包含插件本身和使用示例,您也可以将插件单独抽出,引用使用 8 | 2. 该拖动效果的实现思路是通过拖动子元素,来移动父元素 9 | 3. 效果分为2种: 10 | * 单纯的拖动 11 | * 拖动交换位置 12 | 4. *demo* 效果介绍 13 | * 第一组可以和第二组交换 14 | * 第三组只能组内交换 15 | * 第四组是单纯的拖动 16 | * 后添加的元素都要加上 *DR_mid* 的类名(防止位置对不齐) 17 | 18 | * ###### 使用说明 19 | 1. 内部名词解释 20 | * 类名 *DR_drag* 是用来分组的,是我们主动拖动的子元素-必需 21 | * 类名 *DR_replace* (0-单纯拖动-非必需 1-交换位置-必需) 是用来识别当前元素是否可与同组内元素交换位置 22 | * 类名 *drag* 是我们拖动的子元素,可配置-必需 23 | 2. 调用示例 24 | 25 | $('body').dragMove({ 26 | limit: true,// 限制在窗口内 27 | callback: function($move, $replace) { 28 | console.log('拖动了'+ $('p', $move).text() +'跟'+ $('p', $replace).text() +'进行交换'); 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /input/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | demo 10 | 11 | 31 | 32 | 33 |

暂未开发完毕

34 |
35 | 36 | 37 | 38 | 39 |
40 | 41 | 50 | -------------------------------------------------------------------------------- /input/js/input.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.input.js plugin 3 | */ 4 | ;(function($, window, document, undefined) { 5 | 'use strict'; 6 | 7 | var plugName = "input", 8 | defaults = { 9 | noInput: '',// 不使用该插件的元素 10 | maxLengthFormat: '$/$',// 最大字数显示格式 11 | }; 12 | 13 | function Input($this, options) { 14 | this.name = plugName; 15 | this.defaults = defaults; 16 | this.options = $.extend({}, defaults, options); 17 | this.$el = $this; 18 | this.init(); 19 | } 20 | 21 | Input.prototype = { 22 | init: function() { 23 | this.createEl();// 生成元素 24 | this.events();// 绑定事件 25 | }, 26 | // 生成元素 27 | createEl: function() { 28 | var This = this; 29 | 30 | var style = 31 | ''; 32 | 33 | //$('').appendTo('head'); 34 | 35 | 36 | }, 37 | // 绑定事件 38 | events: function() { 39 | var This = this; 40 | $('input:not('+ This.options.noInput +'), textarea:not('+ This.options.noInput +')', This.$el).each(function() { 41 | $(this).wrap('
'); 42 | $(this).after(''+ $(this).attr('IN-placeholder') +'');// 提示语 43 | //if($(this).attr('IN-maxLength')) { 44 | $(this).after('');// 最大字数 45 | //} 46 | }).on("input.IN propertychange.IN keyup.IN", function() { 47 | This.maxLength($(this)); 48 | if($(this).val()) { 49 | $(this).next().hide(); 50 | }else { 51 | $(this).next().show(); 52 | } 53 | }); 54 | 55 | }, 56 | // 最大字数 57 | maxLength: function($obj/*$input, $tip, $word*/) { 58 | var maxNum = $(obj).attr('IN-maxLength'), 59 | maxLengthFormat = this.options.maxLengthFormat.split(''); 60 | 61 | if(maxNum && maxLengthFormat[0]) { 62 | var prefix = maxLengthFormat[0], 63 | suffix = maxLengthFormat[0]; 64 | } 65 | 66 | /*var nowNum = 0, 67 | maxNum = this.options.remainWordNum, 68 | word = $input.val(), 69 | len = word.toString().length; 70 | 71 | if(len > maxNum) { 72 | word = word.substr(0, maxNum); 73 | $input.val(word); 74 | len = word.toString().length; 75 | } 76 | $word.text(maxNum - len);*/ 77 | } 78 | } 79 | 80 | $.fn.extend({ 81 | input: function(options) { 82 | return this.each(function() { 83 | new Input($(this), options); 84 | }) 85 | } 86 | }) 87 | })(jQuery, window, document); -------------------------------------------------------------------------------- /js/jquery.mousewheel.all.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Mousewheel 3.1.13 3 | * 4 | * Copyright 2015 jQuery Foundation and other contributors 5 | * Released under the MIT license. 6 | * http://jquery.org/license 7 | */ 8 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}); -------------------------------------------------------------------------------- /scrollbar/README.md: -------------------------------------------------------------------------------- 1 | #### scrollbar 说明文档 2 | 3 | * ###### demo 示例 4 | 1. [http://demo.vcxiaohan.com/jquery-plugins/scrollbar/demo.html](http://demo.vcxiaohan.com/jquery-plugins/scrollbar/demo.html) 5 | 6 | * ###### 功能简介 7 | 1. 该插件需要配合 *jquery.mousewheel* 使用 8 | 2. 可自定义滚动条样式 9 | 3. 内容改变时可自动滚动到底部 10 | 4. 兼容ie8+、手机端 11 | 5. 支持嵌套使用(滚动条内部可再包含滚动条) 12 | 13 | * ###### 使用说明 14 | 1. 内部名词解释 15 | * 调用插件的父级元素有且仅有一个子级元素 16 | 2. 调用示例 17 | 18 | var scrollbar = $('.bOuter').scrollbar({ 19 | backClass: 'customBackClass', 20 | frontClass: 'customFrontClass', 21 | autoBottom: false,//内容改变,是否自动滚动到底部 22 | callback: function(curPos, delta) {//滚动时事件回调 23 | console.log(curPos, '当前top值为'+ curPos +'px', delta, delta==1?'向下滚':'向上滚'); 24 | } 25 | }); 26 | -------------------------------------------------------------------------------- /scrollbar/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | demo 11 | 12 | 102 | 103 | 104 |
105 |
106 |

demo1

107 |
108 |
109 |

假如生活欺骗了你

110 |

人生很短暂,一辈子能遇到几个真心懂你的、爱你的知心朋友,也许你沮丧、失落。可是空落落的心哪能承受的起那么多。曾经假想,假如那一切没发生,爱你的人没有离你而去,又会怎样,假如生活欺骗了你,你是否可以坦然面对呢?你是否可以宽容以待?

111 |

逝去的已逝去,何必留恋呢?没有人会同情弱者,你只有崛起,那又何必悲伤、何必停留。世界没有你照样转。哪有为何做不必要的等待、牺牲。

112 |

生活很美好,现实很骨感,那有何必因为一些事、一些人所牵绊呢?

113 |

假如生活欺骗了你,不要悲伤、不要抱怨。从现在起,收获所拥有的,忘却没有的,这样你才会慢慢坚强起来。

114 |

假如生活欺骗了你,即使暂时无法抚平受伤的心灵,总有一天幸福会降临。

115 |

假如生活欺骗了你,学会包容,学会孤单,即使寂寞,也不要表现出来,不要给小瞧你的人机会鄙视,学会隐忍。

116 |

也许生活并没有童话的美好,但是领悟了就好了,人性的自私并不是你所能改变,学会适应才是王道也。

117 |

也许生活并不是预料的美好,请不要忧伤,人生并不是一帆风顺,即使失败,笑着面对,一切都会过去。

118 |

也许容易得到的,你不一定珍惜,那又何必呢?坎坷的路上,虽然艰辛,但拥有一颗恒心,梦想总会花开。

119 |

暂时的失败并不代笔什么,重要的是你要拥有一颗平常心,微笑的对待,生活会更美好。

120 |

这一刻,也许你跌倒了,也许跌疼了,也许落泪了,请不要伤心。擦干你的泪水继续前行。总有一天你会体会收获的喜悦。

121 |

看远处的鲜花在向你招手,哭泣后的喜悦马上要降临。加油。

122 |

生活欺骗了你,只是为你下一次的路途搬走拌石,生活欺骗了你,只是为了你下一次的重生。那又何必纠结呢?为何不收起你那份受伤的心呢?选择原谅,选择坚强。才会让此刻的你继续前行。那就放手,丢去不必要的烦恼。继续航帆前行。

123 |
124 |
125 |
126 |
127 |

demo2

128 |
129 |
130 |

假如生活欺骗了你

131 |

人生很短暂,一辈子能遇到几个真心懂你的、爱你的知心朋友,也许你沮丧、失落。可是空落落的心哪能承受的起那么多。曾经假想,假如那一切没发生,爱你的人没有离你而去,又会怎样,假如生活欺骗了你,你是否可以坦然面对呢?你是否可以宽容以待?

132 |

逝去的已逝去,何必留恋呢?没有人会同情弱者,你只有崛起,那又何必悲伤、何必停留。世界没有你照样转。哪有为何做不必要的等待、牺牲。

133 |

生活很美好,现实很骨感,那有何必因为一些事、一些人所牵绊呢?

134 |

假如生活欺骗了你,不要悲伤、不要抱怨。从现在起,收获所拥有的,忘却没有的,这样你才会慢慢坚强起来。

135 |

假如生活欺骗了你,即使暂时无法抚平受伤的心灵,总有一天幸福会降临。

136 |

假如生活欺骗了你,学会包容,学会孤单,即使寂寞,也不要表现出来,不要给小瞧你的人机会鄙视,学会隐忍。

137 |

也许生活并没有童话的美好,但是领悟了就好了,人性的自私并不是你所能改变,学会适应才是王道也。

138 |

也许生活并不是预料的美好,请不要忧伤,人生并不是一帆风顺,即使失败,笑着面对,一切都会过去。

139 |

也许容易得到的,你不一定珍惜,那又何必呢?坎坷的路上,虽然艰辛,但拥有一颗恒心,梦想总会花开。

140 |

暂时的失败并不代笔什么,重要的是你要拥有一颗平常心,微笑的对待,生活会更美好。

141 |

这一刻,也许你跌倒了,也许跌疼了,也许落泪了,请不要伤心。擦干你的泪水继续前行。总有一天你会体会收获的喜悦。

142 |

看远处的鲜花在向你招手,哭泣后的喜悦马上要降临。加油。

143 |

生活欺骗了你,只是为你下一次的路途搬走拌石,生活欺骗了你,只是为了你下一次的重生。那又何必纠结呢?为何不收起你那份受伤的心呢?选择原谅,选择坚强。才会让此刻的你继续前行。那就放手,丢去不必要的烦恼。继续航帆前行。

144 |
145 |
146 |
147 |
148 | 149 | 150 | 151 | 152 |
153 |
154 |

demo解释

155 |

1. demo1 是最简单的调用示例

156 |

2. demo1 内容改变会自动滚动到最底部

157 |

3. demo2 内容改变不会自动滚动到最底部,且滚动条样式可自定义

158 |

4. 可设置滚动到固定位置,滚动过程中提供钩子

159 |

5. 插件可嵌套使用(如:body和demo1、2嵌套使用)

160 |
161 |
162 |
163 | 164 | 226 | -------------------------------------------------------------------------------- /scrollbar/js/scrollbar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jquery.scrollbar.js 3 | * 4 | * Copyright (c) 2016/5/25 Han Wenbo 5 | * 6 | **/ 7 | 8 | ;(function($, window, document, undefined) { 9 | var plugName = "scrollbar", 10 | defaults = { 11 | backClass: 'SC_backClass', 12 | frontClass: 'SC_frontClass', 13 | autoBottom: true,//内容改变,是否自动滚动到底部 14 | moveCallback: function(top, direction) {},//运动时事件回调 15 | stopCallback: function(top, direction) {},//停止时事件回调 16 | }; 17 | 18 | function Scrollbar($el, options) { 19 | this.plugName = plugName; 20 | this.$el = $el; 21 | this.prop = {}; 22 | this.child = {}; 23 | this.el = {}; 24 | this.defaults = defaults; 25 | this.options = $.extend({}, defaults, options); 26 | this.init(); 27 | } 28 | 29 | Scrollbar.prototype = { 30 | init: function() { 31 | this.variable();//声明变量 32 | this.baseEl();//生成滚动条的背景栏和拖动按钮 33 | this.event();//绑定事件 34 | }, 35 | //声明变量 36 | variable: function() { 37 | this.winW = $(window).width(); 38 | this.winH = $(window).height(); 39 | 40 | this.el.width = this.$el.width(); 41 | this.el.height = this.$el.height(); 42 | this.el.outerWidth = this.$el.outerWidth(); 43 | this.el.outerHeight = this.$el.outerHeight(); 44 | this.el.pos = this.$el.position(); 45 | this.el.position = this.$el.position(); 46 | this.el.borderWidth = parseInt(this.$el.css('borderTopWidth')); 47 | 48 | this.$child = this.$el.children(':not(script):eq(0)'); 49 | this.child.width = this.$child.width(); 50 | this.child.height = this.$child.height(); 51 | this.child.outerWidth = this.$child.outerWidth(); 52 | this.child.outerHeight = this.$child.outerHeight(); 53 | if(this.child.outerHeight'+ style +''); 113 | } 114 | 115 | if(this.$el.css('position')=='static') { 116 | this.$el.css('position', 'relative'); 117 | } 118 | this.$el.addClass('SC_outer'); 119 | this.$child.addClass('SC_inner'); 120 | //背景栏 121 | this.$SC_backCtn = $('
').addClass(this.options.backClass).hide().appendTo(this.$el); 122 | 123 | //拖动块 124 | this.$SC_frontCtn = $('
').addClass(this.options.frontClass).appendTo(this.$SC_backCtn); 125 | 126 | this.frontLeft = (parseInt(this.$SC_backCtn.width())-parseInt(this.$SC_frontCtn.width()))/2; 127 | 128 | this.$SC_frontCtn.css({ 129 | left: this.frontLeft, 130 | }); 131 | this.maxTop = this.el.height-this.$SC_frontCtn.height();//拖动块最大top 132 | this.ratio = this.maxScroll/this.maxTop;//比率 133 | }, 134 | //绑定事件 135 | event: function() { 136 | var This = this, 137 | oldX = 0, 138 | oldY = 0, 139 | diffX = 0, 140 | diffY = 0, 141 | touchTimer = null; 142 | 143 | if(document.addEventListener) {//手机端(防止IE8-报错) 144 | This.$el[0].addEventListener('touchstart', function(e) { 145 | var targetTouches = e.targetTouches[0]; 146 | oldX = targetTouches.pageX; 147 | oldY = targetTouches.pageY; 148 | }); 149 | 150 | This.$el[0].addEventListener('touchmove', function(e) { 151 | clearInterval(touchTimer); 152 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeIn(); 153 | e.stopPropagation();//阻止页面滚动 154 | e.preventDefault();//阻止页面滚动 155 | 156 | var targetTouches = e.targetTouches[0]; 157 | 158 | var newX = targetTouches.pageX, 159 | newY = targetTouches.pageY; 160 | 161 | diffX = newX - oldX; 162 | diffY = newY - oldY; 163 | 164 | var childTop = This.$child.position().top, 165 | elH = This.$el.outerHeight(), 166 | childH = This.$child.outerHeight(); 167 | 168 | if(childTop<0 && childH>elH-childTop) { 169 | This.$child.css({'top': '+='+ diffY}); 170 | This.$SC_frontCtn.css({'top': -(This.$child.position().top)/This.ratio}); 171 | }else { 172 | This.$child.css({'top': '+='+ diffY/3}); 173 | } 174 | 175 | oldX = newX; 176 | oldY = newY; 177 | }); 178 | 179 | This.$el[0].addEventListener('touchend', function(e) { 180 | var targetTouches = e.targetTouches[0]; 181 | 182 | var childTop = This.$child.position().top, 183 | elH = This.$el.outerHeight(), 184 | childH = This.$child.outerHeight(); 185 | 186 | if(childTop>=0) {//上出现空白 187 | This.$child.stop().animate({'top': '0'}, 300, function() { 188 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeOut(); 189 | }); 190 | This.options.stopCallback(parseInt(This.$child.css('top')), -1); 191 | }else if(childH<=elH-childTop) { 192 | if(childH < elH) {//下出现空白 193 | This.$child.stop().animate({'top': '0'}, 300, function() { 194 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeOut(); 195 | }); 196 | }else { 197 | This.$child.stop().animate({'top': elH-childH}, 300, function() { 198 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeOut(); 199 | }); 200 | } 201 | This.options.stopCallback(parseInt(This.$child.css('top')), 1); 202 | }else {//缓动停止 203 | clearInterval(touchTimer); 204 | touchTimer = setInterval(function() { 205 | childTop = This.$child.position().top;//更新childTop 206 | 207 | if(childTop>=0) {//上出现空白 208 | This.$child.css({'top': '0'}); 209 | clearInterval(touchTimer); 210 | This.options.stopCallback(parseInt(This.$child.css('top')), -1); 211 | }else if(childH<=elH-childTop) {//下出现空白 212 | This.$child.css({'top': elH-childH}); 213 | clearInterval(touchTimer); 214 | This.options.stopCallback(parseInt(This.$child.css('top')), 1); 215 | }else {//运动中 216 | if(Math.abs(diffY)>1) { 217 | This.$child.css({'top': '+='+ diffY}); 218 | This.$SC_frontCtn.css({'top': -(This.$child.position().top)/This.ratio}); 219 | diffY *= .95; 220 | }else { 221 | This.$SC_backCtn.add(This.$SC_frontCtn).fadeOut(); 222 | clearInterval(touchTimer); 223 | } 224 | This.options.moveCallback(parseInt(This.$child.css('top')), -diffY<0?-1:1); 225 | } 226 | }, 20); 227 | } 228 | 229 | }); 230 | } 231 | 232 | //鼠标滚动(手机端无滚轮) 233 | This.$el.add(This.$SC_backCtn).add(This.$SC_frontCtn).on('mousewheel.SC', function(event, delta) { 234 | This.delta = -delta;// 235 | 236 | if(This.delta<0) {//向上滚 237 | var top = Math.abs(parseInt(This.$child.css('top'))), 238 | once = Math.abs(This.delta*This.deltaFactor); 239 | 240 | if(top0) {//向下滚 254 | var top = Math.abs(parseInt(This.$child.css('top'))), 255 | bottom = Math.abs(parseInt(This.maxScroll-top)), 256 | once = Math.abs(This.delta*This.deltaFactor); 257 | 258 | if(bottom= This.maxTop) {// 297 | endTop = This.maxTop; 298 | } 299 | 300 | This.$SC_frontCtn.css({//拖动按钮滚动 301 | top: endTop, 302 | }); 303 | 304 | This.$child.css({//div滚动 305 | top: -endTop*This.ratio, 306 | }); 307 | This.options.moveCallback(parseInt(This.$child.css('top')), diffClientY<0?-1:1); 308 | }); 309 | }); 310 | 311 | //取消拖动 312 | $(document).on('mouseup.SC', function() { 313 | $(this).off('mousemove.SC'); 314 | $(document).off('selectstart.SC'); 315 | $('body').removeClass('SC_select_no'); 316 | }); 317 | 318 | //监听内容变化(兼容性不好) 319 | /*This.$child.on('DOMNodeInserted.SC', function() { 320 | This.update();//更新 321 | });*/ 322 | 323 | This.text = This.$el.text(); 324 | 325 | This.timer = setInterval(function() { 326 | var newtext = This.$el.text(); 327 | 328 | if(This.text != newtext) { 329 | This.update(); 330 | This.text = This.$el.text(); 331 | if(This.options.autoBottom) { 332 | This.scrollTo('bottom'); 333 | } 334 | } 335 | }, 100); 336 | 337 | //浏览器缩放 338 | $(window).on('resize.SC', function() { 339 | This.update();//更新 340 | }); 341 | 342 | //渐隐渐显 343 | This.$el.hover(function() { 344 | This.$SC_backCtn.stop().fadeIn(); 345 | }, function() { 346 | This.$SC_backCtn.stop().fadeOut(); 347 | }); 348 | }, 349 | //更新 350 | update: function() { 351 | this.el.height = this.$el.height(); 352 | this.el.outerHeight = this.$el.outerHeight(); 353 | this.child.outerHeight = this.$child.outerHeight(); 354 | 355 | if(this.child.outerHeight