zoukankan      html  css  js  c++  java
  • 鼠标框选(上篇)

      好久没有更新博客了,感觉有些手生了,最近换了工作,有传统软件公司跳槽到互联网公司,由原来主做后端,兼职前端变成了全职前端;第一次进入互联网公司,感觉和传统软件公司或技术服务类公司相比,技术范围很浓,大家对技术更有追求,学习更主动,我很喜欢这种气氛,虽然很忙,但是感觉很充实,以后前端这部分开启,把所学所得记录下来,为自己也为分享,本篇作为开篇,聊聊鼠标框选操作。

    1、应用描述

      对于鼠标框选,网上已有粗糙的实现方案,这里也注重思路和方案,逐步对代码进行完善。

      鼠标框选,其实是对传统选择的一个升级,想象这样一种场景,用户选择单选框/复选框,多行多列等,如果需要用户单击选择,数量越多,用户体验越差,对于用户来说,越简单的操作,体验越好,如果通关鼠标拖动,产生一个框选区域,可以对框选区域内所有元素进行操作,也不失为批量操作的一个选择。

    2、实现思路

      所谓框选,直白一点就是绘制一个矩形,而绘制矩形的方式有很多,比如创建一个div/基于cavans绘制一个矩形,创建一个svg矩形,这里我们以最简单的一种方式来实现,基于div来实现。

      整个过程如下:

      1、创建一个div

      2、添加到dom

      3、监听mousemove事件,重绘div

      如果如果只是简单框选,该过程已ok,如果需要框选区高亮,则过程需要如下重构:

      1、创建一个div作为选择框,创建四个div分表作为上、下、左、右四个mask

      2、添加div到dom,同时添加mask到dom

      3、监听mousemove事件,重绘div和mask

    3、代码框架

      今天作为上篇,仅提出实现思路及未经测试的非伪代码,下篇会加入继续完善,基本代码框架如下:

      1 ; (function ($) {
      2 
      3     /**
      4      * 坐标点
      5      * @param {*} x 
      6      * @param {*} y 
      7      */
      8     function Point(x, y) {
      9         this.x = x;
     10         this.y = y;
     11     }
     12     /**
     13      * 框选构造函数
     14      * @param {*} rangEl 容器元素
     15      * @param {*} options 选择项
     16      */
     17     function FrameSelection(rangEl, options) {
     18         this._rangeEl = rangEl;
     19         this._options = $.extend({}, { callback: function () { } }, options);
     20 
     21         this.init();
     22     }
     23     /**
     24      * 框选初始化
     25      */
     26     FrameSelection.prototype.init = function () {
     27         this.unbind();
     28         this.bind();
     29     }
     30     /**
     31      * 解除事件绑定
     32      */
     33     FrameSelection.prototype.unbind = function () {
     34         var $rangEl = $(this._rangeEl);
     35         $rangEl.off('mousedown');
     36         $rangEl.off('mousemove');
     37         $rangEl.off('mouseup');
     38     }
     39     /**
     40      * 绘制接口
     41      */
     42     FrameSelection.prototype.render = function (p1, p2) {
     43         this._renderMask();
     44         this._renderRect();
     45 
     46         typeof this._options.callback === 'function' && this._options.callback();
     47     }
     48 
     49     /**
     50      * 创建遮罩层
     51      */
     52     FrameSelection.prototype._renderMask = function (p1, p2) {
     53         this.create('div.mask', 4, $divs => {
     54             //TODO:计算位置
     55             //渲染到dom中
     56             $divs.appendTo($(this._rangeEl));
     57         })
     58     }
     59     /**
     60      * 创建矩形选框
     61      */
     62     FrameSelection.prototype._renderRect = function (p1, p2) {
     63         this.create('div.rect', 1, $div => {
     64             //TODO:计算位置
     65             //渲染到dom中
     66             $div.appendTo($(this._rangeEl));
     67 
     68         });
     69     }
     70     /**
     71      * 创建元素
     72      */
     73     FrameSelection.prototype.create = function (eleDes, n, callback) {
     74         var desArr = eleDes.split('.');
     75         var eleName = desArr[0], className = desArr[1] || '', eles = '';
     76 
     77         for (var i = 0; i < n; i++) {
     78             eles += '<${eleName} class="${className}"><${eleName}/>';
     79         }
     80         
     81         callback && typeof callback === "function" && callback($(eles));
     82 
     83     }
     84     /**
     85      * 注册事件绑定
     86      */
     87     FrameSelection.prototype.bind = function () {
     88         var $rangEl = $(this._rangeEl);
     89         var self = this;
     90         $rangEl.bind('mousedown', function (event) {
     91             var start = new Point(event.pageX, event.pageY);
     92             //绑定mousedown事件,
     93 
     94             $rangEl.bind('mousemove', function (e) {
     95                 var end = new Point(e.pageX, e.pageY);
     96                 //绘制
     97                 self.render(start, end);
     98 
     99             })
    100         })
    101     }
    102 })(window.jQuery);

    说明:为了dom操作简单,这里假设以引入jquery,代码属于可以作为伪代码阅读,未经过测试,只是基本框架,下篇会进行完善,敬请期待。。。

  • 相关阅读:
    字符串打印
    倒计时(二)之时间戳
    倒计时(一)之数字补0
    递增、递减运算符
    如何让background里的img图片自适应
    CSS三角图标(二)
    CSS三角图标(一)
    网易云外链接生成方法
    python基础语法一
    CSS固定菜单栏
  • 原文地址:https://www.cnblogs.com/Johnzhang/p/7186918.html
Copyright © 2011-2022 走看看