zoukankan      html  css  js  c++  java
  • 封装ellipsis组件

    element-ui表单内tooltip可以让文字超出单元格时显示气泡,但是有一个限制,只能显示纯文本,无法控制tooptip内的样式,即使传入带标签的文本,也会把文本过滤出来,难以满足ui要求。

    于是借用el-poper来实现,又有一个缺点,无论文字是否超出都会展示气泡,最后决定自己封装一个ellipsis组件,当元素内的文本超出元素展示省略号时,出现气泡。

    思路:鼠标移入元素,比较元素的scrollHeight与clientHeight的大小,若滚动高度大于固定显示宽度,则文本是溢出状态。溢出状态时,创建气泡元素,计算好位置。

    创建一个ellipsis组件:

    <template>
      <div
        class="sllipsis-wraper"
        :style="{ '-webkit-line-clamp': lineClamp }"
        @mouseenter="mouseenter($event)"
        @mouseleave="mouseleave($event)"
      >
        <slot></slot>
      </div>
    </template>
    
    <script>
    export default {
      name: "ellipsis",
      props: {
        lineClamp: {
          //展示几行
          type: Number,
          default: 1
        },
        tipText: {
          //提示值
          type: Array | String,
          default: ""
        }
      },
      computed: {
        bubbleId() {
          return `sllipsis-bubble-${this._uid}`;
        },
        htmlStr() {
          if (Array.isArray(this.tipText)) {
            let str = "";
            this.tipText.forEach(item => {
              str += `<span class="bublle-span">${item}</span>`;
            });
            return str;
          } else {
            return this.tipText;
          }
        }
      },
      data() {
        return {};
      },
      created() {},
      methods: {
        mouseenter(e) {
          //鼠标移入
          if (!this.tipText.length) return;
          var target = e.target,
            containerHeight = target.clientHeight,
            textHeight = target.scrollHeight,
            positionObj = target.getBoundingClientRect(),
            windowHeight = window.innerHeight,
            showLocation =
              windowHeight - positionObj.bottom < 50 ? "top" : "bottom";
          if (textHeight > containerHeight) {
            //溢出
            this.showBubble({
              htmlStr: this.htmlStr,
              position: positionObj,
              showLocation: showLocation
            });
          } else {
            //未溢出
            this.hideBubble();
          }
        },
        mouseleave(e) {
          //鼠标移开
          this.hideBubble();
        },
        createBubbleElement(data) {
          //创建提示框
          let { htmlStr, position, showLocation } = data;
          if (!document.getElementById(this.bubbleId)) {
            let nodeEle = document.createElement("div");
            nodeEle.id = this.bubbleId;
            this.setBubbleLocation(nodeEle,data);
            this.setBubbleContent(nodeEle,htmlStr);
            nodeEle.classList.add("is-block");
            document.body.appendChild(nodeEle);
          }
        },
        hideBubble() {
          // 隐藏提示框
          let bubbleNode = this.getBubbleEle();
          if (bubbleNode) {
            bubbleNode.classList.remove("is-block");
          }
        },
        showBubble(data) {
          // 展示提示框
          let bubbleNode = this.getBubbleEle();
          if (bubbleNode) {
            this.setBubbleLocation(bubbleNode,data);
            this.setBubbleContent(bubbleNode,data.htmlStr);
            bubbleNode.classList.add("is-block");
          } else {
            //创建
            this.createBubbleElement(data);
          }
        },
        getBubbleEle() {
          //获取提示框元素
          return document.getElementById(this.bubbleId);
        },
        setBubbleLocation(DOM,data){
          // 设置气泡位置
          let { htmlStr, position, showLocation } = data;
            DOM.classList.add("is-block");
            if (showLocation == "top") {
              DOM.style.top = "";
              DOM.style.bottom = window.innerHeight - position.top + "px";
              DOM.className = `sllipsis-bubble is-top`;
              DOM.style.setProperty('--bubble-allow-y', -12 + "px");
            } else {
              DOM.style.bottom  = "";
              DOM.style.top = position.bottom + "px";
              DOM.className = `sllipsis-bubble is-bottom`;
              DOM.style.setProperty('--bubble-allow-y', -12 + "px");
            }
            DOM.style.left = position.left + "px";
            DOM.style.setProperty('--bubble-allow-x', position.width/2 + "px");
            
        },
        setBubbleContent(DOM,content){
          // 设置气泡内容
          DOM.innerHTML = content;
        }
      }
    };
    </script>
    
    <style lang="scss">
    .sllipsis-wraper {
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-box-orient: vertical;
    }
    .sllipsis-bubble {
      position: fixed;
      max-width: 400px;
      background: #fff;
      border-radius: 4px;
      border: 1px solid #e4e6e9;
      padding: 6px;
      color: #333940;
      line-height: 1.4;
      font-size: 14px;
      box-shadow: 0 2px 4px 0 #e4e6e9;
      word-break: break-all;
      // z-index: 1;
      display: none;
      box-sizing: border-box;
      &::before {
        content: "";
        position: absolute;
        width: 0;
        height: 0;
        border-width: 6px;
        border-style: solid;
        border-radius: 2px;
        z-index:2;
        left:var(--bubble-allow-x)
      }
      &.is-top::before{
        bottom:var(--bubble-allow-y);
        border-color: #fff transparent transparent transparent;
      }
      &.is-bottom::before{
        top:var(--bubble-allow-y);
        border-color: transparent transparent #fff transparent;
      }
      &.is-block {
        display: block;
      }
      &:hover {
        display: block;
      }
      .bublle-span {
        display: inline-block;
        border: 1px solid #e4e6e9;
        font-size: 12px;
        text-align: left;
        color: #333940;
        line-height: 18px;
        border-radius: 2px;
        margin-right: 4px;
        margin-top: 3px;
        margin-bottom: 3px;
        padding: 1px 2px;
      }
    }
    </style>

    使用方法:

    <ellipsis :lineClamp="1" tipText="xxx">
            {{xxx}}
    </ellipsis>
                               

    超出一行隐藏时可省略lineClamp属性

    效果:

  • 相关阅读:
    ubuntu 16.04 更新后搜狗输入法无法输入中文的问题
    转: 苹果APNS的说明
    转:svn 更新指定文件夹
    转: Java 应用一般架构
    【原创】关于bug反正出现的问题可能
    App开发者博客之: 包建强 (专注移动app开发)
    转: 阿里跨平台移动开发工具Weex
    【原创】存储层设计的一些方法论
    转:车牌的自动截取与识别方案
    转: java web demo的示例
  • 原文地址:https://www.cnblogs.com/fqh123/p/15106530.html
Copyright © 2011-2022 走看看