2014-09-06 13 views
8

Próbuję programować coś w stylu textarea, tylko do treningu.jQuery: Podziel tekst na pozycję myszy click

Mam div z (generowane przez użytkowników) tekst w nim:

<div id="editor">Hello! I am a Text!</div> 

Jeśli kliknę (z lewej MouseButton) pomiędzy dwoma „L” z „Hello”, na przykład, ja lubię to zobaczyć:

<div id="editor">Hel<div id="cursor">|</div>lo! I am a Text!</div> 

Jak to osiągnąć? Do tej pory robię to z ...

//HTML 
<div id="editor" onclick="setCursorWithMouse()"><!-- User-Text --></div> 

//jQuery 
function setCursorWithMouse(){ 
    $('#editor').append('<div id="cursor">|</div>'); 
} 

... ale, oczywiście, po prostu dodaje kursor na końcu div.

Skąd mogę wiedzieć, gdzie dokładnie kliknął użytkownik, gdzie dodać kursor (lub cokolwiek innego), gdzie podzielić tekst?

Dzięki

Edit:

  • Nie chcę używać contenteditable! Po prostu spójrz na to w ten sposób: chcę podzielić ciąg znaków w pozycji kliknięcia myszą.

  • Wiem .append() nie jest tym, czego szukam! .append() był tylko symbolem zastępczym dla późniejszej, lepszej funkcji. Tę funkcję, o którą teraz pytam.

  • Używam czcionki o stałej szerokości.

+0

To wygląda tak, jak chcesz, aby stworzyć swój własny edytor tekstu. W tym celu powinieneś rzucić okiem na [html's contenteditable] (https://www.google.com/?q=html%20contenteditable#q=html+contenteditable) – hffmr

+0

Znam contenteditable, ale wolałbym to zrobić bez niego . Chciałbym zaprogramować funkcjonalność textarea lub div z contenteditable przeze mnie, o to właśnie chodzi ... – WcPc

+0

co to jest "append()", gdy chcesz zmienić strukturę istniejącego html? Użyj contenteditable, ponieważ twoje umiejętności nie wystarczą do zrobienia tego, o co prosisz – charlietfl

Odpowiedz

7

to jest tak blisko, jak mogę dostać: DEMO

var clicked=false; 
$('#editor').click(function(e){ 
    $(this).addClass('active'); 
    var letterWidth=7; 
    $('#editor span').remove(); 
    var clickPos=e.pageX-$(this).offset().left; 
    if(!clicked) clickPos+letterWidth; 
    var letter=Math.round(clickPos/letterWidth); 
    var before=$(this).html().substr(0,letter); 
    var after=$(this).html().substr(letter,$(this).html().length); 
    $(this).html(before+'<span>|</span>'+after); 
    clicked=true; 
}); 
$(document).click(function(e){ 
    if(!$('#editor').is(e.target)){ 
     $('#editor').removeClass('active'); 
     $('#editor span').remove(); 
     clicked=false; 
    } 
}); 

mam nadzieję, że jest wystarczająco blisko! :)

UWAGA:

ten kod jest napisane przy założeniu, że font-size jest 16px!

Obawiam się, że musisz obliczyć wartość font-size dla kolejnych rozszerzeń.

+0

To ładnie wygląda! Spróbuję teraz wprowadzić go do mojego kodu, może to chwilę potrwać. Wrócę, a następnie otrzymasz "zaakceptowaną odpowiedź". Dzięki! – WcPc

+0

Ok, działało idealnie. Wielkie dzięki! – WcPc

+0

Nie ma za co;) –

0

Uwaga, nie zwraca oczekiwanych wyników na firefox; chrome zwraca oczekiwane wyniki, ale kursor może przesuwać się w lewo lub w prawo o 1 znak, jeśli mysz nie jest zwolniona powoli.

$(function() { 
 
    $(document).data("text", $("#editor").text()) 
 
    .on("mousedown", function() { 
 
     $("#editor") 
 
     .html($(this) 
 
      .data("text")) 
 
    }) 
 
    .on("mouseup", function() { 
 
     that = $("#editor"); 
 
     var sel = window.getSelection ? window.getSelection() : document.selection(); 
 
     var o = that.text(); 
 
     var before = sel.baseOffset; 
 
     var after = o.length - before; 
 
     var a = o.slice(0, before); 
 
     var b = after === 0 ? "" : o.slice(-after); 
 
     var n = "<data>|</data>"; 
 
     var html = (after === "" ? a + n : a + n + b); 
 
     that.html(html); 
 
    }); 
 
})
#editor { 
 
    font-family: Sans; 
 
    font-size: 28px; 
 
    letter-spacing: 8px; 
 
    white-space: pre; 
 
} 
 
#editor > data { 
 
    color: red; 
 
    max-width: .1em; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<div tabindex="0" id="editor">Hello! I am a Text!</div>

jsfiddle http://jsfiddle.net/guest271314/maakff7q/

+0

Proszę ponownie sprawdzić skrzypce. Po prostu duplikuje istniejący tekst za pomocą '| 'pomiędzy zwrotami. – crashwap

+1

@crashwap Zobacz OP na _ "Jeśli kliknę (lewym klawiszem myszy) pomiędzy dwoma literami" L "z" Hello ", chciałbym zobaczyć:

Hel
|
lo! Jestem tekstem!
" _ . Jeśli poprawnie interpretujesz Pytanie, musisz wstawić '|' gdzie kliknięcie w tekście, w miejscu, w którym kliknięto, symulując 'kursor'? Dzięki – guest271314

+0

Wygląda na to, że Twoja interpretacja OP jest poprawna: znak '|' powinien zostać wstawiony do istniejącej frazy, w miejscu, w którym użytkownik kliknie. ALE, w twoim skrzypku, kursor jest wstawiany na końcu frazy, a fraza jest następnie dokładnie powielana (tworząc dwie kopie oryginalnej frazy, oddzielone przez '|'. * Być może widzisz coś innego, gdy biegasz na skrzypcach? (Jednak jak to możliwe?) * Porównuj efekty wizualne z zaakceptowanym dźwiękiem DEMO. *** (To może wyjaśnić, dlaczego twoja doskonała odpowiedź nie została przegłosowana ...) *** – crashwap

Powiązane problemy