用 jQuery 检测换行符?

发布于 2024-10-11 08:41:34 字数 77 浏览 10 评论 0原文

是否可以让 jQuery/javascript 检测字符串被破坏的位置(为了适应 CSS 宽度限制),以便在新行开始之前插入 DOM 元素?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

谜兔 2024-10-18 08:41:34

我想出了一种方法,但对于您的目的来说可能有点过分了,所以请考虑到这一点。

您需要创建元素的克隆,清空原始元素,然后将每个单词移回到原始元素中。如果高度在任何时候发生变化,则该单词之前会有一个换行符。使用 $(el).text() 做到这一点相当简单,但如果里面可以有其他标签,而不仅仅是文本,那就会变得更加复杂。我尝试在这个答案框中解释如何按节点分解它,但发现在 jsFiddle 中创建 jQuery 插件更容易。链接在这里:http://jsfiddle.net/nathan/qkmse/ (

它不能很好地处理浮动元素,并且在其他一些情况下它会掉落。如果您想要更多选项,或者它不太适合您的目的,或者您不确定如何应用它,请告诉我,我会尽力提供帮助。

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).

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.

不爱素颜 2024-10-18 08:41:34

这是一种方法。注意:如果不使用等宽字体,我看不到理想的解决方案。与字符相等使这项任务变得更加容易。

  1. 等宽字符
  2. 计算一个字符的大小
  3. 计算容器的大小 查找
  4. 每行的字符 查找
  5. 行将中断的位置(即空格、破折号等)
  6. 获取所有中断索引。

查看 jsfiddle 相关的 html。我还没有完成这个功能。计算断裂指数时需要进行更多检查。现在它使用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

http://jsfiddle.net/Y5Ftn/1/

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.

  1. Equal width characters
  2. Calculate the size of one character
  3. Calculate the size of the container
  4. Find characters per row
  5. Find where the row will break (ie whitespace, dashes, etc)
  6. 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.

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

http://jsfiddle.net/Y5Ftn/1/

留一抹残留的笑 2024-10-18 08:41:34

这是我的脚本,它接受文本,然后使每一行成为一个跨度

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

<div class="title">
        <a href="">SOME TEXT LONG TEXT ANDTHISISLONG AND THIS OTHER TEXT</a>
    </div>

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>");
                }
            }

        });

    });

你必须包含 jQuery。

this is my script, that takes text, and then makes each line a span

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

<div class="title">
        <a href="">SOME TEXT LONG TEXT ANDTHISISLONG AND THIS OTHER TEXT</a>
    </div>

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.

吃→可爱长大的 2024-10-18 08:41:34

或者,您可以将文本块的宽度与其父级的宽度进行比较。如果块的宽度至少是其父块的 98%,则非常确定它会损坏

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

远山浅 2024-10-18 08:41:34

我不知道任何内置的 jQuery 或 javascript 函数可以做到这一点。不过,您可以自己执行此操作,但如果您有大量文本,则可能会很慢。

理论上,您可以确保高度设置为自动,删除文本,然后逐字重新插入它。当高度发生变化时,您删除最后一个单词,然后插入 dom 元素。同样,如果有大量文本,这会很慢,更好的方法是不更改原始元素,而是在另一个可以隐藏的元素中进行更改,然后在完成后替换原始元素。这样,您的用户就不会看到内容消失然后逐字返回。

另一种方法是使用类似的原理,从一个相同大小且高度为 auto 的空元素开始,然后插入一个新字符和一个空格,直到得到一个新行。从那里,您可以将其用作上述技术的近似值,或者您可以盲目地添加每个字符串的长度,直到找到新行,同时考虑到 dom 元素的宽度。不过,这种技术对于等宽字体效果更好,这就是仅将其用作近似值的地方。

也就是说,有一种方法可以使用画布来测量文本,但这可能是极端的。理论上来说,创建一个画布元素,获取上下文,设置所有字体属性,然后使用 context.measureText() 方法。您可以在此处找到其使用示例

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.

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.

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.

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.

初熏 2024-10-18 08:41:34

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.

铁憨憨 2024-10-18 08:41:34

我认为使用正则表达式会更容易检测——在保持效率的同时更少的代码。

这是对我有用的东西:

if ((/(\r\n|\n|\r)/.test($(this).val()))) {
    alert('there are line breaks here')
}

我不确定这是否适用于断弦,但它适用于使用 jQuery 检测换行符。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文