2012-12-31 24 views
6

Rozważ następujące contenteditable div.Jak ustawić kursor/pozycję kursora w contenteditable div między dwoma elementami div.

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

Gdybym ustawić kursor między dwoma div i zacząć wpisywać tekst wychodzi śmiały zamiast wstawiania nowego węzła tekstowego między dwoma div. To samo dzieje się, gdy uderzysz w dom i spróbujesz wpisać coś przed pierwszym divem. Staje się częścią pierwszego div.

Jeśli sprawdzam zawartość startContainer zakresu, który jest zwracany z zaznaczenia, otrzymuję zawartość dla jednego z elementów div zamiast pustego węzła tekstowego, jak można się spodziewać.

Zobacz ten http://jsfiddle.net/9ZZpX/3/

Powstaje pytanie, dlaczego tak się dzieje? Jak mogę wybrać spację między elementami div, aby podczas wpisywania czegoś nie było pogrubione? (Oczywiście mogę dodać miejsce i to działa na problem, ale to jest dość brzydkie.)

Możesz zobaczyć, że działa poprawnie na Facebooku, jeśli wpisujesz @mention w oknie aktualizacji statusu i naciśnij HOME. Jeśli wpiszesz tekst, nie zostanie podświetlony.

Jedyne, co udało mi się wymyślić, to przechwytywanie naciśnięcia klawisza i wstawianie węzła tekstowego programowo, ale wydaje się to brzydkie.

Szukałem jak szalony i nie mogę znaleźć żadnych referencji dokumentujących, jak to naprawdę powinno działać. Jest oczywiście coś, czego nie rozumiem i brakuje dokumentacji w tej dziedzinie.

(To, co chcę zrobić, to wykrycie, gdy kursor ma zamiar wprowadzić jeden z tych elementów div i przeskoczyć nad nim .Jeśli dwa elementy div są obok siebie, kursor przeskakuje do jednego z nich. DIV i Mucks się prace)

Więcej informacji na temat tego, co próbuję zrobić. http://a-software-guy.com/2012/12/the-horrors-of-cursor-positioning-in-contenteditable-divs/

+0

Przegłosowałem artykuł. Dzięki za dokumentowanie! –

Odpowiedz

7

Przeglądarki są niespójne w tej sprawie. Firefox pozwoli ci ustawić pozycję na większej liczbie pozycji niż większość przeglądarek, ale WebKit i IE mają określone poglądy na temat prawidłowych pozycji karetki i poprawią zakres dodany do zaznaczenia, aby dopasować się do najbliższej prawidłowej pozycji. Ma to sens: posiadanie różnych pozycji dokumentu, a tym samym zachowanie dla tej samej wizualnej lokalizacji opieki jest mylące dla użytkownika. Jednak dzieje się to kosztem braku elastyczności dla programisty.

To nie jest udokumentowane w żadnym miejscu. The current Selection spec nic o tym nie mówi, głównie dlatego, że nie istniała specyfikacja, gdy przeglądarki zaimplementowały swoje selekcji API i nie ma jednolitego zachowania dla bieżącej specyfikacji do dokumentu.

Jedną opcją jest przechwytywanie zdarzenia keypress zgodnie z sugestią, ale nie pomoże to, gdy użytkownik wklei treść za pomocą menu edycji lub menu kontekstowego. Innym byłoby śledzenie selekcji za pomocą myszy i zdarzeń kluczowych, tworzenie elementów za pomocą, powiedzmy, zerowej szerokości znaku, w celu umieszczenia karetki i umieszczenia karetki w jednym z tych elementów, gdy jest to konieczne. Jak mówisz, brzydka.

+0

Dziękuję. Doskonały. Dokładnie tego potrzebowałem. –

+0

(BTW, dziękuję za Rangy, bardzo przydatne.) –

+0

Artykuł o moich wysiłkach i podejściu, które próbuję: http://a-software-guy.com/2013/01/you-cant-select-that -webkit-browser-selections-and-ranges-in-chrome-and-safari/ –

4

Moja odpowiedź będzie tylko dodatkiem do Tima, który jest wyczerpujący.

AFAIK Facebook nie wykorzystuje treści do edycji. Pole statusu składa się z prostego pola tekstowego i warstwy div pod nim, na którym renderują niebieskie cyfry dla nicków.

Chociaż, nawet gdyby tak było, byłby to inny przypadek, ponieważ nick byłby elementem liniowym i na szczęście sytuacja z elementami liniowymi jest prostsza :).

Jeśli chodzi o pozycjonowanie kija w niedostępnych miejscach - w CKEdycierze mieliśmy ten sam problem. Jest wiele miejsc, w których użytkownik nie może się poruszać. Postanowiliśmy rozwiązać ten problem za pomocą wtyczki o nazwie Magic-line. Jak widać w wersji demo, całkowicie pomijamy problem selekcji i myślę, że jest to najlepszy sposób na rozwiązanie tego problemu. Jest bardzo użyteczny, aw CKEdicie 4.0.1 będzie on (i już jest na master) również w pełni dostępny za naciśnięcia klawiszy.

+0

To interesujące rozwiązanie. +1. –

+0

Bardzo interesujące +1. Zacząłem próbować replikować to, co zrobił Facebook, ale szybko zdałem sobie sprawę, że to, co chcę osiągnąć, jest nieco inne. Po prostu nietypowy temat, jeśli otworzysz linię na górze, w Chrome pod Linuksem nie ma sposobu na usunięcie górnej linii. Naciskam delete i cały obszar zostanie podświetlony. –

0

Inną rzeczą, którą możesz zrobić, to użyć obserwatora mutacji, aby złapać mutacje, a następnie naprawić je po fakcie. W moim przypadku użycia miałem szczęście, ponieważ każdy element miał wstępnie zdefiniowany tekst. Kiedy uruchamiany jest obserwator mutacji, po prostu przeniosłem zmieniony tekst do nowego węzła tekstowego przed lub po elemencie, stosownie do potrzeb. Wydaje się to o wiele łatwiejsze niż w przypadku innych opcji, ponieważ obserwator uruchamia wszystkie zmiany danych postaci, a także ma odpowiedni zapis wszystkich zmian, w przeciwieństwie do zdarzenia naciśnięcia klawisza.

Powiązane problemy