如何在 JavaScript 中防止双击时选择文本?

问题描述 投票:0回答:1

我正在使用 JavaScript 中的双击事件侦听器,以在用户双击某些文本元素时触发操作。但是,我还有另一个响应文本选择的事件侦听器,问题是当我双击时,两个事件都会被触发:选择文本,然后执行双击事件。

我尝试过使用

preventDefault()
,但它并没有停止文本选择。这是我的代码的简化版本:

document.addEventListener('dblclick', function() {
  const selection = window.getSelection();
  console.log(selection);

  if (selection.toString().length >= 0) {
    const range = selection.getRangeAt(0);
    const selectedNode = range.startContainer.parentNode;

    if (selectedNode.tagName === 'P' && selectedNode.hasAttribute('data-audio')) {
      const audioFile = selectedNode.getAttribute('data-audio');

      // Stop the current audio if it is playing
      if (currentAudio && !currentAudio.paused) {
        currentAudio.pause();
        currentAudio.currentTime = 0; // Reset to the beginning
      }

      // Play the new audio file
      playAudio(audioFile);
    }
  }
});

function playAudio(audioFile) {
 //script to play audio
}



const toolbar = document.getElementById('toolbar');
//this is also gets executed when double click selection occurs 
//it displays a floating menu bar
document.addEventListener('mouseup', function() {
  const selection = window.getSelection();
  if (selection.toString().length > 0) {
    const range = selection.getRangeAt(0);
    const rect = range.getBoundingClientRect();

    toolbar.style.top = `${rect.top - toolbar.offsetHeight}px`;
    toolbar.style.left = `${rect.left}px`;
    toolbar.style.display = 'block';
  } else {
    toolbar.style.display = 'none';
  }

});

如何阻止双击时触发文本选择?

我已经尝试过 event.preventDefault() 但没有成功。我还可以尝试哪些其他方法? 如果您需要我的 HTML,就是这样

<p class = "verse" data-audio="benMahmoud-01.mp3">this is the first audio</p>
<p class = "verse" data-audio="benMahmoud-02.mp3">this is the second audio</p>
<p class = "verse" data-audio="benMahmoud-03.mp3">this is the third audio</p>
javascript html mouseevent addeventlistener
1个回答
0
投票

dblclick
事件本质上会选择您双击的任何文本。由于您需要能够选择文本,因此使元素不可选择的 CSS 选项将不起作用。当您双击时,它会选择您双击的文本,然后在第二次单击后,当您的
mouseup
触发时,您将选择文本并运行
mouseup
事件逻辑。

要分离这两个事件,您可以在 mousedownmouseup 事件中添加进一步的逻辑,以跟踪鼠标是否在两个事件之间移动。只需将鼠标的 event.pageX 位置记录到全局变量即可。对每个事件重复并比较两者。如果没有匹配,表示在按下鼠标按钮和释放鼠标按钮事件期间文本插入符号移动并突出显示文本。在此条件下运行您想要在鼠标松开事件中触发的代码。

通过这种方法,无需担心双击期间突出显示的文本。

let downPageX = null;
let upPageX = null;

document.addEventListener('mousedown', function(e) {
  downPageX = e.pageX;
})

document.addEventListener('mouseup', function(e) {
  upPageX = e.pageX;
  if(downPageX !== upPageX){
    // run the logic for highlighted text here...
  }

function playAudio(audioFile) {
 //script to play audio
}

let downPageX = null;
let upPageX = null;

const toolbar = document.getElementById('toolbar');

document.addEventListener('mousedown', function(e) {
  downPageX = e.pageX;
  // BELOW CODE added for display ONLY NOT NEEDED
  if(toolbar.checkVisibility()){
    toolbar.querySelector('span').remove();
    toolbar.style.display = 'none';
  }
})

document.addEventListener('mouseup', function(e) {
  upPageX = e.pageX;
  if(downPageX !== upPageX){
    const selection = window.getSelection();

    if (selection.toString().length > 0) {
      const range = selection.getRangeAt(0);
      const rect = range.getBoundingClientRect();

      toolbar.style.top = `${rect.top - toolbar.offsetHeight}px`;
      toolbar.style.left = `${rect.left}px`;
      toolbar.style.display = 'block';
      // BELOW CODE added for display ONLY NOT NEEDED
      const span = document.createElement('span');
      toolbar.insertAdjacentHTML('beforeend', `<span> for selected text: <em>'${range}'</em></span>`);
      //-------------------------//
    } else {
      toolbar.style.display = 'none';
    }
  }

});

document.addEventListener('dblclick', function() {
  const selection = window.getSelection();
  if (selection.toString().length >= 0) {
    const range = selection.getRangeAt(0);
    const selectedNode = range.startContainer.parentNode;
    console.log(`we have double clicked on -> ${range} <- ... run double click logic now...`)
    //if (selectedNode.tagName === 'P' && selectedNode.hasAttribute('data-audio')) {
    //  const audioFile = selectedNode.getAttribute('data-audio');

      // Stop the current audio if it is playing
    //  if (currentAudio && !currentAudio.paused) {
    //    currentAudio.pause();
    //    currentAudio.currentTime = 0; // Reset to the beginning
    //  }

      // Play the new audio file
    //  playAudio(audioFile);
   // }
  }
});
#toolbar {
  display: none;
}
<p class="verse" data-audio="benMahmoud-01.mp3">this is the first audio</p>

<div id="toolbar">This is the tooltip</div>

© www.soinside.com 2019 - 2024. All rights reserved.