Heim >Web-Frontend >js-Tutorial >Behandeln Sie den Überlauf von mehrzeiligem Text, indem Sie eine V-Clamp-Anweisung einkapseln
Der Inhalt dieses Artikels befasst sich mit der Verarbeitung des Überlaufs von mehrzeiligem Text durch Kapselung einer V-Clamp-Anweisung. Ich hoffe, dass er für Sie hilfreich ist.
Als ich kürzlich an einem Projekt gearbeitet habe, bin ich auf eine Anforderung gestoßen: Der Text im Div muss in zwei Zeilen angezeigt werden. Die Breite des Div ist festgelegt. Wenn es überläuft, werden Auslassungspunkte angezeigt angezeigt. Wir alle kennen das Überlaufproblem von einzeiligem Text. Fügen Sie einfach das folgende CSS-Attribut hinzu und es ist in Ordnung:
overflow: hidden; white-space: nowrap; //段落中文本不换行 text-overflow: ellipsis;
Nachdem ich die Informationen überprüft hatte, stellte ich fest, dass es immer noch einen Weg gibt
Die Seitenimplementierung im WebKit-Browser oder im mobilen Endgerät (die meisten Browser mit WebKit-Kern) ist relativ einfach und Sie können WebKit verwenden direkt. CSS-erweiterte Eigenschaften (WebKit ist eine private Eigenschaft)-webkit-line-clamp ;Hinweis: Dies ist eine nicht unterstützte WebKit-Eigenschaft und erscheint nicht in CSS im Spezifikationsentwurf. -webkit-line-clamp wird verwendet, um die Anzahl der in einem Blockelement angezeigten Textzeilen zu begrenzen. Um diesen Effekt zu erzielen, muss es mit anderen WebKit-Eigenschaften kombiniert werden.
Wir können dies mit dem folgenden Code erreichen:
overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
Bei dieser Methode treten jedoch Kompatibilitätsprobleme auf und sie funktioniert nicht im Firefox-Browser.
Um das Kompatibilitätsproblem zu lösen, gibt es clamp.js[https://www.npmjs.com/package...], das dieses Problem sehr gut löst.
Um die Integration mit Vue zu verbessern, werden wir heute eine V-Clamp-Anweisung kapseln, um dieses Problem bequem zu lösen.
// 注册一个全局自定义指令 `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}) } })
Es ist eigentlich ganz einfach. Es verschiebt nur die Funktionen in clamp.js. Dann kannst du es so verwenden:
<div class="txt" v-clamp>很抱歉!没有搜索到相关模板很抱歉!没有搜索到相关模板很抱歉!没有搜索到相关模板很抱歉!没有搜索到相关模板</div>
Das obige ist der detaillierte Inhalt vonBehandeln Sie den Überlauf von mehrzeiligem Text, indem Sie eine V-Clamp-Anweisung einkapseln. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!