前两天研究了一下textarea的直观行的换行规律,挺复杂啊:
直观行怎样取不光要看cols大小,还要看网页编码方式。
cols="30"的textarea,实际上每行可以容纳29个半角字符,多少个全角字符就不一定了,与网页编码方式有关。
在IE6.0实测的情况,直观行的换行发生在红字处(红字折到下一行)。
dddddddddddd米ddddddddddddddddddddd //全角后面的连续半角内容被当成一个完整单词处理,如果剩下的位置容不下单词的长度了,就要换行,此为特殊规律A
网页按Unicode编码(“运行代码”的弹出页面即按此编码,JS生成的页面均按此编码)时的一般规律是
(“占满”是说后面无论再跟全角、半角字符,都得换行)
123456789012345678901234567890 //29半角占满
一二三四五六七八九十一二三四五六七八九十 //17全角占满
一二三四五六七八九十一二三四五六七0八九十
一二三四五六七八九十一二三四五六0七八九十 
0一二三四五六七八九十一二三四五六1七八九十 //16全角,1半角占满
0一二三四五六七八九十一二三四五六七八九十
0一二三四五六七八九十一二三四五1六七八九十 //15全角,2半角后不可容全角
01一二三四五六七八九十一二三四五六七八九十
01一二三四五六七八九十一二三四五2六七八九十 //15全角,2半角后可再容1半角(多于1半角时按特殊规律A)
012一二三四五六七八九十一二三四五六七八九十 //15全角,3半角占满
012一二三四五六七八九十一二三四五3六七八九十
0123一二三四五六七八九十一二三四五六七八九十 //14全角,4半角后不可容全角
0123一二三四五六七八九十一二三四4五六七八九十 //14全角,4半角后可再容1半角(多于1半角时按特殊规律A)
01234一二三四五六七八九十一二三四五六七八九十 //14全角,5半角占满
01234一二三四五六七八九十一二三四5五六七八九十
012345一二三四五六七八九十一二三四五六七八九十 //13全角,6半角后不可容全角
012345一二三四五六七八九十一二三6四五六七八九十 //13全角,6半角后可容1半角(多于1半角时按特殊规律A)
0123456一二三四五六七八九十一二三四五六七八九十 //13全角,7半角占满
0123456一二三四五六七八九十一二三7四五六七八九十
01234567一二三四五六七八九十一二三四五六七八九十 //12全角,8半角占满
01234567一二三四五六七八九十一二8三四五六七八九十
012345678一二三四五六七八九十一二三四五六七八九十 //11全角,9半角后不可容全角
012345678一二三四五六七八九十一9二三四五六七八九十 //11全角,9半角后可再容1半角(多于1半角时按特殊规律A)
0123456789一二三四五六七八九十一二三四五六七八九十 //11全角,10半角占满
……
0一二三四五六七八九十一二三四五12六七八九十 //15全角,1半角后可再容2半角连续字符(多于2半角时按特殊规律A),此条可由15全角,3半角占满得出
……
0一二三四五六七八九十一二三四1234五六七八九十 //14全角,1半角后可再容4半角连续字符(多于4半角时按特殊规律A),此条可由14全角,5半角占满得出
……
01一二三四五六七八九十一二三四234五六七八九十 //14全角,2半角后可再容3半角连续字符(多于3半角时按特殊规律A),此条可由14全角,5半角占满得出
……
换行位置不仅与换行位置之前的整行文字有关,还与红字有关(往往全角文字是因为无法在上行末尾挤下才被折到下一行的)。
总结一下就有:

