[英]JavaScript 'contenteditable' — Getting/Setting Caret Position
我已經閱讀了幾篇關於插入符號的帖子,但似乎都沒有回答我的特定問題。
問題 :我希望插入符號作為div1出現在div2上的確切位置
所以,我需要一些方法來讀取用戶點擊div1的位置,然后當div2出現時將光標/插入符號放在同一位置,這樣就是一組getCaretLocation(in_div_id)和setCaretLocation(in_div_id)函數。
有辦法嗎?
謝謝 -
簡答 :你做不到
答案很長 :你將面臨的問題是你將能夠獲得div1上click事件的(x,y)坐標,但是任何實現的插入位置都要求你知道插入符號在內容中的位置(這是插入符號前面的字符數)。
要將(x,y)坐標轉換為字符位置,您實際上需要知道之前有多少個字符(即,如果文本是ltr,則保留在當前行和上面的字符處)。
如果使用固定寬度字體,則可以簡化問題:將(x,y)坐標映射到字符網格上的(線,列)坐標。
但是,您仍然面臨不知道文本如何被包裝的問題。 例如 :
------------------
|Lorem ipsum |
|dolor sit amet |
|consectetur |
|adipiscing elit |
------------------
如果用戶點擊了dol中的d ,你知道該字符是第二行的第一個,但是在不知道包裝算法的情況下,你無法知道它是“Lorem ipsum dolor sit中的第13個字符...... ”。 並且無法保證這種包裝算法在瀏覽器和平台之間是相同的。
現在,我想知道為什么你會首先使用2個不同的同步div
? 當用戶點擊(或懸停)時,僅使用一個div並將其內容設置為可編輯是不是更容易?
你可以,基本上你需要在你的第一個div上設置可編輯的臨時內容以捕獲插入符號位置
$('div1').hover(function()
{ $(this).attr('contenteditable','true');
},function()
{ $(this).removeAttr('contenteditable');
}).mouseup(function()
{ var t = $(this);
// get caret position and remove content editable
var caret = t.getCaret();
t.removeAttr('contenteditable');
// do your div switch stuff
...
// and apply saved caret position
$('div2').setCaret(caret);
});
現在只需要獲取/設置插入符號方法:)
編輯>這是我自己的,( 現場演示 )
getSelection:function($e)
{ if(undefined === window.getSelection) return false;
var range = window.getSelection().getRangeAt(0);
function getTreeOffset($root,$node)
{ if($node.parents($root).length === 0) return false; // is node child of root ?
var tree = [], treesize = 0;
while(1)
{ if($node.is($root)) break;
var index, $parent = $node.parent();
index = $parent.contents().index($node);
if(index !== -1) { tree[treesize++] = index; } $node = $parent;
}; return tree.reverse();
}
var start = getTreeOffset($e,$(range.startContainer));
var end = getTreeOffset($e,$(range.endContainer));
if(start & end === false) return false;
return {start:start,end:end,startOffset:range.startOffset,endOffset:range.endOffset};
}, setSelection:function($e,s,win)
{ $e.focus(); if(s === false) return; var sel = win.getSelection(); sel.removeAllRanges();
function getNode($e,s)
{ var node = $e;
for( var n=0;n<s.length;n++ )
{ var index = s[n]; if(index < 0) break;
node = node.contents(':eq('+index+')');
} return node.get(0);
}
var start = getNode($e,s.start), end = getNode($e,s.end), range = win.document.createRange();
range.setStart(start,s.startOffset); range.setEnd(end,s.endOffset); sel.addRange(range);
}
您可以在插入符號處插入一個小的span-element,獲取其位置並將其刪除。 對於跨瀏覽器范圍和選擇庫,請參閱rangy 。
單擊元素時,將創建一個長度為零的Selection對象(從element.getSelection()獲取,其中element是有問題的div)。 該對象的focusOffset將告訴您單擊該div中的第74個字符(這是Adrien所說的在不同答案中不可能的事情)。
讀取文本中的插入位置,然后在編輯窗口中設置插入位置。
聽起來你正在嘗試進行內聯編輯...你看過jeditable插件了嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.