摘要:最近做項目時,遇到了一個需求要求里文本在兩行顯示,的寬度是固定的,如果溢出的話就顯示省略號。用來限制在一個塊元素顯示的文本的行數。為了實現該效果,它需要組合其他的屬性。為了更好的跟相結合,今天我們就封裝一個的指令,來方便的解決這個問題。
最近做項目時,遇到了一個需求:要求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 node
if (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 trying
else 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 it
else {
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 chunks
if (!chunks) {
//If there are more characters to try, grab the next one
if (splitOnChars.length > 0) {
splitChar = splitOnChars.shift();
}
//No characters to chunk by. Go character-by-character
else {
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 character
else {
chunks = null;
}
//Insert the custom HTML before the truncation character
if (truncationHTMLContainer) {
target.nodeValue = target.nodeValue.replace(opt.truncationChar, "");
element.innerHTML = target.nodeValue + " " + truncationHTMLContainer.innerHTML + opt.truncationChar;
}
//Search produced valid chunks
if (chunks) {
//It fits
if (element.clientHeight <= maxHeight) {
//There"s still more characters to try splitting on, not quite done yet
if (splitOnChars.length >= 0 && splitChar !== "") {
applyEllipsis(target, chunks.join(splitChar) + splitChar + lastChunk);
chunks = null;
}
//Finished!
else {
return element.innerHTML;
}
}
}
//No valid chunks produced
else {
//No valid chunks even when splitting by letter, time to move
//on to the next node
if (splitChar === "") {
applyEllipsis(target, "");
target = getLastChild(element);
reset();
}
}
//If you get here it means still too big, let"s keep truncating
if (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中的函數搬移了過來。然后就可以像這樣來使用:
很抱歉!沒有搜索到相關模板很抱歉!沒有搜索到相關模板很抱歉!沒有搜索到相關模板很抱歉!沒有搜索到相關模板
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/114096.html
摘要:最近做項目時,遇到了一個需求要求里文本在兩行顯示,的寬度是固定的,如果溢出的話就顯示省略號。用來限制在一個塊元素顯示的文本的行數。為了實現該效果,它需要組合其他的屬性。為了更好的跟相結合,今天我們就封裝一個的指令,來方便的解決這個問題。 最近做項目時,遇到了一個需求:要求div里文本在兩行顯示,div的寬度是固定的,如果溢出的話就顯示省略號。單行文本的溢出問題,我們都很熟悉,只要添加以...
摘要:前言項目中我們經常遇到這種需求,需要對單行多行文本超出顯示為省略號。單行文本省略文本溢出顯示省略號文本不會換行語法默認值適用于所有元素當對象內文本溢出時不顯示省略標記,而是將溢出的部分裁切掉。 前言:項目中我們經常遇到這種需求,需要對單行、多行文本超出顯示為省略號。這篇文章主要總結了小編解決此問題的方法,有不足之處歡迎大家指正。 單行文本省略 showImg(https://segme...
摘要:前言項目中我們經常遇到這種需求,需要對單行多行文本超出顯示為省略號。單行文本省略文本溢出顯示省略號文本不會換行語法默認值適用于所有元素當對象內文本溢出時不顯示省略標記,而是將溢出的部分裁切掉。 前言:項目中我們經常遇到這種需求,需要對單行、多行文本超出顯示為省略號。這篇文章主要總結了小編解決此問題的方法,有不足之處歡迎大家指正。 單行文本省略 showImg(https://segme...
摘要:前言項目中我們經常遇到這種需求,需要對單行多行文本超出顯示為省略號。單行文本省略文本溢出顯示省略號文本不會換行語法默認值適用于所有元素當對象內文本溢出時不顯示省略標記,而是將溢出的部分裁切掉。 前言:項目中我們經常遇到這種需求,需要對單行、多行文本超出顯示為省略號。這篇文章主要總結了小編解決此問題的方法,有不足之處歡迎大家指正。 單行文本省略 showImg(https://segme...
閱讀 2435·2021-09-30 09:48
閱讀 3821·2021-09-24 10:27
閱讀 2116·2021-09-22 15:32
閱讀 2223·2021-08-09 13:44
閱讀 3767·2019-08-30 15:55
閱讀 1207·2019-08-29 17:12
閱讀 2323·2019-08-29 17:05
閱讀 3067·2019-08-29 13:43