寻找“换行符”在文本区域中,这是自动换行阿拉伯语文本

发布于 2024-10-12 15:38:30 字数 492 浏览 3 评论 0原文

我有一串文本显示在文本区域中(从右到左方向)。用户可以动态调整文本区域的大小(我使用jquery)并且文本将根据需要换行。

当用户点击提交时,我将获取该文本并使用 PHP 创建图像,但在提交之前我想知道“换行符”或“自动换行”发生在哪里。

到目前为止我看过的所有地方都只向我展示了如何在 php 端处理换行符。我想澄清的是,没有换行符。我拥有的是一个长字符串,它将根据用户设置的文本区域的宽度以不同的方式进行换行。

我无法使用“列”或任何其他标准宽度表示形式,因为我有一种非常复杂的阿拉伯字体,它实际上由许多不同宽度的字形(字符)组成。

如果有人知道访问自动换行发生位置的方法(如果需要,可以在文本区域或 div 中),我真的很想知道。

我唯一的其他解决方案是实际存储(在我的数据库中)每个字符的宽度(有点乏味,因为 600 种不同字体中有 200 多个字符,总共......一些巨大的数字)。

我的希望不高,但我想我会问。

谢谢

我。贾马尔

I have a string of text that I display in a textarea (right-to-left orientation). The user can resize the textarea dynamically (I use jquery for this) and the text will wrap as necessary.

When the user hits submit, I will take that text and create an image using PHP, BUT before submitting I would like to know where the "line-breaks" or rather "word-wraps" occur.

Everywhere I have looked so far only shows me how to process line-breaks on the php side. I want to make it clear that there ARE NO LINE-BREAKS. What I have is one LONG string that will be word-wrapped in different ways based on the width of the textarea set by the user.

I can't use "columns" or any other standard width representation because I have a very complex arabic font that is actually composed of glyphs (characters) of numerous different widths.

If anyone knows of a way of accessing where the word wraps occur (either in a textarea or a div if need-be), I'd really like to know.

My only other solution is to actually store (in my DB) the width of every single character (somewhat tedious since there are over 200 characters in 600 different fonts, for a total of...some huge number).

My hopes aren't high, but I thought I would ask.

Thanks

i. jamal

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

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

发布评论

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

评论(7

情栀口红 2024-10-19 15:38:30

好吧,您可以使用此函数强制将它们放入文本区域,而不是找到换行符(这实际上是不可能的):

function ApplyLineBreaks(strTextAreaId) {
    var oTextarea = document.getElementById(strTextAreaId);
    if (oTextarea.wrap) {
        oTextarea.setAttribute("wrap", "off");
    }
    else {
        oTextarea.setAttribute("wrap", "off");
        var newArea = oTextarea.cloneNode(true);
        newArea.value = oTextarea.value;
        oTextarea.parentNode.replaceChild(newArea, oTextarea);
        oTextarea = newArea;
    }

    var strRawValue = oTextarea.value;
    oTextarea.value = "";
    var nEmptyWidth = oTextarea.scrollWidth;
    var nLastWrappingIndex = -1;
    for (var i = 0; i < strRawValue.length; i++) {
        var curChar = strRawValue.charAt(i);
        if (curChar == ' ' || curChar == '-' || curChar == '+')
            nLastWrappingIndex = i;
        oTextarea.value += curChar;
        if (oTextarea.scrollWidth > nEmptyWidth) {
            var buffer = "";
            if (nLastWrappingIndex >= 0) {
                for (var j = nLastWrappingIndex + 1; j < i; j++)
                    buffer += strRawValue.charAt(j);
                nLastWrappingIndex = -1;
            }
            buffer += curChar;
            oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length - buffer.length);
            oTextarea.value += "\n" + buffer;
        }
    }
    oTextarea.setAttribute("wrap", "");
}

此函数获取文本区域的ID,并且每当有自动换行,它将新换行符推入文本区域。运行表单提交中的函数,您将在服务器端代码中获得带有正确换行符的文本。

已在 IE、Chrome 和 Firefox 上成功测试,您可以在这里亲自查看:http://jsfiddle.net/ yahavbr/pH79a/1/ (预览将显示新行)

Well, instead of finding the line breaks (which is virtually impossible) you can force them into the textarea, using this function:

