react粘贴图片上传的尝试,没完成,有bug,删除之后,粘贴会失效,不知道为什么

/**
 * 新增缺陷弹出框
 */
"use strict";
import "./index.less";
import React, { Component } from "react";
import { message } from "edspUI";
import { Tooltip } from "antd";
import {
  InfoCircleOutlined,
  FolderOutlined,
  CopyFilled,
} from "@ant-design/icons";
import { Language } from "Utils";
import { Modal, Form, Input, Select, Button, Upload, Icon } from "antd";
import { jiraService } from "Services";
const FormItem = Form.Item;
const Option = Select.Option;
const { TextArea } = Input;
//资源国际化
const i18n = Language.getLanguage("jira");
class AddIssueModal extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showModal: this.props.showModal, //是否显示弹出框
      text: "支持多文件同时上传", //tooltip提示框文字
      supportShow: true,
      myFileList: [], //文件渲染数组,用来放文件名字和src,这两种
      realFileList: [], //真实文件列表
    };
  }

  componentWillMount() {
    this.refresh();
  }
  componentDidMount() {
    // 页面挂载后,先初始化一个装文件的
    this.setState({ realFileList: new FormData() });
  }
  refresh() {}
  inputF = () => {};
  pasteImg = (e) => {
    console.log("失效吗");
    // 一触发,就把图片隐藏
    this.setState({ supportShow: false });
    // let items = e.clipboardData.items;
    // let len = items.length;
    // console.log(
    //   e,
    //   e.clipboardData,
    //   e.clipboardData.types,
    //   e.clipboardData.files,
    //   e.clipboardData.items,
    //   e.clipboardData.items[0],
    //   e.clipboardData.items[0].getAsFile(),
    //   len,
    //   e.clipboardData.getData("Files"),
    //   e.clipboardData.getData("image/*")
    // );
    // 如果是复制纯文本,type为text/plain
    // 如果是复制一张图片,type为Files
    // 如果是复制多张图片,type为Files
    // 如果是复制图片加文字,type是['text/plain','text/html']
    // e.preventDefault();

    //正式
    let blob = null;
    if (e.clipboardData || e.originalEvent) {
      let clipboardData = e.clipboardData || e.originalEvent.clipboardData;
      if (clipboardData.items) {
        let items = clipboardData.items;
        let len = items.length;

        // 循环拿到所有图片文件  至于选择文件就另外放到一个list里吧,
        // 就不展示出来了,要不还是展示出来吧,不过展示在那下面比较好 嗯嗯
        // 如果是图片就添加到上面去,其他文件就放下面
        for (let i = 0; i < len; i++) {
          if (items[i].type.includes("image")) {
            blob = items[i].getAsFile();
            // 这里弄个时间戳给它,渲染的时候
            // 有个删除,点击的时候,需要同步删除
            let time = new Date().getTime();
            this.state.myFileList.push({
              fileName: blob.name,
              timeStanmp: time,
            });
            let newArr = this.state.myFileList.concat();
            this.setState({ myFileList: newArr });
            this.state.realFileList.append(time, blob);
            console.log(time, blob);
            console.log("this.state.realFileList", this.state.realFileList);
            console.log("this.state.myFileList", this.state.myFileList);
          }
          // console.log(items[i], items[i].getAsFile());

          // 纯文本 DataTransferItem {kind: "string", type: "text/plain"}
          // 纯图片 DataTransferItem {kind: "file", type: "image/png"}
          // 多张图片的复制弄不出来,看了一下,csdn的写博客,我从本地文件夹
          // 选择两张图片,复制,然后去博客里粘贴,也粘贴不出来。。。
          // 所以我这里也没有这个功能
          // 单张图片+文本
          //       DataTransferItem {kind: "string", type: "text/plain"}
          //       DataTransferItem {kind: "string", type: "text/html"}
          // 多张图片的复制,除了本地文件夹的没用,其他地方的可以
          // 比如csdn的,可以在csdn复制多张图片或者多张图片+文本
          //      多张图片
          //          DataTransferItem {kind: "string", type: "text/html"}
          //          DataTransferItem {kind: "string", type: "cke/id"}
          //      多张图片+文本
          //          DataTransferItem {kind: "string", type: "text/plain"}
          //          DataTransferItem {kind: "string", type: "text/html"}
          //          DataTransferItem {kind: "string", type: "cke/id"}
          // 所以多张图片的就算了吧
          // 就只处理单张图片的和单张图片+文本的就行了,反正只展示图片
          // ....现在看来似乎只能处理单张图片。。。
          // 就只能一张一张复制
          // 但是选择的时候可以选多张

          // 要不都放里面,都可编辑,就用li?
          // 然后我根据是否是图片来不同的展示就行了,不过
          // 我怎么增加文件是增加到state里再渲染到页面上
          // 但是我怎么检测删除呢,要不加个垃圾桶按钮吧,不然我怎么检测
          // 删除退格啥的,就垃圾桶吧
        }
      }
    }

    if (blob) {
      // 做两件事,第一件,读成base64,临时展示,算了,不用展示,
      // 但是都需要文件的名字和后缀,来展示
      // 第二用fd包裹,以便于发送数据给后端
      let imgarr = [];
      let reader = new FileReader();
      reader.readAsDataURL(blob);
      let that = this;
      reader.onload = function (res) {
        if (res.target.result) {
          imgarr.push(res.target.result);
        }
      };
    }

    // let fd = new FormData();
    // console.log(this.files);
    // // files文件列表无法通过普通数组等循环遍历,需要通过迭代器循环遍历
    // for (let file of this.files) {
    //   console.log("object", file);
    //   fd.append(file.name, file);
    // }
  };
  handleFileChange = (e) => {
    console.log("e", e);
    let fd = new FormData();
    console.log(e.target.files);
  };
  delFile = (e, time) => {
    let index = this.state.myFileList.findIndex((el) => el.timeStanmp == time);
    if (index >= 0) {
      this.state.myFileList.splice(index, 1);
      let newArr = this.state.myFileList.concat();
      this.setState({ myFileList: newArr });
    }
    this.state.realFileList.delete(time);
    console.log(this.state.myFileList, this.state.realFileList);
  };
  render() {
    // .ant-input-affix-wrapper .ant-input:focus {
    //     border: none;
    //     border-bottom: 1px solid white !important;
    //     box-shadow: none;}

    const { hideModal } = this.props;
    const { text, supportShow, myFileList } = this.state;

    const fileRender = myFileList.map((el) => {
      return (
        
  • { this.delFile(e, el.timeStanmp); }} > {el.fileName}
  • ); }); const modalOpt = { title: "新增缺陷", width: 900, visible: this.state.showModal, onOk: () => this.handleSubmit(), onCancel: () => hideModal && hideModal(false), okText: i18n.ok, cancelText: i18n.cancel, maskClosable: false, }; return ( {/* 头部 */}
    缺陷摘要:
    {/* onFocus={this.inputF} */}
    {/* 下面部分,分为左右两部分 */}
    提示:
    {/* contenteditable="true" */}
    {/* contenteditable="false" */} 支持粘贴图片...
      {fileRender}
    选择....
    ); } handleSubmit = () => {}; } const MyForm = Form.create()(AddIssueModal); export default MyForm;

    后来发现bug的原因是,第一次就算你是contenteditable="false",第一次粘贴一定触发

    但是之后你粘贴的内容,如果不是contenteditable="true",那就不会有光标,不能编辑,那么粘贴就不会再触发了

    但是我这里就是想实现,既不能编辑,又能触发粘贴。。。所以就难搞,要么就写成可编辑的,contenteditable="true",但是能够阻止退格删除事件,不让删除

    编辑区的东西

    难搞,所以我就吧文件都放在下面了。。。。就没做上面这种

    最新包含粘贴和下载的代码

    /**
     * 新增缺陷弹出框
     */
    "use strict";
    import "./index.less";
    import React, { Component } from "react";
    import { message } from "edspUI";
    import {
      InfoCircleOutlined,
      FolderOutlined,
      CopyFilled,
      VerticalAlignBottomOutlined,
      DeleteOutlined,
    } from "@ant-design/icons";
    import { Language } from "Utils";
    import {
      Modal,
      Select,
      Tooltip,
      Icon,
      Form,
      Input,
      Button,
      Checkbox,
    } from "antd";
    import { jiraService } from "Services";
    const FormItem = Form.Item;
    const Option = Select.Option;
    const { TextArea } = Input;
    //资源国际化
    const i18n = Language.getLanguage("jira");
    class AddIssueModal extends Component {
      constructor(props) {
        super(props);
        this.state = {
          showModal: this.props.showModal, //是否显示弹出框
          text: "支持多文件同时上传", //tooltip提示框文字
          fileList: [],
        };
      }
    
      componentWillMount() {
        this.refresh();
      }
      componentDidMount() {}
      refresh() {}
      pasteImg = (e) => {
        e.preventDefault();
        //正式
        let blob = null;
        if (e.clipboardData || e.originalEvent) {
          let clipboardData = e.clipboardData || e.originalEvent.clipboardData;
          if (clipboardData.items) {
            let items = clipboardData.items;
            let len = items.length;
            // 循环拿到所有图片文件  至于选择文件就另外放到一个list里吧,
            // 就不展示出来了,要不还是展示出来吧,不过展示在那下面比较好 嗯嗯
            // 如果是图片就添加到上面去,其他文件就放下面
            for (let i = 0; i < len; i++) {
              if (items[i].type.includes("image")) {
                blob = items[i].getAsFile();
                this.setState((state) => ({
                  fileList: [...state.fileList, blob],
                }));
              }
            }
          }
        }
      };
      handleFileChange = (e) => {
        this.setState({ supportShow: false });
        for (let file of e.target.files) {
          console.log("file", file);
          this.setState((state) => ({
            fileList: [...state.fileList, file],
          }));
        }
      };
      // 删除图片
      delFile = (file) => {
        this.setState((state) => {
          // 真没想到indexOf可以根据file来找。。。。之前都只能找单层的数组
          const index = state.fileList.indexOf(file);
          const newFileList = state.fileList.slice();
          newFileList.splice(index, 1);
          return {
            fileList: newFileList,
          };
        });
      };
      // 下载图片
      downFile = (file) => {
        const image = new Image();
        // 解决跨域 canvas 污染问题
        image.setAttribute("crossOrigin", "anonymous");
        image.onload = function () {
          const canvas = document.createElement("canvas");
          canvas.width = image.width;
          canvas.height = image.height;
          const context = canvas.getContext("2d");
          context.drawImage(image, 0, 0, image.width, image.height);
          //得到图片的base64编码数据
          const url = canvas.toDataURL("image/png");
          // 生成一个 a 标签
          const a = document.createElement("a");
          // 创建一个点击事件
          const event = new MouseEvent("click");
          // 将 a 的 download 属性设置为我们想要下载的图片的名称,若 name 不存在则使用'图片'作为默认名称
          a.download = file.name || "图片";
          // 将生成的 URL 设置为 a.href 属性
          a.href = url;
          // 触发 a 的点击事件
          a.dispatchEvent(event);
          // return a;
        };
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function (res) {
          if (res.target.result) {
            image.src = res.target.result;
          }
        };
      };
      render() {
        const { hideModal } = this.props;
        const { text, fileList } = this.state;
        const fileRender = fileList.map((el) => {
          return (
            
  • {el.name}
    { this.downFile(el); }} style={ { marginRight: "10px" }} /> { this.delFile(el); }} style={ { marginRight: "10px" }} />
  • ); }); const modalOpt = { title: "新增缺陷", width: 1200, visible: this.state.showModal, onOk: () => this.handleSubmit(), onCancel: () => hideModal && hideModal(false), okText: i18n.ok, cancelText: i18n.cancel, maskClosable: false, }; return ( {/* 头部 */}
    缺陷摘要:
    {/* 下面部分,分为左右两部分 */}
    提示:
    {/* */}
    支持粘贴图片...
    选择....
      {fileRender}
    ); } handleSubmit = () => {}; } const MyForm = Form.create()(AddIssueModal); export default MyForm;

     

    你可能感兴趣的:(react粘贴图片上传的尝试,没完成,有bug,删除之后,粘贴会失效,不知道为什么)