Есть ли у JavaScript способ обрезания HTML-текста без всех головных болей совпадающих меток и т.д.?
Спасибо.
Есть ли у JavaScript способ обрезания HTML-текста без всех головных болей совпадающих меток и т.д.?
Спасибо.
Там нет встроенного javascript. Там плагин jQuery, на который вы можете взглянуть.
У меня была такая же проблема, и я закончил писать следующее, чтобы справиться с этим. Он обрезает HTML до длины, очищает любые теги начала и конца, которые, возможно, были отключены в конце, а затем закрывает все теги, оставшиеся незакрытыми:
function truncateHTML(text, length) {
var truncated = text.substring(0, length);
// Remove line breaks and surrounding whitespace
truncated = truncated.replace(/(\r\n|\n|\r)/gm,"").trim();
// If the text ends with an incomplete start tag, trim it off
truncated = truncated.replace(/<(\w*)(?:(?:\s\w+(?:={0,1}(["']{0,1})\w*\2{0,1})))*$/g, '');
// If the text ends with a truncated end tag, fix it.
var truncatedEndTagExpr = /<\/((?:\w*))$/g;
var truncatedEndTagMatch = truncatedEndTagExpr.exec(truncated);
if (truncatedEndTagMatch != null) {
var truncatedEndTag = truncatedEndTagMatch[1];
// Check to see if there an identifiable tag in the end tag
if (truncatedEndTag.length > 0) {
// If so, find the start tag, and close it
var startTagExpr = new RegExp(
"<(" + truncatedEndTag + "\\w?)(?:(?:\\s\\w+(?:=([\"\'])\\w*\\2)))*>");
var testString = truncated;
var startTagMatch = startTagExpr.exec(testString);
var startTag = null;
while (startTagMatch != null) {
startTag = startTagMatch[1];
testString = testString.replace(startTagExpr, '');
startTagMatch = startTagExpr.exec(testString);
}
if (startTag != null) {
truncated = truncated.replace(truncatedEndTagExpr, '</' + startTag + '>');
}
} else {
// Otherwise, cull off the broken end tag
truncated = truncated.replace(truncatedEndTagExpr, '');
}
}
// Now the tricky part. Reverse the text, and look for opening tags. For each opening tag,
// check to see that he closing tag before it is for that tag. If not, append a closing tag.
var testString = reverseHtml(truncated);
var reverseTagOpenExpr = /<(?:(["'])\w*\1=\w+ )*(\w*)>/;
var tagMatch = reverseTagOpenExpr.exec(testString);
while (tagMatch != null) {
var tag = tagMatch[0];
var tagName = tagMatch[2];
var startPos = tagMatch.index;
var endPos = startPos + tag.length;
var fragment = testString.substring(0, endPos);
// Test to see if an end tag is found in the fragment. If not, append one to the end
// of the truncated HTML, thus closing the last unclosed tag
if (!new RegExp("<" + tagName + "\/>").test(fragment)) {
truncated += '</' + reverseHtml(tagName) + '>';
}
// Get rid of the already tested fragment
testString = testString.replace(fragment, '');
// Get another tag to test
tagMatch = reverseTagOpenExpr.exec(testString);
}
return truncated;
}
function reverseHtml(str) {
var ph = String.fromCharCode(206);
var result = str.split('').reverse().join('');
while (result.indexOf('<') > -1) {
result = result.replace('<',ph);
}
while (result.indexOf('>') > -1) {
result = result.replace('>', '<');
}
while (result.indexOf(ph) > -1) {
result = result.replace(ph, '>');
}
return result;
}
Я знаю, что этот вопрос старый, но у меня недавно была такая же проблема. Я написал следующую библиотеку, которая безопасно обрезает действительный HTML: https://github.com/arendjr/text-clipper
Там плагин mootools, который делает именно то, что вам нужно: mooReadAll в mouools forge
Недавно я закончил функцию jQuery, чтобы сделать это, используя ширину и высоту контейнера. Протестируйте его и посмотрите, работает ли он для вас. Я еще не уверен в проблемах совместимости, ошибках или ограничениях, но я тестировал их в FF, Chrome и IE7.
Если вам нужно более легкое решение в vanilla JS, это должно сработать, хотя в нем останутся пустые элементы, поэтому все зависит от того, заботитесь ли вы о них. Также обратите внимание, что он мутирует узлы на месте.
function truncateNode(node, limit) {
if (node.nodeType === Node.TEXT_NODE) {
node.textContent = node.textContent.substring(0, limit);
return limit - node.textContent.length;
}
node.childNodes.forEach((child) => {
limit = truncateNode(child, limit);
});
return limit;
}
const span = document.createElement('span');
span.innerHTML = '<b>foo</b><i>bar</i><u>baz</u>';
truncateNode(span, 5);
expect(span.outerHTML).toEqual('<span><b>foo</b><i>ba</i><u></u></span>');
Я просмотрел интернет, ища ответ на этот вопрос сам, и в конце концов решил, что мне лучше просто написать функцию для выполнения усечения (в отличие от импорта библиотеки для этого. Мой пример использования был довольно узким ( усекая текст до определенного количества символов, я также удостоверяюсь, что эллипсы вставлены в конец ближайшего слова в эту позицию:
function truncate(str){
if (str.length > 150){
var pos = 125, // truncate at 125 chars
// Search for the word end.
right = str.slice(pos).search(/\s/);
return '<div class="newString">' + str.substring(0, pos + right)+'<span style="display:inline;"class="read-more">... more</span>';
}
else{
return str;
}
}
Это довольно сложно.
Если у вас нет разметки HTML,, это может быть полезно.