CODE:[Copy to clipboard]x全角,y半角占满 = x全角,y-1半角后不可容全角 = x全角,y-n半角后可再容n半角连续字符(多于n半角时按特殊规律A)。
所以做实验搞清楚所有“占满”的情形就可以了。
现将cols=30,网页按Unicode编码时的“占满”情况列出:
17全角
16全角,1半角
15全角,3半角
14全角,5半角
13全角,7半角
12全角,8半角
11全角,10半角
10全角,12半角
9全角,13半角
8全角,15半角
7全角,17半角
6全角,19半角
5全角,21半角
4全角,22半角
3全角,24半角
2全角,26半角
1全角,28半角
29半角
利用濒于发生按特殊规律A换行的情形,很容易测出所有“占满”的情形:
例如,一二三四五六七八九十012345678912一二三四五六七八九十 //10全角,12半角占满
一二三四五六七八九十0123456789123一二三四五六七八九十 //红字处按特殊规律A换行,蓝字处按9全角,13半角占满换行
cols=30,网页按GB2312编码时,“占满”规律不同了:
14全角,1半角
13全角,3半角
12全角,5半角
11全角,7半角
10全角,9半角
9全角,11半角
8全角,13半角
7全角,15半角
6全角,17半角
5全角,19半角
4全角,21半角
3全角,23半角
2全角,25半角
1全角,27半角
29半角
这样的话,要根据网页的编码方式和cols,通过实验具体才能测出“占满”规律。
从textarea内容的开头起计算全角和半角字符的数目,根据“占满”规律及特殊规律A决定第一个直观换行的位置,再从第二行(包括物理行和直观行)起计算全角和半角字符的数目,根据“占满”规律及特殊规律A决定第二个直观换行的位置……如是继续下去,直到textarea内容的末尾。这样就可以得到所有的换行位置了。
当然实际应用时没必要也没可能这样做实验啦,比如说选中textarea的第X行到第Y行,还没了解官方的办法是怎样的,我是这么办的:
<textarea rows=5 cols=30 id=abc>
祖父听说我要带女朋友去钓鱼,也想去会会她。我带了女朋友先去,等候祖父的时候,我已经钓到了一条18公斤重的鲈鱼。
祖父到了,我把女友介绍给他认识,又举起那条鱼给他看。
真不错!他说,怎样钓上的?
用蚯蚓。我回答。
那就奇了,他故意一本正经地说,
我那一代至少要用一顿饭和一场电影!</textarea>
<script language=JScript>

/*
Create by Bound0 on Blueidea
mailto:bound0eureka@gmail.com
*/

function sele(s,e){
var src = document.getElementById("abc")
var oTR = src.createTextRange()
var text=src.innerText
var textLength = text.length
conts=[0]

/* 我一开始不知道getClientRects()方法,就用这段代码取textarea内容开始处在网页中的大致坐标,可见条条大路通罗马
Obj=src
for (var sumTop=0,sumLeft=0;Obj!=window.document.body;sumTop+=Obj.offsetTop,sumLeft+=Obj.offsetLeft, Obj=Obj.offsetParent);
startx=sumLeft+6 //textarea内容开始处在网页中的大致坐标
starty=sumTop+9
*/

startx=src.createTextRange().getClientRects()[0].left
starty=src.createTextRange().getClientRects()[0].top

stepy=3 //光标向下移动的步长,不能大于textarea中的字高
currentScr=0 //当前滚动条位置
stepScr=30 //滚动条向下滚动的步长,不能大于textarea的高度

while(1){src.scrollTop=currentScr
currenty=starty
while(1) //光标从textarea内容的开头开始向下移动,遍历各行,在conts[]中记下各换行位置
{oTR.moveToPoint(startx, currenty)
oTR.moveEnd("character", textLength)
cont = textLength - oTR.text.length
if(cont>=textLength)break
if(cont>conts[conts.length-1])conts[conts.length]=cont
currenty+=stepy
}
if(currentScr>=src.scrollHeight)break
currentScr+=stepScr
}

if(e=="")e=s
s=parseInt(s)
e=parseInt(e)
if(isFinite(s)&&isFinite(e)&&s>0&&e>0){if(s>conts.length||e>conts.length){alert("总共只有"+conts.length+"行。") //检查参数有效性
return}
if(e<s){e=s;end.value=e} //如果结束行在开始行之前,强行调整参数
src.scrollTop=0
oTR.moveToPoint(startx,starty) //光标回到textarea内容的开头
st=conts[s-1]
texpreStart=text.substr(0,st).replace(/\r/g,"") //自textarea内容的开头至选择起点前的字串,由于moveStart方法将\r\n视为一个字符,需要修正计数
st=texpreStart.length
oTR.moveStart("character",st)
en=textLength
if(e<conts.length)en=conts[e]
texpreEnd=text.substr(0,en).replace(/\r/g,"") //自textarea内容的开头至选择结束点前的字串,由于moveEnd方法将\r\n视为一个字符,需要修正计数
en=texpreEnd.length
oTR.moveEnd("character", en-st)
oTR.select()
}
}
</script>
选中第<input name=start value=3>行至第<input name=end value=5>行
<button οnclick=sele(start.value,end.value)>select</button>

