react中dangerouslySetInnerHTML的标签绑定事件

项目需求:采用富文本编辑器编辑的一段字符串格式的html需进行显示,使用dangerouslySetInnerHTML进行显示,但是这段HTML中包含img标签,希望将这个img标签不要直接显示,而是处理成a标签,点击时再进行图片显示,点击浏览器任意位置,图片不显示。

代码

import React, {useState} from "react";
// reactstrap components
import {Modal} from "reactstrap";

class ImgHandle extends React.Component {

  constructor(props){
    super(props);
    this.state = {
      content: '<p><img src="https://scpic.chinaz.net/files/pic/pic9/202111/apic36470.jpg"></p>',
      imgModal: false,
      imgSrc: ''
    };
  }
  componentDidMount(){
    document.addEventListener('click', (e) => {
      if(e.target.tagName === 'A'&&e.target.dataset.type === 'picture') {
        // a标签被点击了
        this.toggleImage(e.target.dataset.src);
      }
    })
  }
  listcords = () => {
    //该方法为获取要显示的内容,放在records中,代码省略
  }
  toggleImage = (src)=>{
    this.setState({
      imgModal:!this.state.imgModal,
      imgSrc:src
    });
  }
  //对内容中的图片进行处理
  getModifiedContent = (content) => {
    var pos = content.indexOf("<img");
    var count = 1;

    while(pos!=-1){
      var imgContent = content.substring(pos,content.indexOf(">",pos+1)+1);
      var src = imgContent.substring(imgContent.indexOf("src=")+5,imgContent.indexOf("\"",imgContent.indexOf("src=")+5));
      
      var newContent = "<a data-type='picture' href='javascript:void(0)' target='_blank' data-src='"+src+"'>图片"+count+"</a>";
      //var newContent = "<a href='javascript:void(0)' target='_blank' onClick='"+this.toggleImage+"'>图片"+count+"</a>";
      
      content = content.replace(imgContent,newContent);
      pos = content.indexOf("<img");
      count++;
    }
    return content;
  }
  render() {
    return (
        <div className="content">
   		 <div dangerouslySetInnerHTML={{__html:this.getModifiedContent(this.state.content)}}></div>
          <Modal isOpen={this.state.imgModal} toggle={this.toggleImage} centered={true} size='lg'>
            <img src={this.state.imgSrc}/>
          </Modal>
        </div>
    );
  }
}
export default ImgHandle;

问题

如果按照方法getModifiedContent()中的var newContent = “图片”+count+""来定义a,则函数不会执行,被解析为一下内容:

<a href="javascript:void(0)" target="_blank" onclick="src => {
      this.setState({
        imgModal: !this.state.imgModal,
        imgSrc: src
      });
    }">图片1</a>

而且,如果需要传参数,这种方式更不可能实现。

绑定事件

此时,我们修改绑定方式,将newContent进行如下定义:

var newContent = "<a data-type='picture' href='javascript:void(0)' target='_blank' data-src='"+src+"'>图片"+count+"</a>";

同时,在componentDidMount()方法中为a标签绑定事件:

componentDidMount(){
   document.addEventListener('click', (e) => {
     if(e.target.tagName === 'A'&&e.target.dataset.type === 'picture') {
       // a标签被点击了
       this.toggleImage(e.target.dataset.src);
     }
   })
 }

并将img的src地址放在a标签的属性data-src中,相当于进行传参。而且我们只需要将特定的a标签绑定该事件,因此又定义了属性data-type。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