2013-03-07 120 views
5

我編寫了一個代碼來檢測使用javascript的選擇結束,並將標記放置在結束位置。看到此的jsfiddle:http://jsfiddle.net/vCwwN/使用javascript檢測選擇結束位置

上面的代碼執行以下操作:

  • 它處理所有LTR腳本(例如英語)正常(表示正確地結束標誌)。
  • 對於LTR腳本(例如英語)它會處理選擇是向前(從左/從上到右/下)還是向後(從右/從下到左/上),正確顯示停止選擇的標記(使用鼠標或鍵盤)。
  • 它使用getClientRects來查找所有的選擇矩形邊界,並使用黑客來檢測選擇的方向(如果向後或不向後)。根據這兩個信息,它將標記放在最後。

您可以嘗試選擇上述英文腳本中沒有任何問題的內容。唯一的問題是,當你嘗試處理RTL腳本(例如阿拉伯語)時,那麼標記將顯示在所選RTL腳本的開頭,而不是結尾處(鼠標/鍵盤實際停止的地方)。這些導致問題:

  • 在RTL腳本(阿拉伯語)中開始選擇,並在RTL腳本(阿拉伯語)內結束選擇。這會在選擇開始時顯示標記。
  • 在LTR腳本(英文)內開始選擇,並在RTL(阿拉伯語)腳本內結束選擇。這會在RTL腳本選擇開始時顯示標記(而不是結束)。

基本上,選擇開始隨地(LTR或RTL)和RTL劇本結尾是不正確。任何其他情況都可以正確處理(例如,從LTR或RTL開始,並以LTR結束,甚至在途中通過RTL腳本傳遞)。

問題是RTL腳本翻轉流的方向,因此向後是向前的,向前是向後的。這就是爲什麼我的代碼無法正確處理RTL,反向破解被逆轉。

我想到的一個解決方案是檢測選擇的最後一個字符,並查看它是否具有RTL腳本,然後基於此翻轉後退標誌。我已經放置了一個函數來檢測文本是否以RTL字符結尾(它與未使用的jsfiddle相同)。它可能會幫助你,幫我解決它:)

+0

輸入元件沒有表現得像一個RTL輸入我。 'dir = rtl'缺失? – Halcyon 2013-03-07 17:05:17

+0

不,它應該保持原樣(即LTR,默認)。如果你設置dir = rtl,那麼對於(RTL/LTR)腳本都會翻轉整個內容。我在自己的代碼中處理了(dir = rtl),但決定刪除這個額外的案例,以使代碼更簡單,並增加獲得答案的機會。 – tria 2013-03-07 17:11:07

回答

0

看看這是否是一個正確的方向邁出的一步。

它利用下面的代碼來Return HTML from a user selection發表Tim Down

function getSelectionHtml() { 
    var html = ""; 
    if (typeof window.getSelection != "undefined") { 
     var sel = window.getSelection(); 
     if (sel.rangeCount) { 
      var container = document.createElement("div"); 
      for (var i = 0, len = sel.rangeCount; i < len; ++i) { 
       container.appendChild(sel.getRangeAt(i).cloneContents()); 
      } 
      html = container.innerHTML; 
     } 
    } else if (typeof document.selection != "undefined") { 
     if (document.selection.type == "Text") { 
      html = document.selection.createRange().htmlText; 
     } 
    } 
    return html; 
} 

一旦被定義,你可以叫你所定義的lastCharTRL方法來檢查的最後一個字符是否RTL和採取相應的行動。

if (lastCharRTL(getSelectionHtml())) 
    $('#pointer').css({top: rects[n].top + 10, left: rects[n].left - 10}).show(); 
else if(backwards) 
    $('#pointer').css({top: rects[0].top + 10, left: rects[0].left - 10}).show(); 
else 
    $('#pointer').css({top: rects[n].top + 10, left: rects[n].right}).show(); 

DEMO

+0

雖然你的解決方案/演示有原始問題(RTL結束選擇仍然顛倒),可能是由於innerHTML和if/else-if/else,我想我得到了選擇文本的想法。我知道用'getSelection'你可以調用'toString'並獲得文本。然後檢查開始或結束(取決於選擇的方向)以查看是否存在RTL字符。我會盡力去做,看看。謝謝。 – tria 2013-03-14 09:11:05