2012-03-02 11 views
9

Oto, co próbuję osiągnąć: Gdy użytkownik korzysta z myszy, klawiatury lub przycisku dotykowego, aby wybrać tekst w "myDiv", chcę zdobyć trzy dyskretne fragmenty kodu HTML: kod HTML przed wyborem (do "lewego" z tego), HTML w selekcji i HTML po selekcji ("w prawo"). HTML powinien wyglądać tak, jak w przypadku myDiv.innerHTML.Jak uzyskać kod HTML przed, wewnątrz i po selekcji (nie w textarea)?

Wybór może rozpocząć się lub zakończyć w parze znaczników (tzn. Zaznaczony wybór niekoniecznie musi być prawidłowy HTML). Nie muszę zajmować się specjalnymi scenariuszami, takimi jak elementy pozycjonowane bezwzględnie w ramach selekcji; wszystkie wybrane opcje będą ograniczone do jednego elementu div zawierającego podstawowe tagi, takie jak strong, em, ul, ol, h1, image i table.

Najbliższy, do którego przyszedłem, używa rangy do zaczepienia zaznaczenia i wywołania selection.getRangeAt(0).cloneContents(), aby uzyskać zaznaczony kod HTML. Działa to wystarczająco dobrze, dopóki nie dokonam selekcji, która jest nieważna w izolacji, a przeglądarka zmienia kod HTML fragmentu dokumentu, aby uczynić go prawidłowym znacznikiem.

Dodatkowe informacje: Oto dlaczego muszę to:

Tworzę system sprzężenia zwrotnego dokumentu, więc trzeba zapisać informacje wyboru do bazy danych w celu późniejszego odtwarzania i odtworzeniu. Normalnie zapisałbym zaznaczenie przy użyciu ścieżki DOM i zaznaczonego tekstu, ale tekst może się zmieniać między zapisaniem a odtworzeniem. Na przykład autor może przesuwać całe akapity, usuwać sekcje itd. Ścieżka DOM staje się wówczas bezużyteczna.

Tak więc moim (niedoskonałym) planem jest przechowywanie zaznaczenia jako [offset, długość, html_snippet]. To jest "pozycja". Będę również przechowywać fragmenty html, które pojawiły się bezpośrednio przed i po zaznaczonym tekście. To jest "kontekst".

Korzystając z kombinacji tych danych, powinienem być w stanie przenieść pierwotnie wybrany tekst przez większość czasu, nawet jeśli został przesunięty lub częściowo zmieniony. Gdy to się nie uda, interfejs użytkownika będzie w stanie go rozwiązać, ale chciałbym, aby wystąpił tak rzadko, jak to możliwe.

Superpuchowie!

+3

To jest dużo tekstu. –

+0

Tak, starałem się dostarczyć jak najwięcej informacji, a zamiast tego byłem nieprzyzwoicie gburowaty. Właśnie teraz trochę go pomiażłam. :) –

+0

Żeby było jasne: czy potrzebne fragmenty kodu HTML muszą być dokładnie takie, jakie pojawiają się w źródle HTML wysyłanym do przeglądarki? –

Odpowiedz

1

Mam kilka pytań:

1.- Kiedy mówisz „html po wyborze” - jak by to html być inny niż poprzedni html do wyboru lub na odwrót? Czy sam proces "selekcji" ingeruje w HTML ze względu na twój "skrypt" czy cokolwiek innego?

2.- Powiedziałeś, że selekcja tekstu nie odbywa się w tekstach ... z jakimi elementami pracujesz? akapity? divs ...? Zawężenie go pomogłoby.

3.- Czy myślisz o użyciu jquery?

http://api.jquery.com/select/

Uprawiając jak

$('#element_with_text_goes_here').select(function() { 

//apply grabbing functions here, for example 

//copy html 'before' selection: 
    $pre_html = $('html').clone(); 

    // copy selection...see below: 

    // copy html 'after' selection'...same as before 


}); 

Copy wybór:

Jak wspomniano tutaj:

Selecting text in an element (akin to highlighting with your mouse)