function ApplyLineBreaks(strTextAreaId) {
    var oTextarea = document.getElementById(strTextAreaId);
    if (oTextarea.wrap) {
        oTextarea.setAttribute("wrap", "off");
    }
    else {
        oTextarea.setAttribute("wrap", "off");
        var newArea = oTextarea.cloneNode(true);
        newArea.value = oTextarea.value;
        oTextarea.parentNode.replaceChild(newArea, oTextarea);
        oTextarea = newArea;
    }

    var strRawValue = oTextarea.value;
    oTextarea.value = "";
    var nEmptyWidth = oTextarea.scrollWidth;
    var nLastWrappingIndex = -1;
    for (var i = 0; i < strRawValue.length; i++) {
        var curChar = strRawValue.charAt(i);
        if (curChar == ' ' || curChar == '-' || curChar == '+')
            nLastWrappingIndex = i;
        oTextarea.value += curChar;
        if (oTextarea.scrollWidth > nEmptyWidth) {
            var buffer = "";
            if (nLastWrappingIndex >= 0) {
                for (var j = nLastWrappingIndex + 1; j < i; j++)
                    buffer += strRawValue.charAt(j);
                nLastWrappingIndex = -1;
            }
            buffer += curChar;
            oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length - buffer.length);
            oTextarea.value += "\n" + buffer;
        }
    }
    oTextarea.setAttribute("wrap", "");
}

This function get ID of textarea and whenever there is word wrap, it push new line break into the textarea. Run the function in the form submit and you will get the text with proper line breaks in the server side code.

Tested successfully for IE, Chrome and Firefox feel free to see for yourself here: http://jsfiddle.net/yahavbr/pH79a/1/ (The preview will show the new lines)

随遇而安 2024-10-19 15:38:30

下面是 Shadow Wizard 解决方案的功能等效实现,速度要快得多,因为它使用二分搜索而不是线性搜索来确定每行的长度:

function ApplyLineBreaks(strTextAreaId) {
    var oTextarea = document.getElementById(strTextAreaId);
    if (oTextarea.wrap) {
        oTextarea.setAttribute("wrap", "off");
    }
    else {
        oTextarea.setAttribute("wrap", "off");
        var newArea = oTextarea.cloneNode(true);
        newArea.value = oTextarea.value;
        oTextarea.parentNode.replaceChild(newArea, oTextarea);
        oTextarea = newArea;
    }

    var strRawValue = oTextarea.value;
    oTextarea.value = "";
    var nEmptyWidth = oTextarea.scrollWidth;

    function testBreak(strTest) {
        oTextarea.value = strTest;
        return oTextarea.scrollWidth > nEmptyWidth;
    }
    function findNextBreakLength(strSource, nLeft, nRight) {
        var nCurrent;
        if(typeof(nLeft) == 'undefined') {
            nLeft = 0;
            nRight = -1;
            nCurrent = 64;
        }
        else {
            if (nRight == -1)
                nCurrent = nLeft * 2;
            else if (nRight - nLeft <= 1)
                return Math.max(2, nRight);
            else
                nCurrent = nLeft + (nRight - nLeft) / 2;
        }
        var strTest = strSource.substr(0, nCurrent);
        var bLonger = testBreak(strTest);
        if(bLonger)
            nRight = nCurrent;
        else
        {
            if(nCurrent >= strSource.length)
                return null;
            nLeft = nCurrent;
        }
        return findNextBreakLength(strSource, nLeft, nRight);
    }

    var i = 0, j;
    var strNewValue = "";
    while (i < strRawValue.length) {
        var breakOffset = findNextBreakLength(strRawValue.substr(i));
        if (breakOffset === null) {
            strNewValue += strRawValue.substr(i);
            break;
        }
        var nLineLength = breakOffset - 1;
        for (j = nLineLength - 1; j >= 0; j--) {
            var curChar = strRawValue.charAt(i + j);
            if (curChar == ' ' || curChar == '-' || curChar == '+') {
                nLineLength = j + 1;
                break;
            }
        }
        strNewValue += strRawValue.substr(i, nLineLength) + "\n";
        i += nLineLength;
    }
    oTextarea.value = strNewValue;
    oTextarea.setAttribute("wrap", "");
}

