最近做项目时,遇到了一个需求:要求div里文本在两行显示,div的宽度是固定的,如果溢出的话就显示省略号。单行文本的溢出问题,我们都很熟悉,只要添加以下css属性就ok:

  overflow: hidden;white-space: nowrap; //段落中文本不换行text-overflow: ellipsis;

但是多行文本的溢出怎么处理呢?

  • 查了资料之后发现还是有办法的

    在WebKit浏览器或移动端(绝大部分是WebKit内核的浏览器)的页面实现比较简单,可以直接使用WebKit的CSS扩展属性(WebKit是私有属性)-webkit-line-clamp ;注意:这是一个 不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中。-webkit-line-clamp用来限制在一个块元素显示的文本的行数。 为了实现该效果,它需要组合其他的WebKit属性。

  • 我们用一下代码即可实现:
    overflow : hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;
  • 但是这样处理会遇到兼容性问题,在Firefox浏览器上就不起作用。
  • 为了解决兼容性问题,有一个clamp.js[https://www.npmjs.com/package...]很好的解决这个问题。
  • 为了更好的跟Vue相结合,今天我们就封装一个v-clamp的指令,来方便的解决这个问题。

    // 注册一个全局自定义指令 `v-clamp`
    Vue.directive('clamp', {// 当被绑定的元素插入到 DOM 中时……update: function (el, binding) {function clamp(element, options) {options = options || {};var self = this,win = window,opt = {clamp: options.clamp || 2,useNativeClamp: typeof(options.useNativeClamp) != 'undefined' ? options.useNativeClamp : true,splitOnChars: options.splitOnChars || ['.', '-', '–', '—', ' '], //Split on sentences (periods), hypens, en-dashes, em-dashes, and words (spaces).animate: options.animate || false,truncationChar: options.truncationChar || '…',truncationHTML: options.truncationHTML},sty = element.style,originalText = element.innerHTML,supportsNativeClamp = typeof(element.style.webkitLineClamp) != 'undefined',clampValue = opt.clamp,isCSSValue = clampValue.indexOf && (clampValue.indexOf('px') > -1 || clampValue.indexOf('em') > -1),truncationHTMLContainer;if (opt.truncationHTML) {truncationHTMLContainer = document.createElement('span');truncationHTMLContainer.innerHTML = opt.truncationHTML;}// UTILITY FUNCTIONS __________________________________________________________/*** Return the current style for an element.* @param {HTMLElement} elem The element to compute.* @param {string} prop The style property.* @returns {number}*/function computeStyle(elem, prop) {if (!win.getComputedStyle) {win.getComputedStyle = function(el, pseudo) {this.el = el;this.getPropertyValue = function(prop) {var re = /(\-([a-z]){1})/g;if (prop == 'float') prop = 'styleFloat';if (re.test(prop)) {prop = prop.replace(re, function() {return arguments[2].toUpperCase();});}return el.currentStyle && el.currentStyle[prop] ? el.currentStyle[prop] : null;};return this;};}return win.getComputedStyle(elem, null).getPropertyValue(prop);}/*** Returns the maximum number of lines of text that should be rendered based* on the current height of the element and the line-height of the text.*/function getMaxLines(height) {var availHeight = height || element.clientHeight,lineHeight = getLineHeight(element);return Math.max(Math.floor(availHeight / lineHeight), 0);}/*** Returns the maximum height a given element should have based on the line-* height of the text and the given clamp value.*/function getMaxHeight(clmp) {var lineHeight = getLineHeight(element);return lineHeight * clmp;}/*** Returns the line-height of an element as an integer.*/function getLineHeight(elem) {var lh = computeStyle(elem, 'line-height');if (lh == 'normal') {// Normal line heights vary from browser to browser. The spec recommends// a value between 1.0 and 1.2 of the font size. Using 1.1 to split the diff.lh = parseInt(computeStyle(elem, 'font-size')) * 1.2;}return parseInt(lh);}// MEAT AND POTATOES (MMMM, POTATOES...) ______________________________________var splitOnChars = opt.splitOnChars.slice(0),splitChar = splitOnChars[0],chunks,lastChunk;/*** Gets an element's last child. That may be another node or a node's contents.*/function getLastChild(elem) {//Current element has children, need to go deeper and get last child as a text nodeif (elem.lastChild.children && elem.lastChild.children.length > 0) {return getLastChild(Array.prototype.slice.call(elem.children).pop());}//This is the absolute last child, a text node, but something's wrong with it. Remove it and keep tryingelse if (!elem.lastChild || !elem.lastChild.nodeValue || elem.lastChild.nodeValue === '' || elem.lastChild.nodeValue == opt.truncationChar) {elem.lastChild.parentNode.removeChild(elem.lastChild);return getLastChild(element);}//This is the last child we want, return itelse {return elem.lastChild;}}/*** Removes one character at a time from the text until its width or* height is beneath the passed-in max param.*/function truncate(target, maxHeight) {if (!maxHeight) {return;}/*** Resets global variables.*/function reset() {splitOnChars = opt.splitOnChars.slice(0);splitChar = splitOnChars[0];chunks = null;lastChunk = null;}var nodeValue = target.nodeValue.replace(opt.truncationChar, '');//Grab the next chunksif (!chunks) {//If there are more characters to try, grab the next oneif (splitOnChars.length > 0) {splitChar = splitOnChars.shift();}//No characters to chunk by. Go character-by-characterelse {splitChar = '';}chunks = nodeValue.split(splitChar);}//If there are chunks left to remove, remove the last one and see if// the nodeValue fits.if (chunks.length > 1) {// console.log('chunks', chunks);lastChunk = chunks.pop();// console.log('lastChunk', lastChunk);applyEllipsis(target, chunks.join(splitChar));}//No more chunks can be removed using this characterelse {chunks = null;}//Insert the custom HTML before the truncation characterif (truncationHTMLContainer) {target.nodeValue = target.nodeValue.replace(opt.truncationChar, '');element.innerHTML = target.nodeValue + ' ' + truncationHTMLContainer.innerHTML + opt.truncationChar;}//Search produced valid chunksif (chunks) {//It fitsif (element.clientHeight <= maxHeight) {//There's still more characters to try splitting on, not quite done yetif (splitOnChars.length >= 0 && splitChar !== '') {applyEllipsis(target, chunks.join(splitChar) + splitChar + lastChunk);chunks = null;}//Finished!else {return element.innerHTML;}}}//No valid chunks producedelse {//No valid chunks even when splitting by letter, time to move//on to the next nodeif (splitChar === '') {applyEllipsis(target, '');target = getLastChild(element);reset();}}//If you get here it means still too big, let's keep truncatingif (opt.animate) {setTimeout(function() {truncate(target, maxHeight);}, opt.animate === true ? 10 : opt.animate);} else {return truncate(target, maxHeight);}}function applyEllipsis(elem, str) {elem.nodeValue = str + opt.truncationChar;}// CONSTRUCTOR ________________________________________________________________if (clampValue == 'auto') {clampValue = getMaxLines();} else if (isCSSValue) {clampValue = getMaxLines(parseInt(clampValue));}var clampedText;if (supportsNativeClamp && opt.useNativeClamp) {sty.overflow = 'hidden';sty.textOverflow = 'ellipsis';sty.webkitBoxOrient = 'vertical';sty.display = '-webkit-box';sty.webkitLineClamp = clampValue;if (isCSSValue) {sty.height = opt.clamp + 'px';}} else {var height = getMaxHeight(clampValue);if (height <= element.clientHeight) {console.log(getLastChild(element));clampedText = truncate(getLastChild(element), height);}}return {'original': originalText,'clamped': clampedText};}clamp(el,{clamp: 2}) }
    })
    
    • 其实很简单,仅仅是把clamp.js中的函数搬移了过来。然后就可以像这样来使用:

        <div class="txt" v-clamp>很抱歉!没有搜索到相关模板很抱歉!没有搜索到相关模板很抱歉!没有搜索到相关模板很抱歉!没有搜索到相关模板</div>   

基于clamp.js封装vue指令,处理多行文本的溢出相关推荐

  1. 原生html中modal,基于原生JS封装的Modal对话框插件

    基于原生JS封装Modal对话框插件 原生JS封装Modal对话框插件,个人用来学习原理与思想,只有简单的基本框架的实现,可在此基础上添加更多配置项 API配置 //基本语法 let modal = ...

  2. 基于node.js和vue的前后端分离影院售票系统电影院影片管理

    1,项目介绍 基于 node.js和vue 的影院售票系统拥有两种角色,分别为管理员和用户. 用户:热映.即将上映.电影和影院全局搜索.评论.选座.购票.点赞.收藏.订单等一系列购票功能 管理员:用户 ...

  3. Vue.js:vue指令(给标签属性赋Vue变量v-bind,绑定事件 v-on)vue事件处理函数中, 拿到事件对象,6个事件修饰符

    1. 给标签属性赋Vue变量v-bind 在vue中,v-bind指令可以动态的给标签的属性设置值, 语法:v-bind:属性名="vue变量" 简写::属性名="vue ...

  4. 基于node.js和Vue的运动装备网上商城

    摘  要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存储达到准 ...

  5. 多多客开源版,微信开放平台的小程序SaaS 系统,基于doodoo.js,vue.js

    多多客作为青否原班人马打造的小程序第三方平台,结合5年商城系统.近2年小程序SaaS平台研发及运营经验,将重点发力小程序个性化和各类营销玩法,联合服务商.开发者.经营专家,共建服务生态,服务百万商家. ...

  6. 基于node.js和Vue的食堂窗口美食评价系统/美食网站

    摘要 本论文主要论述了如何使用Node.js语言开发一个食堂窗口美食评价系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发.在引言中,作者将论述食堂窗口 ...

  7. 多多客开源版,微信开放平台的小程序SaaS 系统,基于doodoo.js,vue.js 1

    多多客作为青否原班人马打造的小程序第三方平台,结合5年商城系统.近2年小程序SaaS平台研发及运营经验,将重点发力小程序个性化和各类营销玩法,联合服务商.开发者.经营专家,共建服务生态,服务百万商家. ...

  8. 基于node.js的vue_基于Vue.js和Wilddog的可怕站点danmu项目

    基于node.js的vue AweSiteChat (AweSiteChat) A Vue.js & Wilddog project 一个Vue.js和Wilddog项目 现场演示 (live ...

  9. 基于three.js开发可视化应用经验总结

    文章目录 背景简介 技术方案介绍及对比 Webgl Three.js WEBGL和Three.js的关系 具体应用过程 星空背景 流线汇聚效果 行政分区环形选择器 Three.js 中使用TWEEN插 ...

最新文章

  1. 目标文件中的几个重要的段
  2. 基于php的应用程序,基于PHP的Web应用程序和群发邮件
  3. POJ(1195)(单点修改,区间查询)(二维)
  4. STL::map默认会按照.first的字母顺序排列
  5. 【CodeForces - 190E】Counter Attack (补图bfs,卡常,dsu)
  6. 9 操作系统第二章 进程管理 管程
  7. Java转JSON串的几种方式
  8. python 点击按钮 click_用selenium和Python单击“onclick”按钮
  9. too many connections的一个实践
  10. 拓端tecdat|R语言使用蒙特卡洛模拟进行正态性检验及可视化
  11. 修改数据文件和日志文件路径
  12. 算法:线性时间选择(C/C++)
  13. LSTM matlab实现
  14. 语音合成论文优选:One-shot Voice Conversion by Separating Speaker and Content Representations with Instance N
  15. c语言十六进制字母,c语言读取十六进制文件
  16. win10系统cpu内核或逻辑核心缺少缺少,解决办法
  17. php 失去焦点,jquery设置焦点方法focus()和jquery失去焦点方法blur()
  18. go 合并excel
  19. bilibil网站采集 返回视频下载地址【代码】
  20. 学习嵌入式的开发线路,新手怎么学习嵌入式?

热门文章

  1. android手机接投影仪,手机投屏到投影仪的几种方法
  2. Eric S. Raymond 五部曲 之 《开拓智域》
  3. linux服务器默认多久断开ssh,SSH超时自动断开问题解决
  4. 有了这个抠图滤镜,设计师再也不怕扣头发婚纱了!
  5. netty4 io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
  6. verilog学习笔记:简单的数据选择器modelsim仿真
  7. 苏州计算机英语怎么说,苏州用英语怎么说,苏州的英语单词
  8. 内存泄漏的原因及解决方法
  9. 千寻位置平台使用入门总结
  10. 【deepin】安装与设置win10独立双系统 - 战神Z7-SL7S3安装deepin15.11,并双屏显示