2010-05-31 29 views
5

Tôi đang quên tính tương thích giữa các trình duyệt trong thời điểm này, tôi chỉ muốn điều này hoạt động. Điều tôi đang cố gắng sửa đổi tập lệnh (và có thể bạn không cần biết điều này) tại số typegreek.com Kịch bản cơ bản được tìm thấy here. Về cơ bản những gì nó làm là khi bạn gõ vào các ký tự, nó chuyển đổi các ký tự bạn đang gõ vào các ký tự Hy Lạp và in nó lên màn hình. Những gì tôi đang cố gắng làm là làm cho nó hoạt động trên contentEditable div's (Nó chỉ hoạt động cho Textareas)Cần đặt vị trí con trỏ đến cuối div nội dung có thể chỉnh sửa, vấn đề với các đối tượng được chọn và phạm vi

Vấn đề của tôi là với một chức năng này: Người dùng nhập một khóa, nó sẽ được chuyển sang một phím Hy Lạp, và đi đến một chức năng, nó được sắp xếp thông qua một số nếu, và nơi nó kết thúc là nơi tôi có thể thêm hỗ trợ div. Dưới đây là những gì tôi có cho đến nay,

myField là div, myValue là ký tự Hy Lạp.

//Get selection object... 
var userSelection 
if (window.getSelection) {userSelection = window.getSelection();} 
else if (document.selection) {userSelection = document.selection.createRange();} 

//Now get the cursor position information... 
var startPos = userSelection.anchorOffset; 
var endPos = userSelection.focusOffset; 
var cursorPos = endPos; 

//Needed later when reinserting the cursor... 
var rangeObj = userSelection.getRangeAt(0) 
var container = rangeObj.startContainer 

//Now take the content from pos 0 -> cursor, add in myValue, then insert everything after myValue to the end of the line. 
myField.textContent = myField.textContent.substring(0, startPos) + myValue + myField.textContent.substring(endPos, myField.textContent.length); 

//Now the issue is, this updates the string, and returns the cursor to the beginning of the div. 
//so that at the next keypress, the character is inserted into the beginning of the div. 
//So we need to reinsert the cursor where it was. 

//Re-evaluate the cursor position, taking into account the added character. 
    var cursorPos = endPos + myValue.length; 

    //Set the caracter position. 
    rangeObj.setStart(container,cursorPos) 

Hiện tại, điều này chỉ hoạt động miễn là tôi không nhập nhiều hơn kích thước của văn bản gốc. Nói rằng tôi đã có 30 ký tự trong div trước khi tay. Nếu tôi gõ nhiều hơn 30, nó thêm ký tự 31, nhưng đặt con trỏ trở lại 30. Tôi có thể gõ ký tự 32 tại pos.31, sau đó ký tự 33 ở vị trí pos.32, nhưng nếu tôi cố gắng đặt ký tự 34 vào, nó thêm ký tự và đặt con trỏ về 32. Vấn đề là chức năng thêm các vít ký tự mới lên nếu cursorPos lớn hơn giá trị được xác định trong phạm vi. Ý tưởng nào?

Trả lời

14

Dễ dàng thực hiện trình duyệt chéo này trong div có thể chỉnh sửa được hơn là vùng văn bản. Sau đây giả định div có thể chỉnh sửa nội dung của bạn có id là "greek".

var greekChars = { 
    "a": "\u03b1" 
    // Add character mappings here 
}; 

function convertCharToGreek(charStr) { 
    return greekChars[charStr] || "[Greek]"; 
} 

function insertTextAtCursor(text) { 
    var sel, range, textNode; 
    if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt && sel.rangeCount) { 
      range = sel.getRangeAt(0); 
      range.deleteContents(); 
      textNode = document.createTextNode(text); 
      range.insertNode(textNode); 

      // Move caret to the end of the newly inserted text node 
      range.setStart(textNode, textNode.length); 
      range.setEnd(textNode, textNode.length); 
      sel.removeAllRanges(); 
      sel.addRange(range); 
     } 
    } else if (document.selection && document.selection.createRange) { 
     range = document.selection.createRange(); 
     range.pasteHTML(text); 
    } 
} 

var div = document.getElementById("greek"); 

div.onkeypress = function(evt) { 
    evt = evt || window.event; 
    var charCode = (typeof evt.which == "undefined") ? evt.keyCode : evt.which; 
    if (charCode) { 
     var charStr = String.fromCharCode(charCode); 
     var greek = convertCharToGreek(charStr); 
     insertTextAtCursor(greek); 
     return false; 
    } 
} 
+0

Bravo! Nó hoạt động hoàn hảo! – DavidR

+0

Tôi đã có một trường hợp tương tự, tìm thấy 'range.collapse (false)' là thích hợp hơn 'setStart' +' setEnd' ở đó, nhưng gợi ý của bạn để sử dụng 'sel.removeAllRanges' theo sau bởi' sel.addRange' đã chứng minh _very_ hữu ích trên trình duyệt WebKit! +1 –

+0

chỉ muốn nói lời cảm ơn, tìm thấy điều này sau khi đấu tranh để làm cho nó hoạt động trong 2 giờ –

0

Tôi nghĩ bạn có thể đặt bù trừ bắt đầu vượt quá bù trừ cuối.

Bạn nên đặt bù trừ đầu tiên trước khi bù đắp bắt đầu khi bạn chèn văn bản.

rangeObj.setEnd(container, cursorPos); 
rangeObj.setStart(container,cursorPos); 
+0

Nó vẫn không hoạt động khi tôi cố gắng làm điều đó. Tôi đang nghĩ rằng việc sử dụng dải ô có thể không phải là giải pháp tốt nhất ở đây. – DavidR

Các vấn đề liên quan