前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >鼠标框选 下篇

鼠标框选 下篇

作者头像
Jerremy
发布2022-05-09 15:02:24
1K0
发布2022-05-09 15:02:24
举报
文章被收录于专栏:Puppeteer学习Puppeteer学习

接上篇,上篇写了大致的思路,其实还有很多问题,由于没写测试,在运行时出现了很多问题,比如绘制相关代码,会一直添加元素到dom,这主要因为我在考虑元素绘制和插入dom没有分开处理,本次主要增加了计算和绘制的代码逻辑,逻辑中有些代码还是需要优化的,比如dom访问次数过多,绘制过程做节流处理等,有需要各位自行优化即可,为了操作方便,直接封装成了jQuery插件。

完整代码如下,解释可直接看注释部分:

代码语言:javascript
复制
  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         //默认不绘制mask
131         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文件中,具体代码如下:

代码语言:javascript
复制
<!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放在同一目录下,双击浏览器打开即可运行。运行效果如下

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档