04 年初写的东西,应该是目前研究比较全面的了吧??
<style>
* {
    font-size: 12px;
}
</style>

<script language="javascript">
// Coded by windy_sk <windy_sk@126.com> 20040210

function reportError(msg,url,line) {
    var str = "You have found an error as below: \n\n";
    str += "Err: " + msg + " on line: " + line;
    alert(str);
    return true;
}

window.onerror = reportError;

function show_all(obj, txt_obj) {
    var x, y;
    txt_obj.value = "";
    for(x in obj) {
        if(typeof(obj[x])=="object") {
            txt_obj.value += x + " : \n";
            for(y in obj[x])
                txt_obj.value += "    " + y + " -    " + obj[x][y] + "\n";
        } else {
            txt_obj.value += x + " -    " + obj[x] + "\n";
        }
    }
    return;
}

var cur_pos = 0;
var p_row = 0;
var p_col = 0;
var v_row = 0;
var v_col = 0;
var s_len = 0;
var r_count = 0;

function get_txt_pos() {
    try{
        var obj = document.getElementById("test");
        var rng = obj.createTextRange();
        var rng_sel = obj.document.selection.createRange();
        var if_end = false;
        var arr_sel = new Array();
        
        show_all(rng, ctr);
        show_all(rng_sel, cr)
        show_all(rng.getClientRects(), ctr_crt);
        show_all(rng_sel.getClientRects(), cr_crt)
        show_all(rng.getBoundingClientRect(), ctr_bcrt);
        show_all(rng_sel.getBoundingClientRect(), cr_bcrt)
        
        s_len = rng_sel.text.replace(/\r/, "").length;
        rng.moveToPoint(rng_sel.offsetLeft, rng_sel.offsetTop);
        rng.moveStart('character', -obj.value.length);
        try {
            r_count = rng.text.match(/\r/g).length;
        } catch(e) {
            r_count = 0;
        }
        cur_pos = rng.text.length;
        
        if_end = (rng.getBoundingClientRect().left == rng_sel.getBoundingClientRect().left);
        arr_sel = rng.text.split("\r\n");
        p_row = arr_sel.length;
        p_col = if_end?0:arr_sel[arr_sel.length-1].length;
        
        var rct = rng.getClientRects();
        v_row = rct.length;
        rng.moveToPoint(rct[v_row-1].left, rct[v_row-1].top);
        rng.moveStart('character', -cur_pos);
        v_col = if_end?0:(cur_pos - rng.text.length);
        if(v_col - p_col == 2) v_col = p_col;
        
        err.value = "";
    }catch(e){
        show_all(e, err)
        cur_pos = 0;
        p_row = 0;
        p_col = 0;
        v_row = 0;
        v_col = 0;
        s_len = 0;
        r_count = 0;
    }
    show_txt_pos();
    return;
}

function restore_txt() {
    var obj = document.getElementById("test");
    obj.focus();
    var rng = obj.createTextRange(); 
    rng.moveStart('character', cur_pos - r_count);
    rng.collapse(true);
    rng.moveEnd('character', s_len);
    rng.select();
    show_txt_pos();
    return;
}

function show_txt_pos() {
    cur_pos_show.innerText = cur_pos - r_count;
    p_row_show.innerText = p_row;
    p_col_show.innerText = p_col;
    v_row_show.innerText = v_row;
    v_col_show.innerText = v_col;
    return;    
}
</script>

<table><tr><td>