更新了小提琴

Here is a functionally-equivalent implementation of Shadow Wizard's solution that is much faster because it uses binary search instead of linear search to determine the length of each line:

function ApplyLineBreaks(strTextAreaId) {
    var oTextarea = document.getElementById(strTextAreaId);
    if (oTextarea.wrap) {
        oTextarea.setAttribute("wrap", "off");
    }
    else {
        oTextarea.setAttribute("wrap", "off");
        var newArea = oTextarea.cloneNode(true);
        newArea.value = oTextarea.value;
        oTextarea.parentNode.replaceChild(newArea, oTextarea);
        oTextarea = newArea;
    }

    var strRawValue = oTextarea.value;
    oTextarea.value = "";
    var nEmptyWidth = oTextarea.scrollWidth;

    function testBreak(strTest) {
        oTextarea.value = strTest;
        return oTextarea.scrollWidth > nEmptyWidth;
    }
    function findNextBreakLength(strSource, nLeft, nRight) {
        var nCurrent;
        if(typeof(nLeft) == 'undefined') {
            nLeft = 0;
            nRight = -1;
            nCurrent = 64;
        }
        else {
            if (nRight == -1)
                nCurrent = nLeft * 2;
            else if (nRight - nLeft <= 1)
                return Math.max(2, nRight);
            else
                nCurrent = nLeft + (nRight - nLeft) / 2;
        }
        var strTest = strSource.substr(0, nCurrent);
        var bLonger = testBreak(strTest);
        if(bLonger)
            nRight = nCurrent;
        else
        {
            if(nCurrent >= strSource.length)
                return null;
            nLeft = nCurrent;
        }
        return findNextBreakLength(strSource, nLeft, nRight);
    }

    var i = 0, j;
    var strNewValue = "";
    while (i < strRawValue.length) {
        var breakOffset = findNextBreakLength(strRawValue.substr(i));
        if (breakOffset === null) {
            strNewValue += strRawValue.substr(i);
            break;
        }
        var nLineLength = breakOffset - 1;
        for (j = nLineLength - 1; j >= 0; j--) {
            var curChar = strRawValue.charAt(i + j);
            if (curChar == ' ' || curChar == '-' || curChar == '+') {
                nLineLength = j + 1;
                break;
            }
        }
        strNewValue += strRawValue.substr(i, nLineLength) + "\n";
        i += nLineLength;
    }
    oTextarea.value = strNewValue;
    oTextarea.setAttribute("wrap", "");
}

Updated fiddle.

慕烟庭风 2024-10-19 15:38:30

我认为最简单的方法是将 html 代码中文本区域的自动换行设置为“硬”,如下

<textarea id='yourTextArea' wrap='hard'></textarea>

所示 :提交时的字符串。如果您随后发现该字符串穿过您的字符串,则可以轻松确定最初的中断位置。或者你也可以使用 PHP 的 nl2br() 函数将这些字符转换为
html 标签。

I think the easiest way of doing it would be to set the word wrap of your textarea in the html code to 'hard', like this:

<textarea id='yourTextArea' wrap='hard'></textarea>

It means that wherever your textarea breaks the line for you will also insert a \n linebreak charachter in the string when submitting. If you then find this going through your string it will make it easy to determine where was the break originally. Or you can also turn these characters to
html tags with the nl2br() function of PHP.

小兔几 2024-10-19 15:38:30

出于某种原因,当这篇文章更新时,我从未收到过提醒……昨晚,我有了一个关于如何确定换行符的绝妙想法……
我会重建字符串,并每次检查宽度,它起作用了
所以我来这里分享它......发现我落后了 1 周,

无论如何 2 件重要的事情

  1. 您提供的代码使用了与我相同的绝妙想法(干得好)但是当我测试它时,它打破了第一个正确地行然后在每个字符后添加一个换行符(在链接 jsfiddle.net 上测试)

  2. 我添加了使用 jquery 的代码并使用跨度的宽度来确定何时换行
    起初我尝试使用 div 的宽度,但 div.width() 返回默认宽度,而不是内容的宽度。

我知道这可能不适用于所有浏览器
所以,我恳请如果有人知道一种方法可以使这个万无一失,或者接近它,请分享。

