Я пытаюсь что-то сделать, когда пользователь заканчивает делать выбор - по существу, в первом mouseup событии после каждого selectstart, я думаю, - на странице. Я хочу взять этот выбор и обернуть его в элемент, который будет стилизован с помощью CSS. Я предположил, что Selection API предложил событие для этого; однако, это не кажется.

let selContainer = document.createElement('span')
span.classList.add('user-selection')

const wrapSelection = () => {
  window.getSelection().getRangeAt(0).surroundContent(selContainer)
}


/*                   ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┓
                     ┃                          ┃
                     ┃  The Selection API only  ┃
                     ┃  affords these events:   ┃
                     ┃                          ┃
                     ┃  - selectionchange       ┃
                     ┃  - selectstart     ┏━━━━━┫
                     ┃                    ┃issue┃
                     ┗━━━━━━━━━━━━━━━━━━━━┻━━━━━┛

*/document.addEventListener('selectfinish', wrapSelection)/*
                             ┗━━━━┳━━━━━┛
                                  ┃
                                  ┃
                               no such
                                event                                                                                                                                                                                                        */
3
tjfwalker 2 Мар 2018 в 01:41

4 ответа

Лучший ответ

Я выбрал исходный код hypothes.is клиент веб-аннотаций, чтобы понять, как они отображают toolbar в действии выбора пользователя end . Похоже, это вопрос наблюдается наблюдатель через zena observ.

1
Game T. S. 3 Мар 2018 в 18:24

Один из способов заставить его работать - отслеживать событие selectionchange, и когда выбор не меняется более 500 мс, я считаю, что выбор завершен. Он не идеален, но он работает и корректно срабатывает для любого типа выделения, будь то мышь, клавиатура или CTRL + F.

    let selectionDelay = null, selection = '';

    document.addEventListener('selectionchange', () => {
        const currentSelection = document.getSelection().toString();
        if (currentSelection != selection) {
            selection = currentSelection;
            if (selectionDelay) {
                window.clearTimeout(selectionDelay);
            }
            selectionDelay = window.setTimeout(() => {
                wrapSelection();
                selection = '';
                selectionDelay = null;
            }, 500);
        }
    });
0
IceMetalPunk 24 Май 2019 в 04:46

Это сложнее, чем должно быть. Я использовал комбинацию element.onselectstart, element.onmouseup и document.onselectionchange. Посмотрите на эту демонстрационную версию.

function onSelect(element, callback) {
    // console.log(element, callback);
    let isSelecting = false;
    let selection = null;

    function handleSelectStart(event) {
        // console.log(event);
        isSelecting = true; 
    }

    function handleMouseUp(event) {
        // console.log(event, isSelecting);
        if (isSelecting && !document.getSelection().isCollapsed) {
            callback((selection = document.getSelection()));
            isSelecting = false;
        }
    }

    function handleSelectionChange(event) {
        // console.log('change', isSelecting);
        if (document.getSelection().isCollapsed && null !== selection) {
            callback((selection = null));
        }
    }

    element.addEventListener('selectstart', handleSelectStart);
    element.addEventListener('mouseup', handleMouseUp);
    document.addEventListener('selectionchange', handleSelectionChange);

    return function destroy() {
        element.removeEventListener('selectstart', handleSelectStart);
        element.removeEventListener('mouseup', handleMouseUp);
        document.removeEventListener('selectionchange', handleSelectionChange);
    };
}

Это не будет обрабатывать взаимодействия без мыши. Приспособление событий указателя и клавиатуры было бы хорошим улучшением. Я думаю, что общая картина сохраняется, хотя.

0
Justin Makeig 9 Дек 2019 в 16:54

Более простая альтернатива принятому ответу.

 document.addEventListener('mouseup', e => {
     var s = document.getSelection();
     if (!s.isCollapsed) {
          // do sth with selection
     }
 });

А может лучше?

 document.addEventListener('selectstart', e => {
     document.addEventListener('mouseup', somefunction);
 });
 function somefunction(e) {
     // do sth
     document.removeEventListener('mouseup', somefunction);
 }
0
chuan 17 Фев 2019 в 20:03