react中如何在一张图片上加一个灰色蒙层,并添加事件?

最终效果:

实现原理:

  1. 移动到图片上的时候,给img加一个伪类
    !!此时就要地方要注意了,因为img标签是闭合的标签,无法直接添加 伪类(::after),所以
    我是在img外层加了一个span标签,方便加上伪类,实现浮层的效果
  2. 给元素绑定对应的点击事件

废话不多说,上代码!!!!

typescript 复制代码
// 鼠标移动到图片时,将图片包裹在span标签中
  const handleHover = (event: any) => {
    if (event.target.tagName.toLowerCase() === 'img') {
      // 确保只对img标签进行操作
      const imgElement = event.target;
      // 检查img元素是否已经被包裹在一个具有'class="wrapper"'的div里
      if (
        imgElement.parentNode &&
        imgElement.parentNode.tagName.toLowerCase() === 'span' &&
        imgElement.parentNode.classList.contains('wrapper')
      ) {
        return; // 如果已经包裹了就退出函数
      }

      // 创建一个新的div元素
      const wrapper = document.createElement('span');
      wrapper.className = 'wrapper'; // 给新的div设置类名以便于CSS控制

      // 将img元素插入到新的div中
      imgElement.parentNode.insertBefore(wrapper, imgElement); // 在img之前插入wrapper
      wrapper.appendChild(imgElement); // 把img移到wrapper里
    }
  };

  useEffect(() => {
    window.addEventListener('click', handleClickHtmlContent);

    const container: any = document.getElementById('container');

    // 监听所有img标签的mouseover事件
    container?.addEventListener('mouseover', handleHover);

    return () => {
      window.removeEventListener('click', handleClickHtmlContent);
      container?.removeEventListener('mouseover', handleHover);
    };
  }, []);



// 点击html渲染区域的图片时,调起Antd组件Image的预览
  const handleClickHtmlContent = (e: any) => {
    if (e.target.closest('#container p .wrapper')) {
      const url = e.target.querySelector('img')?.src;
      Modal.confirm({
        title: '确认发送该图片?',
        centered: true,
        icon: null,
        content: (
          <img width={360} src={url} />
        ),
        okText: '确认',
        onOk: () => {
          console.log('确认发送');
        },
      });
    }
  };


// html
<div id="container">
 <img src="123.png"/>
</div>


// css

#container {
  .wrapper {
    position: relative;
    display: inline-block;
    &:hover {
      cursor: pointer;
      box-shadow: 0 0 5px #ccc;
      &::after {
        opacity: 1;
      }
    }
    &::after {
      content: '点击发送图片';
      position: absolute;
      text-align: center;
      align-content: center;
      top: 0;
      left: 0;
      display: block;
      width: 100%;
      height: 100%;
      max-height: 250px;
      color: #fff;
      background: rgba(0, 0, 0, 0.5); /* 示例背景色 */
      opacity: 0; /* 初始状态隐藏 */
      transition: opacity 0.3s ease; /* 添加过渡效果 */
    }
  }
  img {
    max-height: 250px;
    width: auto !important;
  }
}
相关推荐
华仔啊3 小时前
用 Vue3 + Canvas 做了个超实用的水印工具,同事都在抢着用
前端·vue.js·canvas
Bacon4 小时前
前端:从0-1实现一个脚手架
前端
Bacon4 小时前
前端项目部署实战 nginx+docker持续集成
前端
beckyye4 小时前
阿里云智能语音简单使用:语音识别
前端·语音识别·录音
东东2334 小时前
前端规范工具之husky与lint-staged
前端·javascript·eslint
jump6804 小时前
手写事件总线、事件总线可能带来的内存泄露问题
前端
岁月宁静4 小时前
在 Vue 3.5 中优雅地集成 wangEditor,并定制“AI 工具”下拉菜单(总结/润色/翻译)
前端·javascript·vue.js
执沐4 小时前
基于HTML 使用星辰拼出爱心,并附带闪烁+流星+点击生成流星
前端·html
#做一个清醒的人4 小时前
【electron6】Web Audio + AudioWorklet PCM 实时采集噪音和模拟调试
前端·javascript·electron·pcm
拉不动的猪5 小时前
图文引用打包时的常见情景解析
前端·javascript·后端