テキストエリア内でカーソルが何行目の何列目にあるのかを取得したり設定するためのサンプルを作成しました。
試した限りでは意図した通りの動作になることを確認しましたが、正直なところ仕様を理解できているとは言えないので、もしかすると意図しない動作になってしまうケースがあるかもしれません。
以下ソース
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>行番号</title> | |
<style type="text/css"> | |
.max{width:100%;height:100%} | |
.bc{border-collapse:collapse} | |
.of-hidden{overflow:hidden} | |
</style> | |
</head> | |
<body class="of-hidden"> | |
<table class="bc max"> | |
<tr><td><textarea id=ta class=max wrap=off></textarea></td></tr> | |
<tr height=1><td>行:<input id=inp行> 列:<input id=inp列></td></tr> | |
</table> | |
</body> | |
<script> | |
resizeTo(400,400) | |
ta.onkeyup=ta.onkeydown=function(){ | |
var obj=getテキストカーソル位置(this), str=this.value.slice(0,obj.start), arr=str.split('\n') | |
inp行.value = arr.length | |
inp列.value = arr[arr.length-1].length + 1 | |
} | |
getテキストカーソル位置=function(elem){ | |
// 左記URLのページを参照させていただきました。 http://d.hatena.ne.jp/nakazawaken1/20100125/p1 | |
var rngSel=document.selection.createRange(), rngElem=document.body.createTextRange() | |
rngElem.moveToElementText(elem) | |
// rngSelより前の範囲を選択する(rngElemのEndをrngSelのStart位置に合わせる) | |
rngElem.setEndPoint('EndToStart', rngSel) | |
var f=function(rng){ | |
var str=rng.text, str0=str | |
// 選択文字数が0でない間(前の範囲) | |
while(rng.compareEndPoints('StartToEnd', rng) != 0){ | |
// 一文字ずつ範囲終了位置を前にずらしていく | |
rng.moveEnd('character', -1) | |
// ずらす前と後の文字列が異なる状態ならbreak | |
if(str0 != rng.text){break} | |
// ずらす前と後の値が同じ状態の間は改行を付け足していく。 | |
str += '\r\n' | |
} | |
return str | |
} | |
var str前=f(rngElem), str選択=f(rngSel), start=str前.length, end=start + str選択.length | |
return {start:start, end:end} | |
// 以下の方法では選択範囲の末尾に改行文字がある場合、意図した通りの動作にならない。 | |
/* | |
rngSel.moveStart('character', -this.value.length) | |
rngSel.moveEnd ('character', 1) | |
var reg=/\n/g, res=rSel.text.match(reg), 行, 列 | |
if(res){ | |
行 = res.length | |
列 = RegExp.rightContext.length - 1 | |
}else{ | |
行 = 0 | |
列 = rSel.text.length - 1 | |
} | |
inp行.value = 行 | |
inp列.value = 列 | |
*/ | |
} | |
inp行.onchange = inp列.onchange = function(){ | |
var 行=inp行.value, 列=inp列.value, arr=ta.value.split('\r\n'), rng=document.body.createTextRange() | |
行 = isFinite(行) ? 行 : 1 | |
列 = isFinite(列) ? 列 : 1 | |
ta.select() | |
rng.moveToElementText(ta) | |
rng.moveStart('character', arr.slice(0,行).join('\r\n').length - (行-1)) | |
rng.moveStart('character', 列 - arr[行-1].length - 1) | |
while(rng.compareEndPoints('StartToEnd', rng) != 0){ rng.moveEnd('character',-1) } | |
rng.select() | |
} | |
</script> | |
</html> |
0 件のコメント:
コメントを投稿