vue根据文字动态判断溢出...鼠标悬停显示el-tooltip展示

使用自定义el- tooltip 组件

定义

Tooltip是一种小型弹出框,它显示有关特定页面元素的信息,例如按钮、链接或图标。Tooltip通常以半透明的气泡形式呈现,并出现在页面元素的旁边或下方。

它可以改善用户体验,使用户更容易理解页面元素的功能和意图。用户可以通过将鼠标悬停在页面元素上来快速了解有关该元素的信息,而无需离开当前页面或浏览其他页面。

定位问题,很重要,top topLeft topRight bottom bottomLeft bottomRight left right,tooltip可以出现在不同的位置

采用默认插槽的方式,将需要tooltip的内容放置

通过父组件传入的visible进行手动控制tooltip的显现和隐藏

可以自定义tooltip背景色,如果自定义了,文字为白色

创建tooltip组件

/assets/directive/tooltip.js

在全局main.js引入组件

javascript 复制代码
import tooltip from '@/assets/directive/tooltip.js'
Vue.directive('tooltip', tooltip)

组件代码(按需修改)

javascript 复制代码
import {  getLanguage } from '@/assets/language/langs'
export default {
    // 指令所在组件的 VNode 及其子 VNode 全部更新后调用
      componentUpdated (el) {
    //   console.log(...arguments);
      /* 第1步:先要创建一个容器`span`去获取文本的宽度 */
      // 获取当前元素的style
      const curStyle = window.getComputedStyle(el, '');

      // 创建一个容器来记录文字的width
        const textSpan = document.createElement('span');
        // 设置新容器的字体样式,确保与当前需要隐藏的样式相同
        textSpan.style.fontSize = curStyle.fontSize;
        textSpan.style.fontWeight = curStyle.fontWeight;
        textSpan.style.fontFamily = curStyle.fontFamily;
        // 将容器插入body,如果不插入,offsetWidth为0
       
        document.body.appendChild(textSpan);
        // 设置新容器的文字
        const arr = el.innerText.split("  ");
        textSpan.innerHTML = arr[0];
        // console.log(textSpan.offsetWidth,'-------设el')
        var menu = document.getElementById('scenesSub');
        var uls = menu.getElementsByTagName('ul');
        var lis = menu.getElementsByTagName('li');
        var htmlWidth = document.documentElement.offsetWidth;

      // 如果字体元素大于当前元素长度,则需要隐藏
      /* 第2步:用获取到的宽跟`元素长度`的宽进行对比,如果文本字体大于当前`元素长度`元素的宽度,则需要title提示
       * 第3步:监听`el`的`onmouseenter`以及`onmouseleave`的鼠标移入移出事件
       */ 
      var jmz = {};
      jmz.GetLength = function(str) {
          ///<summary>获得字符串实际长度,中文2,英文1</summary>
          ///<param name="str">要获得长度的字符串</param>
          var realLength = 0, len = str.length, charCode = -1;
          for (var i = 0; i < len; i++) {
              charCode = str.charCodeAt(i);
              if (charCode >= 0 && charCode <= 128) realLength += 1;
              else realLength += 2;
          }
          return realLength;
      };
      
      
      //鼠标移入
      el.onmouseenter = (e) => {
        // console.log(e);
        var currLang=getLanguage()
        var innerlength= jmz.GetLength(el.innerText)
        // console.log(innerlength, el.innerText,currLang,'==========el.innerText========',innerlength > fontsmaller);
        //根据不同的语言设置不同的元素宽度
        var fontsmaller=30
        if(currLang=='CN'){ fontsmaller=28}
        else if(currLang=='EN'){ fontsmaller=36}
        else { fontsmaller=45}
        if (innerlength > fontsmaller){
            el.style.overflow = 'hidden';
              el.style.textOverflow = 'ellipsis';
              el.style.whiteSpace = 'nowrap';
        /* 第4步:鼠标移入`onmouseenter`事件里需要处理title提示的显示 */ 
          // 创建浮层元素并设置样式
          const kxmTooltipDom = document.createElement('div');
        kxmTooltipDom.style.cssText = `
          display: inline-block;
          max-width: 2rem;
          max-height: 2rem;
          position: absolute;
          top: ${e.clientY + 5}px;
          left: ${e.clientX}px;
          padding: 0.02rem;
          overflow: auto;
          font-size: 0.07rem;
            color: #333;
            background-color: #FFF;
            border-radius: 0.015rem;
            border: 0.005rem solid #333;
            z-index: 19999
          `;
          // 设置id方便寻找
          kxmTooltipDom.setAttribute('id', 'kxm-tooltip');
          // 将浮层插入到body中
          document.body.appendChild(kxmTooltipDom);
          // 浮层中的文字
          document.getElementById('kxm-tooltip').innerHTML = el.innerText;
        }
       // 鼠标移出
          el.onmouseleave = () => {
          // console.log(...arguments);
          /* 第5步:鼠标移出`onmouseleave`需要移出title显示的元素 */ 
            // 找到浮层元素并移出
            const kxmTooltipDom = document.getElementById('kxm-tooltip');
            kxmTooltipDom && document.body.removeChild(kxmTooltipDom);
          }
   		 } 
        // 需要注意:更新完之后需要移除容器,不然body里会多一个span元素内容
        document.body.removeChild(textSpan);
      },
      // 指令与元素解绑时
      unbind () {
      // console.log(...arguments);
      /* 第6步:解绑移除浮层元素 */
        // 找到浮层元素并移除
        const kxmTooltipDom = document.getElementById('kxm-tooltip');
        kxmTooltipDom && document.body.removeChild(kxmTooltipDom);
      }
  }
  