首先,样式对于同步 textarea 和 div 之间的字体(所有属性)、设置大小以及(对于 IE)删除任何自动出现的滚动条是必需的。


    .inputArea {
      width:200px; 
      height:100px; 
      font-family:Arial; 
      font-size:12px; 
      overflow: auto; 
      border: 1px solid #cccccc;
      padding:0;
      margin:0;
    }
    .divArea {
      font-family:Arial; 
      font-size:12px;
    }
  

接下来,我包括 jquery 和我的自定义函数:

  
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js
"></script>
  <script type="text/javascript">
  $(document).ready(function() {
     $("#breakUp").click(function () {
       showLineBreaks(); 
       addLineBreaks(); 
     });

     function showLineBreaks() {
       content = $("#textEntered").val();
       //replace line breaks in content with "|" to allow for replacement below
       content = content.replace("\r\n", "
"); content = content.replace("\r", "
"); content = content.replace("\n", "
"); $("#unedited").html(content); } function addLineBreaks() { content = $("#textEntered").val(); //replace line breaks in content with "|" to allow for replacement below content = content.replace("\r\n", "|"); content = content.replace("\r", "|"); content = content.replace("\n", "|"); tempContent = ""; $("#edited").html(""); for (var i = 0; i "); } else { tempContent = $("#edited").html(); $("#edited").html(tempContent + content.charAt(i)); if ($("#edited").width() > 200) { $("#edited").html(tempContent + "
" + content.charAt(i)); } } } } }); <script>

最后,我的 html 测试页


  Enter text into the textarea below (Set to 200 px width, 100 px height)<br>
  <textarea id="textEntered" class="inputArea"></textarea>
  <br><br>
  The div below will display that text WITHOUT wrapping, BUT replacing all existing line breaks with <br><br>
  <div id="unedited"></div>
  <br>
  The following div will display that text with line breaks ADDED to fit the wrapping<br>
  <div class="divArea"><span id="edited"></span></div>  
  <br>
  <button id="breakUp">Click Here to Convert</button>

For some reason, I was never alerted when this post was updated...and last night, I had this BRILLIANT idea on how to determine where the line breaks were...
I would rebuild the string, and check the width each time, and it WORKED
so I came here to share it...and found I was 1 week behind

Anyway 2 important things

  1. The code you provided uses the same brilliant idea I had (well done you) BUT when I test it, it breaks the first line correctly then adds a line break after every character (tested on the link jsfiddle.net)

  2. I've added my code which uses jquery and uses the width of a span to determine when to break
    At first I tried using the width of the div, but div.width() returns the default width, not the width of the content.

I AM AWARE THIS MAY NOT WORK ON ALL BROWSERS
so, I ask kindly that if anyone knows of a way of making this foolproof, or close to it, please share.

First, the styles are necessary to synchornize fonts (all attributes) between the textarea and div, set the size, and (for IE) remove any scrollbars that automatically appear.


    .inputArea {
      width:200px; 
      height:100px; 
      font-family:Arial; 
      font-size:12px; 
      overflow: auto; 
      border: 1px solid #cccccc;
      padding:0;
      margin:0;
    }
    .divArea {
      font-family:Arial; 
      font-size:12px;
    }
  

Next, I include jquery and my custom functions:

  
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js
"></script>
  <script type="text/javascript">
  $(document).ready(function() {
     $("#breakUp").click(function () {
       showLineBreaks(); 
       addLineBreaks(); 
     });

     function showLineBreaks() {
       content = $("#textEntered").val();
       //replace line breaks in content with "|" to allow for replacement below
       content = content.replace("\r\n", "
"); content = content.replace("\r", "
"); content = content.replace("\n", "
"); $("#unedited").html(content); } function addLineBreaks() { content = $("#textEntered").val(); //replace line breaks in content with "|" to allow for replacement below content = content.replace("\r\n", "|"); content = content.replace("\r", "|"); content = content.replace("\n", "|"); tempContent = ""; $("#edited").html(""); for (var i = 0; i "); } else { tempContent = $("#edited").html(); $("#edited").html(tempContent + content.charAt(i)); if ($("#edited").width() > 200) { $("#edited").html(tempContent + "
" + content.charAt(i)); } } } } }); <script>

And finally, my html test page


  Enter text into the textarea below (Set to 200 px width, 100 px height)<br>
  <textarea id="textEntered" class="inputArea"></textarea>
  <br><br>
  The div below will display that text WITHOUT wrapping, BUT replacing all existing line breaks with <br><br>
  <div id="unedited"></div>
  <br>
  The following div will display that text with line breaks ADDED to fit the wrapping<br>
  <div class="divArea"><span id="edited"></span></div>  
  <br>
  <button id="breakUp">Click Here to Convert</button>
月下凄凉 2024-10-19 15:38:30

这是我的示例,用于计算文本区域中每行文本的实际行数(换行后)。请注意,当滚动条开始出现时,文本区域的文本宽度会稍微缩小。这可能会导致先前内容进一步换行,从而导致先前计算的行高不正确。因此,文本区域必须将CSS样式的overflow-y设置为“滚动”,以强制始终显示滚动条

function get_row_wraps(txtArea){                        
    if(wrap=="off"){                                    
        var out=[];                                     
        for(var i=txtArea.split_lines.length; i>=0; --i)
            out[i]=1;                                   
        return out;                                     
    }                                                   

    var its=txtArea.value.split("\n");                        
    var newArea = txtArea.cloneNode(true);              
    newArea.hidden=true;                                
    newArea.style.visibility = "hidden";                
    txtArea.parentNode.appendChild(newArea);            

    // get single row height                            
    newArea.style.height="auto";                        
    newArea.style.overflowY="scroll";                   
    newArea.value="1\n2\n3";                            
    var unit_height=newArea.scrollHeight;               
    newArea.value="1\n2\n3\n4";                         
    var unit_height=newArea.scrollHeight-unit_height;   
    newArea.style.height=Math.round(unit_height*1.5)+"px"; // so that the scrollbar does not vanish
    newArea.value="";                                   

    // obtain row height for every line of text         
    function comp_Nrow(scroll_height){                  
        return Math.floor(scroll_height/unit_height);   
    }                                                   
    function calc_rows(txt){                            
        newArea.value+=txt;                             
        return comp_Nrow(newArea.scrollHeight);         
    }                                                   
    var out=[];                                         
    for(var i=0; i<its.length; i++)                     
        out.push(calc_rows(i==0?its[i]:("\n"+its[i]))); 
    txtArea.parentNode.removeChild(newArea);            
    for(var i=out.length-1; i>0; i--)                   
        out[i]-=out[i-1];                               
//  alert(out);                                         
    return out;                                         
}                                                       

上面的函数返回文本区域中每行文本(用“\n”分隔)的实际换行行数。
至少对于 Chrome 和 Firefox 来说,计算是准确的。

Here is my example for computing the actual number of rows (after line wrapping) for every line of text in a textarea. Take note that the text width of a textarea shrinks slightly when the scrollbar starts to appear. This can cause further wrapping of the previous content so that the previously computed row height will not be correct. Therefore, the textarea must have CSS-style overflow-y set to "scroll" to force the display of the scrollbar all the time.

function get_row_wraps(txtArea){                        
    if(wrap=="off"){                                    
        var out=[];                                     
        for(var i=txtArea.split_lines.length; i>=0; --i)
            out[i]=1;                                   
        return out;                                     
    }                                                   

    var its=txtArea.value.split("\n");                        
    var newArea = txtArea.cloneNode(true);              
    newArea.hidden=true;                                
    newArea.style.visibility = "hidden";                
    txtArea.parentNode.appendChild(newArea);            

    // get single row height                            
    newArea.style.height="auto";                        
    newArea.style.overflowY="scroll";                   
    newArea.value="1\n2\n3";                            
    var unit_height=newArea.scrollHeight;               
    newArea.value="1\n2\n3\n4";                         
    var unit_height=newArea.scrollHeight-unit_height;   
    newArea.style.height=Math.round(unit_height*1.5)+"px"; // so that the scrollbar does not vanish
    newArea.value="";                                   

    // obtain row height for every line of text         
    function comp_Nrow(scroll_height){                  
        return Math.floor(scroll_height/unit_height);   
    }                                                   
    function calc_rows(txt){                            
        newArea.value+=txt;                             
        return comp_Nrow(newArea.scrollHeight);         
    }                                                   
    var out=[];                                         
    for(var i=0; i<its.length; i++)                     
        out.push(calc_rows(i==0?its[i]:("\n"+its[i]))); 
    txtArea.parentNode.removeChild(newArea);            
    for(var i=out.length-1; i>0; i--)                   
        out[i]-=out[i-1];                               
//  alert(out);                                         
    return out;                                         
}                                                       

The above function returns the actual number of wrapped rows for each line of text (separated by "\n") in an textarea.
The computation is accurate at least for Chrome and Firefox.

丑疤怪 2024-10-19 15:38:30

代码在“Crome”、“Firefox”和“IE”上进行了测试。获取换行符和回车符组件“textArea”(使用 JavaScript 的客户端)。

效果很好!
我想与您分享

重要的是包括风格

    <html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<%--//definimos un estilo--%>
 <STYLE type="text/css">
    #CadTemp 
    {
        font-family: "Arial", serif; 
        font-size: 12pt; 
        visibility: hidden;
        position: absolute;
        top: -100;
        left: 0px;
    }
 </STYLE>

    <script type="text/javascript">
        function mostrar() {
            return 'ancho cadena: ' + document.getElementById('myTextarea').value.visualLength() + '  \n' + 'ancho textarea: ' + (document.getElementById('myTextarea').scrollWidth -4);
        }


        //sustituimos el espacio en blanco por el punto, tienen exactamente el mismo tamaño en 'pixeles'
        function reemplazarEspacios(texto) {
            var devolver = "";
            for (var i = 0; i < texto.length; i++) {
                if (texto.charAt(i) == ' ') {
                    devolver += '.'
                } else {
                    devolver += texto.charAt(i);
                }
            }
            return devolver;
        }

        // Calcula los pixeles de ancho que ocupa un texto (la cadena debe tener el mismo tamaño y tipo de fuente)
        String.prototype.visualLength = function () {
            var ruler = document.getElementById("CadTemp");            
            ruler.innerHTML = reemplazarEspacios(this)
            return ruler.offsetWidth;
        }

        //quitar espacios a la derecha de la cadena
        String.prototype.rtrim = function() {return this.replace(/\s+$/,"");}

        //devuelve el ultimo espacio de la cadena (que no sea espacio final)
        function IndEspacio(cadena) {
            //quito los espacios al final
            var cadenaTemp = cadena.rtrim();
            return cadenaTemp.lastIndexOf(' ');
        }

        //insertar un salto de linea
        function AplicarSaltosLinea(ID_elemento) {
           //guardo el elemento web en una variable
           var TextArea = document.getElementById(ID_elemento);
           var cadenaTexto = "";
           var Cadenafinal = "";
           var buffer = "";

           //recorremos toda la cadena
           for (var i = 0; i < TextArea.value.length; i++) {
                //guardamos el caracater en la cadena
                cadenaTexto += TextArea.value.charAt(i);

                //si hay un retorno de carro, antes de llegar al final del textArea
                if (TextArea.value.charAt(i) == '\n') {
                    Cadenafinal += cadenaTexto.substr(0, cadenaTexto.lastIndexOf('\n') + 1) ;
                    cadenaTexto = "";
                }

                //si el ancho actual de la cadena  es mayor o igual que el ancho del textarea (medida pixeles)
                if (cadenaTexto.visualLength() > TextArea.scrollWidth - 4) {
                    //recuperamos el ultimo espacio en blanco antes de la ultima letra o palabra
                    var indiceEspacio = IndEspacio(cadenaTexto)

                    buffer = "";
                    //ultimo espacio en blanco detectado, metemos el trozo de palabra desde el ultimo espacio
                    if (indiceEspacio >= 0) {
                        for (var j = indiceEspacio + 1; j <= i; j++)
                            buffer += cadenaTexto.charAt(j);
                        indiceEspacio = -1;
                    } else {
                        buffer += TextArea.value.charAt(i);
                    }
                    //coloca la cadena 
                    Cadenafinal += cadenaTexto.substr(0, cadenaTexto.length - buffer.length) + "\n";
                    cadenaTexto = buffer;
                }
            }

            Cadenafinal += cadenaTexto;

            document.getElementById("pnlPreview").innerHTML = Cadenafinal.replace(new RegExp("\\n", "g"), "<br />");
        }


    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <span id="CadTemp">hola</span>
    </div>
    <br />
    <div>
        <textarea cols="20" rows="5" id="myTextarea" wrap="hard" 
            style="font-family: Arial, Helvetica, sans-serif; font-size: 12pt"></textarea>
    </div>
    <div id="pnlPreview"></div>
    <div>
        <button type="button" onclick="AplicarSaltosLinea('myTextarea');">Apply Line Breaks</button>
        <button type="button" onclick="alert( document.getElementById('myTextarea').value )">mensaje</button>
        <button type="button" onclick="alert( mostrar())">calcular Ancho Pixel</button>
        <br />
        </div>
    </form>
</body>
</html>

Code tested at "Crome", "Firefox" and "IE". Get line feeds and carriage returns a component "textArea" (client side with javascript).

WORKS WELL!.
I would like to share it with you

important to include the style

    <html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<%--//definimos un estilo--%>
 <STYLE type="text/css">
    #CadTemp 
    {
        font-family: "Arial", serif; 
        font-size: 12pt; 
        visibility: hidden;
        position: absolute;
        top: -100;
        left: 0px;
    }
 </STYLE>

    <script type="text/javascript">
        function mostrar() {
            return 'ancho cadena: ' + document.getElementById('myTextarea').value.visualLength() + '  \n' + 'ancho textarea: ' + (document.getElementById('myTextarea').scrollWidth -4);
        }


        //sustituimos el espacio en blanco por el punto, tienen exactamente el mismo tamaño en 'pixeles'
        function reemplazarEspacios(texto) {
            var devolver = "";
            for (var i = 0; i < texto.length; i++) {
                if (texto.charAt(i) == ' ') {
                    devolver += '.'
                } else {
                    devolver += texto.charAt(i);
                }
            }
            return devolver;
        }

        // Calcula los pixeles de ancho que ocupa un texto (la cadena debe tener el mismo tamaño y tipo de fuente)
        String.prototype.visualLength = function () {
            var ruler = document.getElementById("CadTemp");            
            ruler.innerHTML = reemplazarEspacios(this)
            return ruler.offsetWidth;
        }

        //quitar espacios a la derecha de la cadena
        String.prototype.rtrim = function() {return this.replace(/\s+$/,"");}

        //devuelve el ultimo espacio de la cadena (que no sea espacio final)
        function IndEspacio(cadena) {
            //quito los espacios al final
            var cadenaTemp = cadena.rtrim();
            return cadenaTemp.lastIndexOf(' ');
        }

        //insertar un salto de linea
        function AplicarSaltosLinea(ID_elemento) {
           //guardo el elemento web en una variable
           var TextArea = document.getElementById(ID_elemento);
           var cadenaTexto = "";
           var Cadenafinal = "";
           var buffer = "";

           //recorremos toda la cadena
           for (var i = 0; i < TextArea.value.length; i++) {
                //guardamos el caracater en la cadena
                cadenaTexto += TextArea.value.charAt(i);

                //si hay un retorno de carro, antes de llegar al final del textArea
                if (TextArea.value.charAt(i) == '\n') {
                    Cadenafinal += cadenaTexto.substr(0, cadenaTexto.lastIndexOf('\n') + 1) ;
                    cadenaTexto = "";
                }

                //si el ancho actual de la cadena  es mayor o igual que el ancho del textarea (medida pixeles)
                if (cadenaTexto.visualLength() > TextArea.scrollWidth - 4) {
                    //recuperamos el ultimo espacio en blanco antes de la ultima letra o palabra
                    var indiceEspacio = IndEspacio(cadenaTexto)

                    buffer = "";
                    //ultimo espacio en blanco detectado, metemos el trozo de palabra desde el ultimo espacio
                    if (indiceEspacio >= 0) {
                        for (var j = indiceEspacio + 1; j <= i; j++)
                            buffer += cadenaTexto.charAt(j);
                        indiceEspacio = -1;
                    } else {
                        buffer += TextArea.value.charAt(i);
                    }
                    //coloca la cadena 
                    Cadenafinal += cadenaTexto.substr(0, cadenaTexto.length - buffer.length) + "\n";
                    cadenaTexto = buffer;
                }
            }

            Cadenafinal += cadenaTexto;

            document.getElementById("pnlPreview").innerHTML = Cadenafinal.replace(new RegExp("\\n", "g"), "<br />");
        }


    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <span id="CadTemp">hola</span>
    </div>
    <br />
    <div>
        <textarea cols="20" rows="5" id="myTextarea" wrap="hard" 
            style="font-family: Arial, Helvetica, sans-serif; font-size: 12pt"></textarea>
    </div>
    <div id="pnlPreview"></div>
    <div>
        <button type="button" onclick="AplicarSaltosLinea('myTextarea');">Apply Line Breaks</button>
        <button type="button" onclick="alert( document.getElementById('myTextarea').value )">mensaje</button>
        <button type="button" onclick="alert( mostrar())">calcular Ancho Pixel</button>
        <br />
        </div>
    </form>
</body>
</html>
梦行七里 2024-10-19 15:38:30

我无意挖掘旧帖子,但这是我搜索了一段时间后发现的。 @Shadow Wizard 的解决方案对我不起作用,因为它在每个句子后面都留了一个空格,所以我决定进行一些调整。我不是针对每个字符进行操作,而是针对每个单词进行操作。这使得检查更加容易,并且速度也快了 10 倍,使用完整的 Lorem Ipsum 检查(约 600 毫秒 vs 小提琴 6 秒,没有小提琴 120 毫秒)。

我创建了一个(已记录的)小提琴。我将看看是否可以优化它不过,多一点。

function applyLineBreaks = function(strTextAreaId) {

    // Get txtarea
    var oTextarea = document.getElementById(strTextAreaId);

    // Disable textarea wrap
    oTextarea.setAttribute("wrap", "off");

    // Split the characters into an array
    var aWords = oTextarea.value.split(' ');

    // Empty the textarea
    oTextarea.value = "";

    // Get textarea scrollwidth
    var nEmptyWidth = oTextarea.scrollWidth;

    // Start looping over the words
    for(var i = 0; i < aWords.length; i++)
    {
        if(i > 1000)
        {
            break;
        }
        var curWord = aWords[i] + ' ';

        // Add character to textarea
        oTextarea.value += curWord;

        // console.log(oTextarea.scrollWidth, nEmptyWidth);
        if(oTextarea.scrollWidth > nEmptyWidth)
        {
            let oldVal      = oTextarea.value;
            let newVal      = oldVal.substring(0, (oldVal.length - (curWord.length + 1))) + "\n" + curWord;
            oTextarea.value = newVal;
        }
    }
    oTextarea.setAttribute("wrap", "");

    return oTextarea.value;
};

I don't mean to dig up old posts, but this is the one where I came out after searching for some time. @Shadow Wizard 's solution didn't work for me because it put a space behind every sentence, so I decided to make some adjustments. Instead of doing it per-character, I do it per-word. This results in way easier checks and is also 10 times faster, checking with full Lorem Ipsum (~600ms vs 6 full seconds on fiddle, 120ms without fiddle).

I have created a (documented) fiddle. I'm going to see if I can optimise it a bit more, though.

function applyLineBreaks = function(strTextAreaId) {

    // Get txtarea
    var oTextarea = document.getElementById(strTextAreaId);

    // Disable textarea wrap
    oTextarea.setAttribute("wrap", "off");

    // Split the characters into an array
    var aWords = oTextarea.value.split(' ');

    // Empty the textarea
    oTextarea.value = "";

    // Get textarea scrollwidth
    var nEmptyWidth = oTextarea.scrollWidth;

    // Start looping over the words
    for(var i = 0; i < aWords.length; i++)
    {
        if(i > 1000)
        {
            break;
        }
        var curWord = aWords[i] + ' ';

        // Add character to textarea
        oTextarea.value += curWord;

        // console.log(oTextarea.scrollWidth, nEmptyWidth);
        if(oTextarea.scrollWidth > nEmptyWidth)
        {
            let oldVal      = oTextarea.value;
            let newVal      = oldVal.substring(0, (oldVal.length - (curWord.length + 1))) + "\n" + curWord;
            oTextarea.value = newVal;
        }
    }
    oTextarea.setAttribute("wrap", "");

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