zoukankan      html  css  js  c++  java
  • 【前端】常用总结(一)


    阅读目录

    一、canvas截图

    二、分组间元素拖动

    三、占位符交互效果

    四、导出Excel/Zip文件

    一、canvas截图

    1 需求

    页面内的某块容器截图,截取的图片需要去除不需要的元素

    2 canvas实现

    //截图
    function capturePicture(){
        //修改全局视图样式   借助vue实现可以在此处先把页面上不需要截取元素隐藏掉
        //this.capture_status = true;
    
        //base64转blob
        function dataURIToBlob(dataURI) {
            var binStr = atob(dataURI.split(',')[1]),
                len = binStr.length,
                arr = new Uint8Array(len);
    
            for (var i = 0; i < len; i++) {
                arr[i] = binStr.charCodeAt(i);
            }
            let blobs = new Blob([arr]);
            return blobs;
        }
    
        function _fixType(type) {
            type = type.toLowerCase().replace(/jpg/i, 'jpeg');
            let r = type.match(/png|jpeg|bmp|gif/)[0];
            return 'image/' + r;
        }
        //唤起浏览器下载
        function fileDownload(dataUrl) {
            let aLink = document.createElement('a');
            aLink.style.display = 'none';
            aLink.href = URL.createObjectURL(dataURIToBlob(dataUrl));
            aLink.download = `${formatTimeToYMD(getNowTime())}项目统计.jpg`; //图片名称
            // 触发点击-然后移除
            document.body.appendChild(aLink);
            aLink.click();
            document.body.removeChild(aLink);
        }
    
        setTimeout(()=>{ //这里加等待时间是为了确保上面设置的页面元素改变之后在截取
            const ele = document.getElementById("jira-container");  //截图容器
            const config = {
                allowTaint: true,
                scale: 1
            };
            html2canvas(ele, config).then(canvas => {
                var type = 'jpg';
                var imgData = canvas.toDataURL(type); //canvas转换为图片
                // 加工image data,替换mime type,方便以后唤起浏览器下载
                imgData = imgData.replace(_fixType(type), 'image/octet-stream');
                fileDownload(imgData);
                this.capture_status = false;
            })
        }, 300)
    },
    

    3 问题

    截图的图片如果超出了屏幕大小,请滚动到页面最上部分截取,否则会有截取信息缺失,原因暂时不详。

    二、分组间元素拖动

    1 需求

    多个分组之间实现元素拖动

    1.1 例子

    分组a: [{"name": "vue.draggable","order": 1,"fixed": false},{"name": "draggable","order": 2,"fixed": false}]
    分组b: [{"name": "vue.draggable","order": 3,"fixed": false},{"name": "draggable","order": 4,"fixed": false}]
    实现a,b中的元素可以通过拖拽DOM改变
    

    2 Vue.Draggable实现

    2.1 html

    <draggable
        class="dragArea list-group"
        :list="list_a"   //放入
        :clone="clone"   //设置后按住ctrl拖拽会复制一行
        :group="{ name: 'people', pull: pullFunction }"    //name:分组名称, pull:拖动时回调函数
        @start="start"   //开始拖拽的时候回调函数
      >
      <div v-for="(item, index) in list_a"></div>
    </draggable>
    
    <draggable class="dragArea list-group" :clone="clone" :list="list_b" group="people">   //需要指定group所属分组
      <div v-for="(item, index) in list_b"></div>
    </draggable>
    

    2.2 js

    data() {
        return {
            controlOnStart: true,
        }
    }
    methods: {
        clone(args) {
            return JSON.parse(JSON.stringify(args))
        },
        pullFunction() {
          return this.controlOnStart ? "clone" : true;
        },
        start({ originalEvent }) {
          this.controlOnStart = originalEvent.ctrlKey;  //是否按ctrl键
        },
    }
    

    3 问题

    假如组内元素是可以输入的,常用操作移动鼠标拉选内容就会很不方便。

    三、占位符交互效果

    1 需求

    Material Design规范中占位符交互效果,实现修改用户名

    2 实现

    2.1 html

      <div class="input-box">
        <div class="input-outline-x">
            <input class="input-control input-outline" placeholder="新用户名称" v-model="user_info.user_name"/>
            <label class="input-label">新用户名称</label>
            <span class="span-desc">4-30个字符</span>
        </div>
        <div class="input-box-button">
          <el-button type="primary" size="small" @click="submit">确 定</el-button>  //修改操作
          <el-button size="small" @click="activeName=''">取 消</el-button>
        </div>
      </div>
    

    2.2 css

    .input-outline-x{
        margin-top: 10px;
         -moz-fit-content;
         fit-content;
        position: relative;
    }
    .input-fill-x {
        border-bottom: 1px solid #d0d0d5;
    }
    .input-fill-x::after {
        content: '';
        position: absolute;
        border-bottom: 2px solid #2486ff;
        left: 0; right: 0; bottom: -1px;
        transform: scaleX(0);
        transition: transform .25s;
    }
    .input-fill-x:focus-within::after {
        transform: scaleX(1);
    }
    

    3 优势

    借助CSS placeholder-shown伪类,纯CSS,无任何JS,实现这样的占位符交互效果。

    四、导出Excel/Zip文件

    1.导出excel

    1.1导出代码

    import XLSX from 'xlsx'
    
    function export_json_to_excel({
      multiHeader = [],
      header,
      data,
      filename,
      merges = [],
      autoWidth = true,
      bookType=  'xlsx'
    } = {}) {
      /* original data */
      filename = filename || 'excel-list'
      data = [...data]
      data.unshift(header);
    
      for (let i = multiHeader.length-1; i > -1; i--) {
        data.unshift(multiHeader[i])
      }
    
      var ws_name = "SheetJS";
      var wb = new Workbook(),
        ws = sheet_from_array_of_arrays(data);
    
      if (merges.length > 0) {
        if (!ws['!merges']) ws['!merges'] = [];
        merges.forEach(item => {
          ws['!merges'].push(XLSX.utils.decode_range(item))
        })
      }
    
      if (autoWidth) {
        /*设置worksheet每列的最大宽度*/
        const colWidth = data.map(row => row.map(val => {
          /*先判断是否为null/undefined*/
          if (val == null) {
            return {
              'wch': 10
            };
          }
          /*再判断是否为中文*/
          else if (val.toString().charCodeAt(0) > 255) {
            return {
              'wch': val.toString().length * 2
            };
          } else {
            return {
              'wch': val.toString().length
            };
          }
        }))
        /*以第一行为初始值*/
        let result = colWidth[0];
        for (let i = 1; i < colWidth.length; i++) {
          for (let j = 0; j < colWidth[i].length; j++) {
            if (result[j]['wch'] < colWidth[i][j]['wch']) {
              result[j]['wch'] = colWidth[i][j]['wch'];
            }
          }
        }
        ws['!cols'] = result;
      }
    
      /* add worksheet to workbook */
      wb.SheetNames.push(ws_name);
      wb.Sheets[ws_name] = ws;
    
      var wbout = XLSX.write(wb, {
        bookType: bookType,
        bookSST: false,
        type: 'binary'
      });
      saveAs(new Blob([s2ab(wbout)], {
        type: "application/octet-stream"
      }), `${filename}.${bookType}`);
    }
    

    1.2使用

    const data = [{"name": "dc", "arg": 10}]
    
    //格式化数据,将data数据转化成[["dc", 10], ]
    formatJson(filterVal, jsonData) {
        return jsonData.map(v => filterVal.map(j => {
            return v[j]
        }))
    }
    //
    export_json_to_excel.then(excel => {
        const tHeader = ['姓名', '年龄']
        const filterVal = ['name', 'arg']
        const data = formatJson(filterVal, data)
        excel.export_json_to_excel({
          header: tHeader,
          data,
          filename: '姓名'
        })
      })
    

    2.导出多sheet页excel

    2.1导出代码

    import XLSX from 'xlsx'
    
    //数据写入sheet页对象
    function export_write_to_sheet({
      multiHeader = [],
      header,
      data,
      merges = [],
      autoWidth = false,
    
    } = {}) {
      /* original data */
      data = [...data]
      data.unshift(header);
    
      for (let i = multiHeader.length-1; i > -1; i--) {
        data.unshift(multiHeader[i])
      }
      var ws = sheet_from_array_of_arrays(data);
    
      if (merges.length > 0) {
        if (!ws['!merges']) ws['!merges'] = [];
        merges.forEach(item => {
          ws['!merges'].push(XLSX.utils.decode_range(item))
        })
      }
      return ws
    }
    
    // sheet页对象信息写入excel
    function writer_sheet_data_to_excle(filename, data) {
      var wb = new Workbook()
    
      for(let i=0;i<data.length;i++){
        /* add worksheet to workbook */
        wb.SheetNames.push(data[i][0]);
        wb.Sheets[data[i][0]] = data[i][1];
      }
      // filename = filename || 'excel-list';
      var wbout = XLSX.write(wb, {
        bookType: 'xlsx',
        bookSST: false,
        type: 'binary'
      });
      saveAs(new Blob([s2ab(wbout)], {
        type: "application/octet-stream"
      }), `${filename}.xlsx`);
    
    }
    

    2.2使用

    const data1 = [{"name": "dc", "arg": 10}]
    const data2 = [{"name1": "dz", "arg1": 15}]
    
    //格式化数据
    formatJson(filterVal, jsonData) {
      return jsonData.map(v => filterVal.map(j => {
        return v[j]
    }))
    const t1Filter = ['name', 'arg'];
    const t2Filter = ['name1', 'arg1'];
    const t1Header = ['姓名', '年龄']
    const t2Header = ['姓名1', '年龄1']
    let record_data = [];
    // 格式化数据
    const fdata1 = formatJson(t1Filter, data1);  
    const fdata2 = formatJson(t2Filter, data2);
    // 数据写入sheet页对象
    const ws1 = excel.export_write_to_sheet({ header: t1Header, data:fdata1})
    const ws2 = excel.export_write_to_sheet({ header: t2Header, data:fdata2})
    
    record_data.push(['sheet1', ws1]);
    record_data.push(['sheet2', ws2]);
    # 循环添加sheet对象信息
    excel.writer_sheet_data_to_excle('多sheet页', record_data)
    

    3.导出Zip

    require('script-loader!file-saver');
    import JSZip from 'jszip'
    
    // 导出zip压缩文件
    export function export_txt_to_zip(th, jsonData, txtName, zipName) {
      const zip = new JSZip()
      const txt_name = txtName || 'file'
      const zip_name = zipName || 'file'
      const data = jsonData
      let txtData = `${th}
    `
      data.forEach((row) => {
        let tempStr = ''
        tempStr = row.toString()
        txtData += `${tempStr}
    `
      })
      zip.file(`${txt_name}.txt`, txtData)
      zip.generateAsync({
        type: "blob"
      }).then((blob) => {
        saveAs(blob, `${zip_name}.zip`)
      }, (err) => {
        alert('导出失败')
      })
    }
    
  • 相关阅读:
    js 中的基本包装类型
    js监听浏览器,关闭,刷新(兼容IE6+,Firefox,Chrome,Safari)
    js 中的 && 与 ||
    程序设计模式的工厂(Factory)模式
    关于MOSS首页不能打开提示“根级别上的数据无效
    获取汉字的拼音的首个字母方法
    XmlDocument扩展类
    初次体验Android,过程很艰辛!
    用Python写个翻译工具
    开发经验是修炼设计模式的基石
  • 原文地址:https://www.cnblogs.com/zhangliang91/p/12197501.html
Copyright © 2011-2022 走看看