javascript 复制代码
 <el-menu-item v-for="(items, indexs) in item.children"  :key="indexs" :index="items.linkName" v-tooltip >
 	{{ items.linkName }} 
 </el-menu-item>

关于其中offsetWidth、clientWidth、scrollWidth学习记录

关于js中的offsetWidth、clientWidth、scrollWidth等一系列属性及其方法一直都傻傻分不清,这里就来总结一下这些方法的用法和含义。

javascript 复制代码
<script>
    /*
     ****** 元素视图属性
     * offsetWidth 水平方向 width + 左右padding + 左右border-width
     * offsetHeight 垂直方向 height + 上下padding + 上下border-width
     * 
     * clientWidth 水平方向 width + 左右padding
     * clientHeight 垂直方向 height + 上下padding
     * 
     * offsetTop 获取当前元素到 定位父节点 的top方向的距离
     * offsetLeft 获取当前元素到 定位父节点 的left方向的距离
     * 
     * scrollWidth 元素内容真实的宽度,内容不超出盒子高度时为盒子的clientWidth
     * scrollHeight 元素内容真实的高度,内容不超出盒子高度时为盒子的clientHeight
     * 
     ****** 元素视图属性结束
     * 
     ****** Window视图属性(低版本IE浏览器[<IE9]不支持) 【自测包含滚动条,但网络教程都说不包含???】
     * innerWidth 浏览器窗口可视区宽度(不包括浏览器控制台、菜单栏、工具栏) 
     * innerHeight 浏览器窗口可视区高度(不包括浏览器控制台、菜单栏、工具栏)
     * ***** Window视图属性结束
     * 
     ****** Document文档视图
     * (低版本IE的innerWidth、innerHeight的代替方案)
     * document.documentElement.clientWidth 浏览器窗口可视区宽度(不包括浏览器控制台、菜单栏、工具栏、滚动条)
     * document.documentElement.clientHeight 浏览器窗口可视区高度(不包括浏览器控制台、菜单栏、工具栏、滚动条)
     * 
     * document.documentElement.offsetHeight 获取整个文档的高度(包含body的margin)
     * document.body.offsetHeight 获取整个文档的高度(不包含body的margin)
     * 
     * document.documentElement.scrollTop 返回文档的滚动top方向的距离(当窗口发生滚动时值改变)
     * document.documentElement.scrollLeft 返回文档的滚动left方向的距离(当窗口发生滚动时值改变)
     ****** Document文档视图结束
     * 
     ****** 元素方法
     * 1. getBoundingClientRect() 获取元素到body
     *  bottom: 元素底边(包括border)到可视区最顶部的距离
     *  left: 元素最左边(不包括border)到可视区最左边的距离
     *  right: 元素最右边(包括border)到可视区最左边的距离
     *  top: 元素顶边(不包括border)到可视区最顶部的距离
     *  height: 元素的offsetHeight
     *  width: 元素的offsetWidth
     *  x: 元素左上角的x坐标 
     *  y: 元素左上角的y坐标 
     * 
     * 2. scrollIntoView() 让元素滚动到可视区
     * 
     * ***** 元素方法结束
     * 
     */
</script>
相关推荐
dot.Net安全矩阵6 分钟前
.NET内网实战:通过命令行解密Web.config
前端·学习·安全·web安全·矩阵·.net
叫我:松哥10 分钟前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
Hellc00717 分钟前
MacOS升级ruby版本
前端·macos·ruby
前端西瓜哥26 分钟前
贝塞尔曲线算法:求贝塞尔曲线和直线的交点
前端·算法
又写了一天BUG27 分钟前
npm install安装缓慢及npm更换源
前端·npm·node.js
cc蒲公英40 分钟前
Vue2+vue-office/excel 实现在线加载Excel文件预览
前端·vue.js·excel
Java开发追求者41 分钟前
在CSS中换行word-break: break-word和 word-break: break-all区别
前端·css·word
好名字08211 小时前
monorepo基础搭建教程(从0到1 pnpm+monorepo+vue)
前端·javascript
森叶1 小时前
Electron-vue asar 局部打包优化处理方案——绕开每次npm run build 超级慢的打包问题
vue.js·electron·npm
pink大呲花1 小时前
css鼠标常用样式
前端·css·计算机外设