Javascript 用jQuery检测换行符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4671713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
detecting line-breaks with jQuery?
提问by Mild Fuzz
is it possible to have jQuery/javascript detect where a string is broken (in order to fit into CSS width constraints) so as to insert DOM elements before the beginning of a new line?
是否可以让 jQuery/javascript 检测字符串在哪里被破坏(为了适应 CSS 宽度约束),以便在新行的开头之前插入 DOM 元素?
回答by Nathan MacInnes
I came up with an approach, but it might be overkill for your purposes, so take this into account.
我想出了一种方法,但对于您的目的来说可能有点矫枉过正,因此请考虑到这一点。
You need to create a clone of the element, empty the original, then move each word back into the original element. If the height changes at any point, there's a line-break before that word. This would be fairly simple to do using $(el).text()
, but it gets more complicated if there can be other tags inside, not just text. I tried explaining how to break it down by node in this answer box, but found it easier just to create a jQuery plugin in a jsFiddle. Link here: http://jsfiddle.net/nathan/qkmse/(Gist).
您需要创建元素的副本,清空原始元素,然后将每个单词移回原始元素。如果高度在任何时候发生变化,则在该词之前会有一个换行符。使用 做起来相当简单$(el).text()
,但如果内部可以有其他标签,而不仅仅是文本,则会变得更加复杂。我尝试在这个答案框中解释如何按节点分解它,但发现在 jsFiddle 中创建一个 jQuery 插件更容易。链接在这里:http: //jsfiddle.net/nathan/qkmse/(要点)。
It won't handle floated elements all that well, and there are a few other situations where it'll fall over. Let me know if you'd like more options, or if it doesn't quite work for your purposes, or if you're not sure how to apply it and I'll try to help.
它不会很好地处理浮动元素,并且还有其他一些情况它会倒下。如果您想要更多选择,或者它不适合您的目的,或者您不确定如何应用它,请告诉我,我会尽力提供帮助。
回答by Josiah Ruddell
Here is one approach. Note: I do not see a ideal solution without using monospace fonts. The equal with characters make this task much easier.
这是一种方法。注意:如果不使用等宽字体,我看不到理想的解决方案。与字符相等使此任务更容易。
- Equal width characters
- Calculate the size of one character
- Calculate the size of the container
- Find characters per row
- Find where the row will break (ie whitespace, dashes, etc)
- Get all breaking indexes.
- 等宽字符
- 计算一个字符的大小
- 计算容器的大小
- 查找每行字符
- 查找行将中断的位置(即空格、破折号等)
- 获取所有破坏索引。
Have a look at the jsfiddle for associated html. I have not completed this function. More checks need to be put in when calculating the breaking index. Right now it is using lastIndexOf(' '), but this ignores that the next index could be a space, or the current. Also I am not accounting for other line-breaking characters. However this should be a great starting point.
查看相关 html 的 jsfiddle。我还没有完成这个功能。在计算断裂指数时需要进行更多的检查。现在它正在使用 lastIndexOf(' '),但这忽略了下一个索引可能是一个空格或当前索引。此外,我不考虑其他换行字符。然而,这应该是一个很好的起点。
var text = $('#text').text(), // "lorem ipsum ... "
len = text.length, // total chars
width = $('#text').width(), // container width
span = $('<span />').append('a').appendTo('#sandbox'),
charWidth = span.width(), // add single character to span and test width
charsPerRow = Math.floor(width/charWidth); // total characters that can fit in one row
var breakingIndexes = [], // will contain indexes of all soft-breaks
gRowStart = 0, // global row start index
gRowEnd = charsPerRow;// global row end index
while(gRowEnd < len){
var rowEnd = text.substring(gRowStart, gRowEnd).lastIndexOf(' '); // add more checks for break conditions here
breakingIndexes.push(gRowStart + rowEnd); // add breaking index to array
gRowStart = gRowStart + rowEnd + 1; // next start is the next char
gRowEnd = gRowStart + charsPerRow; // global end inxex is start + charsperrow
}
var text2 = $('#text2').text(); // "lorem ipsum ... " now not width bound
var start = 0, newText = '';
for(var i=0; i < breakingIndexes.length; i++){
newText += text2.substring(start, breakingIndexes[i]) + '<br />'; // add hard breaks
start = breakingIndexes[i]; // update start
}
$('#text2').html(newText); // output with breaks
回答by Chris Panayotoff
this is my script, that takes text, and then makes each line a span
这是我的脚本,它需要文本,然后使每一行成为一个跨度
CSS:
CSS:
margin: 0;
padding: 0;
}
.title{
width: 300px;
background-color: rgba(233,233,233,0.5);
line-height: 20px;
}
span{
color: white;
background-color: red;
display: inline-block;
font-size: 30px;
}
a{
text-decoration: none;
color: black;
}
html
html
<div class="title">
<a href="">SOME TEXT LONG TEXT ANDTHISISLONG AND THIS OTHER TEXT</a>
</div>
JS
JS
$(function(){
$(".title").find("a").each(function(){
var $this = $(this);
var originalText = $this.text();
$this.empty();
var sections = [];
$.each( originalText.split(" "), function(){
var $span = $("<span>" + this + "</span>");
$this.append($span);
var index = $span.position().top;
if( sections[index] === undefined ){
sections[index] = "";
}
sections[index] += $span.text() + " ";
});
$this.empty();
for(var i = 0; i< sections.length; i++){
if( sections[i] !== undefined ){
var spanText = $.trim(sections[i]);
$this.append("<span>" + spanText + "</span>");
}
}
});
});
You have to got jQuery included.
你必须包含 jQuery。
回答by Harijs Deksnis
Alternatively you could compare width of the text block with its parent's width. If the block is at least 98% of the width of its parent, pretty sure it breaks
或者,您可以将文本块的宽度与其父级的宽度进行比较。如果块至少是其父块宽度的 98%,则很确定它会损坏
回答by streetlight
I think it would be easier to detect using a regex -- much less code while retaining efficiency.
我认为使用正则表达式检测会更容易——在保持效率的同时减少代码。
Here's something that worked for me:
这是对我有用的东西:
if ((/(\r\n|\n|\r)/.test($(this).val()))) {
alert('there are line breaks here')
}
I'm not sure if this will work with your broken strings, but it works for detecting line-breks with jQuery.
我不确定这是否适用于您损坏的字符串,但它适用于使用 jQuery 检测换行符。
回答by Josh Schumacher
Not sure what exactly your use case is but http://code.google.com/p/hyphenator/may be a solution to your problem or if you dig into the hyphenator.js source code, you may be able to find the code you are looking for.
不确定您的用例究竟是什么,但http://code.google.com/p/hyphenator/可能是您问题的解决方案,或者如果您深入研究 hyphenator.js 源代码,您也许能够找到代码你正在寻找。
回答by LoveAndCoding
I don't know of any built in jQuery of javascript function to do this. You could, however, do it yourself, but it would be potentially slow if you have a lot of text.
我不知道有任何内置 jQuery 的 javascript 函数可以做到这一点。但是,您可以自己完成,但是如果您有很多文本,它可能会很慢。
In theory, you could make sure the height is set to auto, remove the text, and then word by word reinsert it. On a change in the height, you remove the last word, and insert your dom element. Again, this will be slow if there is a lot of text, and the better way to do this would be to not change the original element, but do it in another element which could be hidden, and then replace the original element on completion. That way, your user wouldn't see the content disappear and then come back word by word.
理论上,您可以确保将高度设置为自动,删除文本,然后逐字重新插入。在高度发生变化时,删除最后一个单词,然后插入 dom 元素。同样,如果有很多文本,这会很慢,更好的方法是不更改原始元素,而是在另一个可以隐藏的元素中执行,然后在完成时替换原始元素。这样,您的用户就不会看到内容消失,然后一个字一个字地回来。
Another way would be to use a similar principle, and start with an empty element of the same size with height auto, and insert a new character and a space until you get a new line. From there, you can use this as an approximation with the above techinique, or you can blindly add up the length of each string until you find a new line, taking into account the width of your dom element. This technique works better with monospaced fonts though, which is where using it only as an approximation comes in.
另一种方法是使用类似的原则,从一个高度为 auto 的相同大小的空元素开始,然后插入一个新字符和一个空格,直到你得到一个新行。从那里,您可以将其用作上述技术的近似值,或者您可以盲目地将每个字符串的长度相加,直到找到一个新行,同时考虑到 dom 元素的宽度。不过,这种技术对等宽字体效果更好,这只是将其用作近似值的地方。
That said, there is a way to measure text using canvas, but that may be extreme. In theory it would be, create a canvas element, get the context, set all the font properties, and then use the context.measureText()
method. An example of it use can be found here.
也就是说,有一种使用画布测量文本的方法,但这可能是极端的。理论上它会是,创建一个画布元素,获取上下文,设置所有字体属性,然后使用该context.measureText()
方法。可以在此处找到它的使用示例。