jQuery - выберите невидимый текст, наложенный на изображение, аля GMail PDF viewer - PullRequest
7 голосов
/ 09 ноября 2010

Я накладываю невидимый текст поверх изображения. Существует ли плагин jQuery (или аналогичный), который позволит пользователям выбирать область на изображении (которая также выделяет наложенный текст) и сможет копировать содержимое.

Прямо сейчас я поместил каждый символ в свой собственный тег <span />. Проблема в том, что когда пользователь выбирает, он иногда выделяет весь наложенный текст (если пользователь не очень точен своей мышью), иногда само изображение становится выделенным и т. Д.

Было бы неплохо решение, похожее на средство просмотра PDF GMail. Предложения?

Ответы [ 2 ]

8 голосов
/ 09 ноября 2010

Похоже, Google знает из pdf-файла, где в файле находятся различные текстовые смещения x,y. Когда вы выделяете несколько строк, он размещает набор абсолютно расположенных «выделенных» дивов над изображением, где находится «текст» (они имеют класс highlight-pane). Когда вы выбираете текст, он заполняет текстовое поле #selection-content содержимым того, что вы выбрали, и выделяет текст в нем (попробуйте использовать, например, window.getSelection().anchorNode в Chrome). Помимо этих оверлеев, есть только изображение .page-image. Бьюсь об заклад, они на самом деле используют окно, чтобы захватить все жесты мыши, которые им небезразличны (я полагаю mousedown и mouseup). ( Вот пример документа в формате PDF )

Если вы позиционируете элементы абсолютно, вы можете обнаружить mousedown, mousemove и mouseup, выяснить, находится ли мышь над элементами диапазона (или ближайшая к ней), и заполнить текстовое поле содержимым всего контента между этими двумя элементами. Если вы хотите просто использовать гранулярность слова, я сомневаюсь, что кто-то будет жаловаться (окружайте каждое слово с помощью интервала, а не каждой буквы).

Редактировать : Прошлой ночью мне стало любопытно, и я кодировал действительно наивную версию. Он работает только с mousedown и mouseup и не работает в IE (мне не хочется отлаживать его):

Проверьте это на jsfiddle.

Функции, которые вы можете добавить:

  1. Какой-то лучший способ проверки совпадений на основе позиции; Я просто делаю, включен ли он в коробку.
  2. Динамическое обновление mousemove
  3. На основе строки, а не на основе диапазона
  4. Вы все еще можете выбирать по цвету фона, но в зависимости от того, как устроены ваши элементы, это может выглядеть не очень хорошо. Также потребуется поддержка прозрачности.
1 голос
/ 10 ноября 2010

Вот простой пример, использующий мой ответ на ваш предыдущий вопрос: http://www.jsfiddle.net/yijiang/83W7X/2/embedded/result

var selected = [];

function drawSelection(){
    if(selected.length){
        selected.sort(function(a, b){
            if(a.sourceIndex){
                return a.sourceIndex - b.sourceIndex;
            } else if(a.compareDocumentPosition){
                if(a.compareDocumentPosition(b) == Node.DOCUMENT_POSITION_PRECEDING){
                    return 1;
                } else {
                    return -1;
                }
            }
        });
        var range = rangy.createRange(),
            sel = rangy.getSelection();

        range.setStart(selected[0].children[0], 0);
        range.setEnd(selected[selected.length - 1].children[0], 1);
        sel.setSingleRange(range);
    }
}

$('ul').selectable({
    delay: 100,
    selecting: function(event, ui) {
        if(ui.selecting.getAttribute('class').indexOf('wrapper') !== -1 && $.inArray(ui.selecting, selected) === -1) {
            selected.push(ui.selecting);
            drawSelection();
        }
    },
    unselecting: function(event, ui){
        if(ui.unselecting.getAttribute('class').indexOf('wrapper') !== -1 && $.inArray(ui.unselecting, selected) > -1){
            selected.splice($.inArray(ui.unselecting, selected), 1);
            drawSelection();
        }
    }
});

Он сочетает в себе выбираемый пользовательский интерфейс jQuery с превосходной библиотекой Тима Дауна Rangy, чтобы создать нечто похожее на то, что вы просили,Я думаю.То, что вы просили, было не совсем понятно.

Код содержит массив выбранных li элементов.Вторая часть кода добавляет соответствующие обработчики событий и параметры.Функция drawSelection вызывается каждый раз, когда элемент выбирается или отменяется.Функция сначала сортирует все элементы по их положению в DOM, затем переходит к рисованию выбора от первого выбранного li до последнего.

Код, подобный theazureshadow , предназначен только для проверки концепции, поскольку я абстрагируюсь от того, что действительно должно быть простой задачей выбора li s для довольно тяжелого Rangyбиблиотека.Это также не очень хорошо работает и может быть сделано с некоторым рефакторингом.

...