zoukankan      html  css  js  c++  java
  • 鼠标框选 下篇

    接上篇,上篇写了大致的思路,其实还有很多问题,由于没写测试,在运行时出现了很多问题,比如绘制相关代码,会一直添加元素到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              this.$rangeEl.width(),
     76             height: $rect.css('top')
     77         });
     78 
     79         $left.css({
     80             top: $rect.css('top'),
     81             left: $top.css('left'),
     82              $rect.css('left'),
     83             height: $rect.height()
     84         });
     85 
     86         $right.css({
     87             top: $rect.css('top'),
     88             left: $left.width() + $rect.width(),
     89              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              $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              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文件中,具体代码如下:

    <!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>
    View Code

    直接保存js代码到frame_selection.js文件,和index.html放在同一目录下,双击浏览器打开即可运行。运行效果如下

  • 相关阅读:
    aws centos 基本环境安装
    aws 安装python解释器
    odoo 开发环境部署
    graphql规范
    python 字符串format使用
    设计模式
    集合的常见操作
    字典常见操作
    python实现简单的购物车
    python实现简单的登录管理
  • 原文地址:https://www.cnblogs.com/Johnzhang/p/7191487.html
Copyright © 2011-2022 走看看