<textarea id="test" style="width:400px; height:200px" οnclick="get_txt_pos()" οnkeyup="get_txt_pos()">
1 - 1234567890
2 - 12345678901234567890
3 - 123456789012345678901234567890
4 - 1234567890123456789012345678901234567890
5 - 12345678901234567890123456789012345678901234567890
6 - 123456789012345678901234567890123456789012345678901234567890
7 - 1234567890123456789012345678901234567890123456789012345678901234567890
8 - 12345678901234567890123456789012345678901234567890123456789012345678901234567890
9 - 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
0 - 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
</textarea>

</td><td width="50"> </td><td valign="top">

<b>Current Position : </b><span id="cur_pos_show"></span>
 
<b>Physical Row: </b><span id="p_row_show"></span>
 
<b>Physical Column: </b><span id="p_col_show"></span>
 
<b>Visible Row: </b><span id="v_row_show"></span>
 
<b>Visible Column: </b><span id="v_col_show"></span>
 
<b>Error Message: </b>
 
<textarea id="err" style="width:350px; height:120px"></textarea>
</td></tr></table>

<input type="button" name="textfield" οnclick="restore_txt()" value="Restore Selection">

<table>
<tr>
<td><b>CreateRange</b>
 
<textarea id="cr" style="width:400px; height:200px"></textarea>
</td><td><b>CreateTextRange</b>
 
<textarea id="ctr" style="width:400px; height:200px"></textarea>
</td>
</tr>
<tr>
<td><b>CreateRange.getClientRects()</b>
 
<textarea id="cr_crt" style="width:400px; height:200px"></textarea>
</td><td><b>CreateTextRange.getClientRects()</b>
 
<textarea id="ctr_crt" style="width:400px; height:200px"></textarea>
</td>
</tr>
<tr>
<td><b>CreateRange.getBoundingClientRect()</b>
 
<textarea id="cr_bcrt" style="width:400px; height:200px"></textarea>
</td><td><b>CreateTextRange.getBoundingClientRect()</b>
 
