应如何选择selectfinish / selectend事件?

时间:2018-03-01 22:41:49

标签: javascript event-handling observable dom-events textselection

我希望在用户完成选择后,即在每次selectstart事件后的第一个mouseup事件中,我想在页面上做一些事情。我想采取这种选择并将其包装在一个通过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 个答案:

答案 0 :(得分:0)

替代已接受答案的简单方法。

 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);
 }

答案 1 :(得分:0)

使它起作用的一种方法是跟踪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);
        }
    });

答案 2 :(得分:0)

这比应该的要复杂。我使用了element.onselectstartelement.onmouseupdocument.onselectionchange的组合。看看这个demo

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);
    };
}

这不会处理非鼠标交互。容纳指针和键盘事件将是一个不错的增强。我认为总体格局仍然存在。