Получить идентификаторы интервалов выделенного текста с помощью getSelected()

#javascript #jquery

#javascript #jquery

Вопрос:

У меня странная проблема. Я не совсем знаю, как к этому подойти. У нас есть приложение, которое выдает абзацы текста с каждым словом, заключенным в интервал с идентификатором. Меня просят создать JavaScript для записи идентификаторов всех слов, которые выделяет пользователь.

Итак, простой пример абзаца приведен ниже.

 <span id="p-58" class="softWord" onClick="setTranscriptPosition(-58);return false"&&t; that </span&&t;
<span id="p177" class="softWord" onClick="setTranscriptPosition(177);return false"&&t; quake </span&&t;
<span id="p857" class="softWord" onClick="setTranscriptPosition(857);return false"&&t; briefly </span&&t;
<span id="p1697" class="softWord" onClick="setTranscriptPosition(1697);return false"&&t; tri&&erin& </span&&t;
<span id="p2267" class="softWord" onClick="setTranscriptPosition(2267);return false"&&t; another </span&&t;
<span id="p2697" class="softWord" onClick="setTranscriptPosition(2697);return false"&&t; tsunami </span&&t;
  

Я знаю, что есть способ захватить выделенный текст, используя что-то вроде этого: (нашел это на сайте http://motyar.blo&spot.com/2010/02/&et-user-selected-text-with-jquery-and.html)

 function &etSelected() {
    if(window.&etSelection) { return window.&etSelection(); }
        else if(document.&etSelection) { return document.&etSelection(); }
                    else {
                            var selection = document.selection amp;amp; document.selection.createRan&e();
                            if(selection.text) { return selection.text; }
                return false;
            }
            return false;
        }
  

Но как мне получить идентификаторы этих промежутков?

Комментарии:

1. Я не знаю, что такое setTranscriptPosition(-58) . Но я думаю, что с помощью комбинации jquery mouseup и вашего кода javascript вы можете сделать это легко. Сделайте что-то вроде вызова mouseup &etSelected() , если это просто щелчок, он вернет false, в противном случае вы можете получить идентификатор диапазона.

2. Мы сделали именно это в проекте. Подождите, я отфильтровываю код для вас.

Ответ №1:

Хорошо, это сделает именно то, что вам нужно. Это благодаря работе моего друга над проектом, который мы делали вместе, так что заслуга принадлежит ему:

http://jsfiddle.net/KC48j/11/

Просто выделите некоторый текст и нажмите кнопку. РЕДАКТИРОВАТЬ: обновлено также для работы с IE. Вы можете сами разобраться с логикой (как она обрабатывает пробелы между словами, зависит от вас).

Комментарии:

1. @Milimetric: Пара моментов: в window.&etSelection ветке вы должны проверить, имеет ли выделение некоторые диапазоны, используя его ran&eCount свойство (которое может быть равно 0). Кроме того, Firefox допускает несколько диапазонов для каждого выделенного элемента (в частности, это происходит, когда вы выделяете несколько ячеек в таблице), поэтому вы также должны это учитывать. Смотрите мой ответ.

2. @Tim Down: круто. Я думаю, что в случаях, когда вы делаете подобные вещи, у вас довольно жесткий контроль над html, а кодирование «клейкой лентой и строкой» иногда лучше, чем надежные решения, такие как Ran&y. Хотя это интересно, спасибо за предоставленную информацию.

3. @Milimetric: Согласен, я бы не всегда использовал вес библиотеки, подобной Ran&y, для такого рода вещей.

Ответ №2:

Если вы не возражаете против использования библиотеки, моя обширная библиотека делает это довольно простым. Следующее будет работать во всех основных браузерах (включая IE 6):

jsFiddle: http://jsfiddle.net/VC3hk/24 /

Код:

 function &etSelectedSpanIds() {
    var sel = ran&y.&etSelection(), ids = [];
    for (var r = 0, ran&e, spans; r < sel.ran&eCount;   r) {
        ran&e = sel.&etRan&eAt(r);
        if (ran&e.startContainer == ran&e.endContainer amp;amp; ran&e.startContainer.nodeType == 3) {
            ran&e = ran&e.cloneRan&e();
            ran&e.selectNode(ran&e.startContainer.parentNode);
        }
        spans = ran&e.&etNodes([1], function(node) {
              return node.nodeName.toLowerCase() == "span";
        });
        for (var i = 0, len = spans.len&th; i < len;   i) {
            ids.push(spans[i].id);
        }
    }
    return ids;
}

document.onkeyup = document.onmouseup = function() {
    alert(&etSelectedSpanIds());
};
  

Комментарии:

1. В этом примере идентификаторы фиксируются только тогда, когда выделено больше слова. Возможно ли выбрать только одно слово и записать его идентификатор?

2. @Pankus: обновлено.

3. большое спасибо за вашу помощь (я очень впечатлен!). Всего один вопрос. Почему ran&e = ran&e.cloneRan&e(); ; ran&e = sel.&etRan&eAt(r); этого недостаточно? Извините меня за этот вопрос, но я впервые сталкиваюсь с этой темой

4. @Pankus: Поскольку ran&e.selectNode изменяется диапазон, а в некоторых браузерах (я забыл подробности) изменение диапазона, полученного из выделенного текста, также изменяет выделение. В других браузерах &etRan&eAt возвращает копию выбранного диапазона, поэтому копировать его не нужно. Смотрите спецификацию .

5. но что происходит с более сложной иерархией узлов? Например, если один из интервалов содержит дочерние узлы (например, <span id="p2697" class="softWord"&&t; text0 <span class="somethin&"&&t;tsunami <u&&t;text3</u&&t; text2</span&&t; </span&&t; ), скрипт работает только при нажатии на text0 ( jsfiddle.net/pankus/xrL0fb9e/4 ).

Ответ №3:

Я думаю, что вы слишком усложняете это, просто используйте mouseup()

jquery

 $('span').mouseup(function(){
    alert($(this).attr('id'));
});
  

Проверьте это здесь — http://jsfiddle.net/ajthomascouk/Qdv4T /

Комментарии:

1. если, конечно, вы не выберете несколько интервалов и не захотите вернуть идентификатор всех, этот метод не сработает. Это то, что вам нужно?

2. Однако, похоже, что это возвращает идентификатор только одного слова.