簡體   English   中英

JavaScript'contenteditable' - 獲取/設置插入位置

[英]JavaScript 'contenteditable' — Getting/Setting Caret Position

我已經閱讀了幾篇關於插入符號的帖子,但似乎都沒有回答我的特定問題。

  1. 我有2個div( div1div2
  2. div1 =不可編輯的div
  3. div2 = contenteditable div
  4. 兩個div包含完全相同的內容
  5. 當用戶點擊div1時 ,它會被隱藏, div2出現在確切的位置,用戶可以編輯

問題 :我希望插入符號作為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM