【问题标题】:How should Selection selectfinish/selectend event be implemented?Selection selectfinish/selectend事件应该如何实现?
【发布时间】:2018-08-10 02:54:28
【问题描述】:

每当用户完成选择时(我认为基本上是在每个selectstart 事件之后的第一个mouseup 事件上,我想),我都希望做一些事情。我想采用该选择并将其包装在要通过 CSS 设置样式的元素中。我认为 Selection API 为此提供了一个事件;但是,它似乎没有。

我不只是听mouseup,因为我特别希望它能够与浏览器的查找功能产生的选择一起使用(“在此页面中查找...”;+f).

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                                                                                                                                                                                                        */

【问题讨论】:

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


    【解决方案1】:

    One way that I've gotten it to work is to track the selectionchange event and when the selection doesn't change for over 500ms, I consider that a select end.它并不完美,但它可以正常工作并正确触发任何类型的选择,无论是鼠标、键盘还是 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】:

      我挑选了hypothes.is 网络注释客户端的source code,以了解他们如何让toolbar 出现在用户选择操作结束上。这似乎是employing an observer 通过zen-observable 的问题。

      【讨论】:

      • 他们的解决方案是最好的/最简单的/唯一的吗?如果是这样,它究竟是如何工作的,是否设置好;如果没有,还有什么?
      【解决方案3】:

      这比它应该的要复杂。我使用了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);
          };
      }
      

      这不会处理非鼠标交互。容纳指针和键盘事件将是一个很好的增强。不过,我认为总体模式是成立的。

      【讨论】:

        【解决方案4】:

        接受答案的更简单的替代方案。

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

        【讨论】:

        • 如果在不使用鼠标的情况下进行选择,例如,当用户使用 Find 时会怎样?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-10
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多