首页 > 代码库 > 鼠标框选 下篇
鼠标框选 下篇
接上篇,上篇写了大致的思路,其实还有很多问题,由于没写测试,在运行时出现了很多问题,比如绘制相关代码,会一直添加元素到dom,这主要因为我在考虑元素绘制和插入dom没有分开处理,本次主要增加了计算和绘制的代码逻辑,逻辑中有些代码还是需要优化的,比如dom访问次数过多,绘制过程做节流处理等,有需要各位自行优化即可,为了操作方便,直接封装成了jQuery插件。
完整代码如下,解释可直接看注释部分:
1 ; (function ($) { 2 3 $.fn.frameSelection = function (options) { 4 var defaultOpts = { 5 callback: function () { }, 6 mask: false, 7 done: function (result) { console.log(result) } 8 }; 9 var options = $.extend({}, defaultOpts, options); 10 new FrameSelection($(this), options); 11 } 12 /** 13 * 坐标点 14 * @param {*} x 15 * @param {*} y 16 */ 17 function Point(x, y) { 18 this.x = x; 19 this.y = y; 20 } 21 /** 22 * 框选构造函数 23 * @param {*} $rangeEl 容器元素 24 * @param {*} options 选择项 25 */ 26 function FrameSelection($rangeEl, options) { 27 this.$rangeEl = $rangeEl; 28 this.options = options; 29 30 this.init(); 31 } 32 /** 33 * 框选初始化 34 */ 35 FrameSelection.prototype.init = function () { 36 this.unbind(); 37 this.bind(); 38 } 39 /** 40 * 解除事件绑定 41 */ 42 FrameSelection.prototype.unbind = function () { 43 44 this.$rangeEl.off(‘mousedown‘); 45 this.$rangeEl.off(‘mousemove‘); 46 this.$rangeEl.off(‘mouseup‘); 47 } 48 /** 49 * 绘制接口 50 */ 51 FrameSelection.prototype.render = function (p1, p2) { 52 this.options.mask && this.renderMask(p1, p2); 53 this.renderRect(p1, p2); 54 } 55 /** 56 * 清理元素 57 */ 58 FrameSelection.prototype.clear = function () { 59 this.$rangeEl.find(‘.rect,.mask‘).remove(); 60 } 61 62 /** 63 * 创建遮罩层 64 */ 65 FrameSelection.prototype.renderMask = function (p1, p2) { 66 var $rect = this.$rangeEl.find(‘div.rect‘); 67 var $top = this.$rangeEl.find(‘div.mask:eq(0)‘), 68 $left = this.$rangeEl.find(‘div.mask:eq(1)‘), 69 $right = this.$rangeEl.find(‘div.mask:eq(2)‘), 70 $bottom = this.$rangeEl.find(‘div.mask:eq(3)‘); 71 72 $top.css({ 73 top: this.$rangeEl.css(‘top‘), 74 left: this.$rangeEl.css(‘left‘), 75 width: this.$rangeEl.width(), 76 height: $rect.css(‘top‘) 77 }); 78 79 $left.css({ 80 top: $rect.css(‘top‘), 81 left: $top.css(‘left‘), 82 width: $rect.css(‘left‘), 83 height: $rect.height() 84 }); 85 86 $right.css({ 87 top: $rect.css(‘top‘), 88 left: $left.width() + $rect.width(), 89 width: this.$rangeEl.width() - ($left.width() + $rect.width()), 90 height: $left.height() 91 }); 92 93 $bottom.css({ 94 top: $top.height() + $left.height(), 95 left: this.$rangeEl.css(‘left‘), 96 width: $top.width(), 97 height: this.$rangeEl.height() - ($top.height() + $left.height()) 98 }); 99 100 }101 /**102 * 创建矩形选框103 */104 FrameSelection.prototype.renderRect = function (p1, p2) {105 var $rect = this.$rangeEl.find(‘div.rect‘);106 107 $rect.css({108 top: Math.min(p1.y, p2.y),109 left: Math.min(p1.x, p2.x),110 width: Math.abs(p1.x - p2.x),111 height: Math.abs(p1.y - p2.y)112 })113 114 }115 /**116 * 创建元素117 */118 FrameSelection.prototype.create = function (eleDes, n, callback) {119 var desArr = eleDes.split(‘.‘);120 var eleName = desArr[0], className = desArr[1] || ‘‘, eles = ‘‘;121 122 for (var i = 0; i < n; i++) {123 eles += `<${eleName} class="${className}"></${eleName}>`;124 }125 126 callback && typeof callback === "function" && callback($(eles));127 128 }129 FrameSelection.prototype.createElToDom = function () {130 //默认不绘制mask131 var fn = ($eles) => {132 $eles.appendTo(this.$rangeEl);133 }134 this.options.mask && this.create(‘div.mask‘, 4, fn);135 this.create(‘div.rect‘, 1, fn);136 137 typeof this.options.callback === ‘function‘ && this.options.callback();138 }139 /**140 * 注册事件绑定141 */142 FrameSelection.prototype.bind = function () {143 var self = this;144 this.$rangeEl.bind(‘mousedown‘, function (event) {145 var start = new Point(event.pageX, event.pageY);146 //清理147 self.clear();148 self.createElToDom();149 150 self.$rangeEl.bind(‘mousemove‘, function (e) {151 var end = new Point(e.pageX, e.pageY);152 //绘制153 self.render(start, end);154 155 })156 });157 158 this.$rangeEl.bind(‘mouseup‘, function (e) {159 self.$rangeEl.off(‘mousemove‘);160 })161 }162 })(window.jQuery);
直接在html中测试打开即可,css代码未独立处理,直接写入了html文件中,具体代码如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>frame_selection</title> <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script> <script src="./frame_selection.js"></script> <script> $(document).ready(function(){ $(‘.container‘).frameSelection({ mask:true, callback:function(){ console.log(‘rendering!!!‘); }, done:function(result){ console.log(‘rendering done‘,result); } }) ; }) </script> <style> .container{ width:600px; height: 400px; left:0; top:0; } .mask, .rect { position: absolute; } .mask { background-color: #000; opacity: 0.2; } .rect { background-color: #fff; opacity: 0.1; border:1px dashed #000; } </style></head><body> <div class="container"> </div></body></html>
直接保存js代码到frame_selection.js文件,和index.html放在同一目录下,双击浏览器打开即可运行。运行效果如下
鼠标框选 下篇
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。