Jason napisał następującą funkcję:

function selectText(element) { 
    var doc = document; 
    var text = doc.getElementById(element);  

    if (doc.body.createTextRange) { // ms 
     var range = doc.body.createTextRange(); 
     range.moveToElementText(text); 
     range.select(); 
    } else if (window.getSelection) { // moz, opera, webkit 
     var selection = window.getSelection();    
     var range = doc.createRange(); 
     range.selectNodeContents(text); 
     selection.removeAllRanges(); 
     selection.addRange(range); 
    } 
} 

żywej demo pracy, które można znaleźć tutaj: http://jsfiddle.net/edelman/KcX6A/339/

oraz wersja jQuery plugin tutaj: http://jsfiddle.net/edelman/KcX6A/340/

które można wykorzystać do otrzymywania wybranego tekstu. Będziesz musiał go odpowiednio dostosować, ponieważ zbliżał się do niego z przeciwnego kąta. Im więcej szczegółów możesz nam dać ... tym lepiej możemy pomóc.

Nadzieja to pomaga
G

+0

W odpowiedzi na twoje pierwsze pytanie: Przez "poprzedni" do wyboru nie mam na myśli "w przeszłości", mam na myśli "po lewej stronie". Wyobraź sobie, że dokonanie wyboru dzieli zawartość mojego div na trzy sekcje: html po lewej stronie selekcji, html w selekcji i html po prawej stronie selekcji. Potrzebuję uzyskać niezmodyfikowany html dla każdej z tych sekcji. –

+0

W odpowiedzi na twoje drugie pytanie: To wszystko jest zawarte w div, który zawiera znaczniki, takie jak strong, em, image, itp. –

+0

... a jQuery jest zdecydowanie moją preferencją, ale nie jest wymagana. –

0

Ten kod html/tekst dostaje od wyboru użytkownika, ale działa tylko w IE. Kod działa również z zaznaczeniem krzyżowym. (Globals wykorzystywane do prowadzenia kod krótki.)

<script> 
function selected(){ 
    thediv=document.getElementById('div'); 
    res=document.getElementById('htm'); 
    userSelection=document.selection; 
    userRange=userSelection.createRange(); 
    /* For wider scale of elements */ 
    // rangeParent=userRange.parentElement(); 
    // if(rangeParent!=thediv) userRange.moveToElementText(rangeParent); 
    rangeText=userRange.htmlText; // OR: rangeText=userRange.text; 
    res.innerText=rangeText;  
    return; 
}  
</script> 
</head>  
<body onload="document.onselectionchange=selected;"> 
<div id="div"> 
<h1>The great testpage</h1> 
<p>A paragraph with some text</p> 
<p>This paragraph <b>contains</b> a child element.</p> 
<p>And this is the last paragraph.</p> 
<table> 
<tr><td>Cell1-1</td><td>cell1-2</td></tr> 
<tr><td>Cell2-1</td><td>cell2-2</td></tr> 
</table> 
<ol> 
<li>item1</li> 
<li>item2</li> 
<li>item3</li> 
</ol> 
</div> 
<br> 
<span id="htm"></span> 
</body> 

zawartość przed & po selekcji w thediv dostaniesz tak: prepost=thediv.innerHTML/innerText.split(rangeText);

Jeśli strona zawiera żadnych innych elementów, ale thediv, muszą być niezaznaczonym.

+0

IE-only nie działa dla mnie, ale dzięki za wysiłek niezależnie. :) –

+0

@AlanBellows Zanim "wykończyłeś" swój oryginalny wpis, wspomniałem o IE. W każdym razie kod zawiera pewne pomysły, które można "przetłumaczyć" także dla innych przeglądarek. Ta odpowiedź nie była nawet idealnym rozwiązaniem dla twojego pytania.Masz bardzo interesujące i wymagające zadanie, powodzenia z nim ... – Teemu

+0

W moim oryginalnym poście napisałem, że jest w porządku, jeśli nie działa on w IE. :) Czego szukam może nie być możliwe, ale przez gumę spróbuję. Dzięki! –

Powiązane problemy