Próbuję uzyskać przesunięcia znaków dla początku i końca zaznaczenia w obrębie artykułu. Chciałbym jednak, aby niektóre elementy zostały zignorowane w tym procesie.Pobranie zaznaczonego tekstu z wyjątkiem elementów nie do wybrania
W mojej aplikacji serwer pracuje z kodem HTML, zanim JS wstrzyknie kilka elementów dynamicznie i jest bardzo ważne, aby liczba znaków w tekście pozostawała spójna między serwerem a klientem.
Miałem nadzieję, że będzie to tak proste jak window.getSelection()
wraz z user-select: none;
. Niestety, mimo że tekst nie wygląda na wybrany, nadal znajduje się w zakresie wyboru.
Napisałem krótki przykład poniżej. Miałem szansę na napisanie removeFromSelection
jako obejścia bez większego powodzenia. Być może muszę usunąć zakresy, które nakładają się na .unselectable
i ręcznie wypełnić luki nowymi obiektami zasięgu. Czuję, że to powinno być łatwiejsze niż robię to. Jak powinienem to robić?
function findAncestorOffset(container, node, offset)
{
\t if (node == container)
\t \t return offset;
\t var parent = node.parentNode;
\t var syblings = parent.childNodes;
\t for (var i = 0, len = syblings.length; i < len; i++)
\t {
\t \t if (syblings[i] == node)
\t \t \t break;
\t \t offset += $(syblings[i]).text().length;
\t }
\t return findAncestorOffset(container, parent, offset);
}
function removeFromSelection(selector, selection)
{
\t $(selector).each(function(i, node){
\t \t var range = document.createRange();
\t \t range.selectNodeContents(node);
\t \t selection.removeAllRanges(range);
\t });
}
var onSelect = function(){
var sel = window.getSelection();
//removeFromSelection('.unselectable', sel);
var text = sel.toString();
$('#out').text(text);
var range = sel.getRangeAt(0).cloneRange();
var i = findAncestorOffset($('.article')[0], range.startContainer, range.startOffset);
$('#from').text(i);
$('#to').text(i + text.length);
}
$('.article').mouseup(onSelect);
$('.article').focusout(onSelect);
.unselectable {
\t -webkit-touch-callout: none;
\t -webkit-user-select: none;
\t -khtml-user-select: none;
\t -moz-user-select: none;
\t -ms-user-select: none;
\t user-select: none;
}
pre, .article {
border: solid 1px black;
padding: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Select This</h1>
<div class="article">
<p>
This can be selected.
</p>
<p class="unselectable">
This can't.
</p>
<p>
And this can again.
</p>
</div>
<h1>Output</h1>
<div>
From: <span id="from"></span>, To: <span id="to"></span>
</div>
<pre id="out">
</pre>
Powinieneś dostać wybrany HTML: http://stackoverflow.com/questions/5222814/window-getselection-return-html Następnie można filtrować go, np: http://jsfiddle.net/xpca4fp5/ Ale to wymagałoby więcej testów, ponieważ myślę, że to może być błędne –