2012-12-31 231 views
6

考慮下面的contenteditable div。如何在兩個div之間的contenteditable div中設置插入/光標位置。

<div contenteditable="true"> 
<div>bold text</div><div>bold text</div> 
</div> 

如果我定位兩個div之間光標並開始鍵入文本出來大膽而不是插入的兩個div之間一個新的文本節點。如果你打回家並嘗試在第一個div前輸入內容,也會發生同樣的情況。它成爲第一個div的一部分。

如果我檢查從選擇返回的範圍的startContainer,我得到的div的一個內容,而不是一個空的文本節點,如我所料。

看到這個http://jsfiddle.net/9ZZpX/3/

的問題是,爲什麼會發生這種情況?我如何選擇div之間的位置,以便在輸入內容時不會加粗? (很明顯,我可以添加一個空間,並且可以解決問題,但這非常難看。)

如果您在狀態更新框中輸入@mention,然後按HOME,則可以在Facebook上看到此功能正常工作。如果您輸入的文字不會突出顯示。

我已經能夠想到的唯一事情是攔截按鍵並以編程方式插入文本節點,但這看起來很難看。

我瘋狂地搜索,找不到任何引用記錄如何真的應該工作。顯然有一些我不明白的地方,而且這方面的文檔確實很少。我想要做的就是檢測光標何時進入這些div並跳過它,如果兩個div彼此相鄰,則光標跳轉到其中一個的div並渣土趕工)上什麼,我試圖做

更多信息:http://a-software-guy.com/2012/12/the-horrors-of-cursor-positioning-in-contenteditable-divs/

+0

我爲文章upvoted。感謝記錄! –

回答

7

瀏覽器是在這個不一致。 Firefox會讓你把插入的位置放在比大多數瀏覽器更多的位置上,但是WebKit和IE都有關於有效插入位置的明確想法,並且會修改你添加到選擇的範圍以符合最近的有效位置。這確實是有道理的:具有不同的文檔位置並因此針對相同的視覺插頁位置的行爲對於用戶而言是混淆的。但是,這是以開發人員不靈活爲代價的。

這沒有記錄在任何地方。 current Selection spec對此沒有提及,主要原因是瀏覽器在實現其選擇API時沒有規範存在,並且當前規範沒有統一的行爲文檔。

根據您的建議,一個選項是攔截keypress事件,但當用戶使用編輯或上下文菜單粘貼內容時,這將無濟於事。另一種方法是使用鼠標和鍵盤事件記錄選擇內容,創建具有零寬度空格字符的元素,以便在必要時將插入符號放入並放置在一個元素中。正如你所說,醜陋。

+0

謝謝。優秀。這正是我需要的。 –

+0

(順便說一句,謝謝你的Rangy,非常有用) –

+0

一篇關於我的努力和我嘗試的方法的文章:http://a-software-guy.com/2013/01/you-cant-select-that -webkit-browser-selections-and-ranges-in-chrome-and-safari/ –

4

我的答案將只是蒂姆的一個補充,這是一個全面的。

AFAIK Facebook不會使用可編輯的內容。狀態框由一個簡單的textarea和div底層構成,它們在其上呈現藍色背景以便刻劃。

儘管他們確實會這樣做,但因爲nick會是一個內聯元素,幸運的是內聯元素的情況更簡單:)。

關於在無法訪問的地方定位插入符號 - 在CKEditor中,我們遇到了同樣的問題。有很多地方用戶不能移動插入符號。我們決定用名爲Magic-line的插件來解決這個問題。正如您在演示中看到的,我們完全繞過了選擇問題,我認爲這是解決此問題的最佳方法。這是非常有用的,並且在CKEditor 4.0.1中它將會(並且已經在master上)也可以通過按鍵完全訪問。

+0

這是一個有趣的解決方案。 +1。 –

+0

非常有趣的+1。我開始嘗試複製Facebook做的事情,但很快意識到我想完成一些不同的事情。 只是一個偏離正題的話題,如果你在頂部打開一行,在Linux下的Chrome中似乎沒有辦法刪除第一行。我按刪除,整個區域被突出顯示。 –

0

你可以做的另一件事是使用突變觀察器來捕捉突變,然後在事後修復它們。在我的用例中,我很幸運,每個元素都有預定義的文本。當突變觀察者觸發時,我只是簡單地將更改的文本移動到元素之前或之後的新文本節點。這似乎比其他選項容易得多,因爲觀察者會觸發字符數據的所有更改,並且它也具有所有更改的正確記錄,與按鍵事件不同。

相關問題