<textarea id="ctr_bcrt" style="width:400px; height:200px"></textarea>
</td>
</tr>
</table>
根据被某网站匿名转载的页面( http://dl.pconline.com.cn/html_2/4/545/id=38457&pn=0.html )上的网友留言,上面的《JS实现文本域的任意行选定》示例代码有一处bug:即在滚动条不在顶端的情况下运行示例代码会出错。现已修正:只增加了一行代码

CODE:
src.scrollTop=0 //确保开始数行数时滚动条位于顶部
<textarea rows=5 cols=30 id=abc>
Bound0 子确工作室 生物信息学相关业务简介

[多步生物信息查询的一步化]

将繁琐的多步生物信息查询合并为一步,减少在各个网页间的手工跳转。

只要能够理清多步生物信息查询的流程就可能做到一步化。

[批量数据转录、整合]

将大量零散的文档收录到数据库中或整理、转化为符合要求的格式。

例如:将数百个结构复杂的word文档内容收录到数据库中。

[定制Bound0 Eureka预选器数据库]

利用Bound0 Eureka预选器数据库可以初步判断样品的成分,缩小进一步实验的处理范围,对接下来的实验环节做出调整,或预选出最佳的实验方案,从而缩短研究、开发的周期,节省人力物力。还可以初步验证某些假设推断,并有助于提出新的假设推断,构建新的假说。同时让交流和教学过程变得更简单、方便。

有关Bound0 Eureka预选器数据库核心技术的专利申请已被受理,专利申请号:200610077985.3。

定制Bound0 Eureka预选器数据库(Bound0 Eureka Preselector)的业务实质:
1、定制公共数据库内容的本地化整合。
2、定制数据库查询方式和查询项目。
3、定制分析、统计功能。
4、定制数据共享功能。
5、定制教学展示功能。
6、定制其他辅助功能。

例如:Bound0酵母蛋白Eureka预选器数据库的数据内容整合了SGD数据库(Saccharomyces Genome Database,酵母基因组库http://www.yeastgenome.org/)中的部分数据。共包含6713个蛋白的信息。

Bound0酵母蛋白Eureka预选器数据库具有以下基本功能:
(1)Eureka Preselector(主功能): 根据条件给出符合条件的蛋白质列表。根据蛋白质的特征与目标特征的接近程度对列表内的蛋白质进行排名。以网页形式输出、保存 Eureka 结果。对保存的结果进行对比分析。
(2)以树状结构显示(treeview)蛋白质的各种生物学信息。
(3)以搜索引擎形式,对描述蛋白质充当的细胞组分、参与的生物过程、分子功能等描述性特征的标准化术语(GO Term)提供注释和指导。
(4)以搜索引擎形式,对蛋白质的各种ID、名称进行通译。
(5)在安装了Bound0酵母蛋白Eureka预选器数据库的计算机上,实现自定义的eureka:// 协议。可以在用户自己的网页中以超级链接(文字链接、图片热点链接等)的方式动态地调用数据库中的内容进行演示。
(6)自动生成上述演示所需要的链接代码。
(7)独立发行(便于数据共享)的数据分析配件,可对以网页形式保存的 Eureka 结果进行处理。更多详情请置询bound0@tom.com</textarea>
<script language=JScript>
/*
Create by Bound0 on Blueidea
mailto:bound0@tom.com
*/
function sele(s,e){
var src = document.getElementById("abc")
var oTR = src.createTextRange()
var text=src.innerText
var textLength = text.length
conts=[0]
/* 我一开始不知道getClientRects()方法,就用这段代码取textarea内容开始处在网页中的大致坐标,可见条条大路通罗马
Obj=src
for (var sumTop=0,sumLeft=0;Obj!=window.document.body;sumTop+=Obj.offsetTop,sumLeft+=Obj.offsetLeft, Obj=Obj.offsetParent);
startx=sumLeft+6 //textarea内容开始处在网页中的大致坐标
starty=sumTop+9
*/
src.scrollTop=0 //确保开始数行数时滚动条位于顶部
startx=src.createTextRange().getClientRects()[0].left
starty=src.createTextRange().getClientRects()[0].top
stepy=3 //光标向下移动的步长,不能大于textarea中的字高
currentScr=0 //当前滚动条位置
stepScr=30 //滚动条向下滚动的步长,不能大于textarea的高度
while(1){src.scrollTop=currentScr
currenty=starty
while(1) //光标从textarea内容的开头开始向下移动,遍历各行,在conts[]中记下各换行位置
{oTR.moveToPoint(startx, currenty)
oTR.moveEnd("character", textLength)
cont = textLength - oTR.text.length
if(cont>=textLength)break
if(cont>conts[conts.length-1])conts[conts.length]=cont
currenty+=stepy
}
if(currentScr>=src.scrollHeight)break
currentScr+=stepScr
}
if(e=="")e=s
s=parseInt(s)
e=parseInt(e)
if(isFinite(s)&&isFinite(e)&&s>0&&e>0){if(s>conts.length||e>conts.length){alert("总共只有"+conts.length+"行。") //检查参数有效性
return}
if(e<s){e=s;end.value=e} //如果结束行在开始行之前,强行调整参数
src.scrollTop=0
oTR.moveToPoint(startx,starty) //光标回到textarea内容的开头
st=conts[s-1]
texpreStart=text.substr(0,st).replace(/\r/g,"") //自textarea内容的开头至选择起点前的字串,由于moveStart方法将\r\n视为一个字符,需要修正计数
st=texpreStart.length
oTR.moveStart("character",st)
en=textLength
if(e<conts.length)en=conts[e]
texpreEnd=text.substr(0,en).replace(/\r/g,"") //自textarea内容的开头至选择结束点前的字串,由于moveEnd方法将\r\n视为一个字符,需要修正计数
en=texpreEnd.length
oTR.moveEnd("character", en-st)
oTR.select()
}
}
</script>
选中第<input name=start value=3>行至第<input name=end value=5>行
<button οnclick=sele(start.value,end.value)>select</button>

textarea研究相关推荐

  1. HTML textarea cols,rows属性和宽度高度关系研究

    一.关于textarea元素的cols和rows属性 <textarea>元素,俗称"文本域",或者"多行文本框",其自带原生的HTML属性rows ...

  2. textarea 中获取用户的空格和回车

    今天在工作中要通过textarea 获取用户的空格和回车 ,保存好用户的格式,在前台显示,总是遇到空格和换行的问题,就仔细研究了下,因为在ie和火狐中老是不兼容,在网上找了下也没找到好的解决办法,于是 ...

  3. textarea限制输入长度

    最近公司的项目客户在使用时报错,研究后发现,textarea输入框,输入值的长度超过了数据库中定义的长度,所以造成了,前台的错误,因此要对前台输入框的输入的长度进行限制:经过研究后发现,一下几种方法可 ...

  4. html实体编码_深入研究浏览器解析和XSS有效负载编码

      翻译文章, 原文:Deep dive into browser parsing and XSS payload encoding[1] 这篇博客文章将深入探讨HTML,URL和JavaScript ...

  5. 实现Flex的TextArea文本中关键字的高亮显示

    最近做的Flex项目中有一个需求,要求在一个TextArea中输入文本时,当文本中出现SQL关键字(如select,from,where等)时,让这些关键字高亮显示. 经过一个下午的研究最终算是基本上 ...

  6. Webkit中textarea的设定

    使用chrome浏览器或者safari浏览器,经常会发现自己的textarea很奇怪,可以拖动放大缩小,而且还有个奇怪的边.最初我们遇到这类问题的时候,直接给设计交代说那是浏览器的特性,俺们管不着,结 ...

  7. 工作记录(JS向textarea添加固定内容、通过固定字符将字符串分割为数组)

    第一个是在 textarea 输入框中添加固定的内容. 代码如下: <textarea id="text" cols="30" rows="10 ...

  8. flyingsaucer转换多个html,使用flying-saucer 实现 html转pdf实现input框select,textarea

    使用flying-saucer 实现 html转pdf实现input框select,textarea 使用flying-saucer 实现 html转pdf实现input框select,textare ...

  9. vue实现带样式的textarea输入框,contenteditable属性应用

    提示:vue中使用contenteditable 文章目录 前言 一.contenteditable 什么是contenteditable: 二.contenteditable的使用 总结 前言 开发 ...

最新文章

  1. 在Exchange Server 2007中 设置用户邮箱的大小
  2. Git之多个用户ID适配
  3. [vue-element] ElementUI是怎么做表单验证的?在循环里对每个input验证怎么做呢?
  4. BZOJ 4810 [Ynoi2017]由乃的玉米田(莫队+bitset)
  5. 动态规划——K号数(蓝桥杯试题集)
  6. 3风扇声音怎么调小_美的风扇价格表
  7. RFID技术为智能轮胎在未来车联网领域的应用奠定了基础
  8. STM32F4: Generating parallel signals with the FSMC
  9. JS字符串转为数值方法详解
  10. 使用jemalloc优化java_C++性能优化(十) —— JeMalloc
  11. Mac 输入法自动切换,代码编辑器中文状态下使用英文标点
  12. 【python教程入门学习】Python字典及基本操作(超级详细)
  13. 彻底禁用win10自动更新功能及其powershell代码
  14. 使用adb命令修改build.prop文件
  15. MarkDown 高级操作
  16. 【流畅的Python学习笔记】2023.4.21
  17. 赴微软测试工程师必考一道笔试题目
  18. 知识点摘抄:数字后面+UL是什么?
  19. 如何释放磁盘空间在您的Mac
  20. 1.Hadoop的安装和使用(华为云学习笔记,Spark编程基础,大数据)

热门文章

  1. android屏幕录制功能,Android利用ADB进行屏幕录制
  2. 内容推荐场景中自监督学习的应用
  3. PHPMailer远程命令执行漏洞复现
  4. PDF文件怎么转换成PPT
  5. 这样做团建,还担心员工离职吗?
  6. 自动复制吱口令html,支付宝吱口令自动复制 JavaScript 脚本代码 码上中国博客
  7. 智能体脂秤方案——什么是体脂?
  8. html dashed显示实线怎么改,实现css虚线样式的两种方式:dotted和dashed(实例)
  9. 计算机科学与技术本科相当于计算机几级,软件工程的学生毕业后计算机等级算几级?...
  10. java 错误1335_安装JAVA的JDK时出现,错误1335? – 手机爱问