使用jQuery检测换行符?
有没有可能让jQuery / javascript检测字符串被破坏的位置(为了适应CSS宽度约束),以便在新行的开头之前插入DOM元素?
我提出了一种方法,但是对于你的目的来说可能有些过分,所以考虑到这一点。
您需要创建元素的克隆,清空原始元素,然后将每个单词移回原始元素。 如果高度在任何点发生变化,那么在该单词之前会有一个换行符。 使用$(el).text()
可以相当简单,但如果内部可以有其他标记,则会变得更复杂,而不仅仅是文本。 我试着解释如何在这个答案框中按节点分解它,但发现在jsFiddle中创建一个jQuery插件更容易。 链接到这里: http : //jsfiddle.net/nathan/qkmse/ ( Gist )。
它不会很好地处理浮动元素,还有一些其他情况会崩溃。 如果您想要更多选项,或者如果它不适合您的目的,或者如果您不确定如何应用它,我会尽力帮助我。
这是一种方法。 注意:如果不使用等宽字体,我看不到理想的解决方案。 与字符相等使这项任务更容易。
- 等宽字符
- 计算一个字符的大小
- 计算容器的大小
- 每行查找字符
- 查找行将中断的位置(即空白,破折号等)
- 获取所有破坏索引。
看一下相关html的jsfiddle。 我还没有完成这个function。 在计算破坏指数时需要进行更多检查。 现在它正在使用lastIndexOf(”),但这忽略了下一个索引可能是空格或当前。 另外,我不考虑其他破线字符。 然而,这应该是一个很好的起点。
var text = $('#text').text(), // "lorem ipsum ... " len = text.length, // total chars width = $('#text').width(), // container width 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]) + '
'; // add hard breaks start = breakingIndexes[i]; // update start } $('#text2').html(newText); // output with breaks
这是我的脚本,它接受文本,然后使每一行成为一个跨度
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
JS
$(function(){ $(".title").find("a").each(function(){ var $this = $(this); var originalText = $this.text(); $this.empty(); var sections = []; $.each( originalText.split(" "), function(){ var $span = $("" + this + ""); $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("" + spanText + ""); } } }); });
你必须得到jQuery。
我不知道有任何内置的jQuery javascript函数来做到这一点。 但是,你可以自己做,但如果你有很多文字,它可能会很慢。
理论上,您可以确保将高度设置为自动,删除文本,然后逐字逐句重新插入。 在更改高度时,删除最后一个单词,然后插入dom元素。 同样,如果有大量文本,这将会很慢,更好的方法是不更改原始元素,而是在另一个可隐藏的元素中执行,然后在完成时替换原始元素。 这样,您的用户就不会看到内容消失,然后逐字回复。
另一种方法是使用类似的原理,并从具有高度auto的相同大小的空元素开始,并插入新的字符和空格,直到获得新的行。 从那里,你可以使用它作为上述技术的近似,或者你可以盲目地加上每个字符串的长度,直到你找到一个新的行,考虑到你的dom元素的宽度。 尽管使用等宽字体,这种技术效果更好,这只是作为近似值使用它的地方。
也就是说,有一种方法可以使用canvas来测量文本,但这可能是极端的。 从理论上讲,它将创建一个canvas元素,获取上下文,设置所有字体属性,然后使用context.measureText()
方法。 可以在此处找到它的使用示例。
不确定您的用例究竟是什么,但http://code.google.com/p/hyphenator/可能是您的问题的解决方案,或者如果您深入了解hyphenator.js源代码,您可能能够找到代码你在找。
我认为使用正则表达式检测更容易 – 在保持效率的同时更少的代码。
这对我有用:
if ((/(\r\n|\n|\r)/.test($(this).val()))) { alert('there are line breaks here') }
我不确定这是否适用于你的断字符串,但它适用于使用jQuery检测行错误。
或者,您可以比较文本块的宽度与其父级的宽度。 如果该块至少是其父级宽度的98%,那么确定它会中断