我无法理解为什么我的代码中的单击会选择文本

xor*_*xor 8 html javascript css

我正在尝试创建一个小菜单,当您单击它时会打开,当您在外部单击时会关闭.我设法做到了,主要是.我按下打开菜单的按钮有一些填充,当我专门点击填充时,打开的菜单会选择所有文本,这很奇怪,我不明白为什么会发生这种情况.我查看了MDN的文档,我最喜欢的搜索引擎和IRC(freenode)的解决方案,但到目前为止还没有运气.

我做了一个最小的工作示例,我链接到底部,我添加了一些注释,可以评论一些行来改变行为.简单地说,你可以按蓝色方块,字母'a'将显示为选中,预期的行为是字母'a'应该显示,但未选中.如果您了解发生了什么,请告诉我.^ _ ^

编辑:我看到一些关于不同浏览器的不同结果的讨论.我目前在Linux上使用64位的Firefox 59.0.1(Fedora 27).有人建议这可能是一个错误,我无法排除这一点.

https://jsfiddle.net/16k672tt/4/

function outside_function(event) {
    var outside = event.target;
    outside.classList.remove("outside");
    var menu_list = document.getElementById("menu-list");
    menu_list.classList.remove("menu-list-open");
    event.stopPropagation();
  }
  var outside = document.getElementById("outside");
  outside.addEventListener("click", outside_function);

  function menu_click_event(event) {
    var menu_list = document.getElementById("menu-list");
    var outside = document.getElementById("outside");
    menu_list.classList.add("menu-list-open");
    outside.classList.add("outside");
    event.stopPropagation();
  }
  var menu = document.getElementById("menu");
  menu.addEventListener("click", menu_click_event);
Run Code Online (Sandbox Code Playgroud)
.menu {
  /* If you comment the next line, it renders the way I expect */
  display: flex;
  width: 2.5rem;
  height: 2.5rem;
  background-color: #0000ff80;
}

.outside {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

.menu-list {
  display: none;
}

.menu-list-open {
  display: block;
  /* If you comment the next line, it renders the way I expect */
  /* In fact if you decrease the alpha value to 0 it works as well (#ffffff00) */
  background-color: #ffffffc0;
}
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <div id="outside"></div>
    <div id="menu" class="menu">
      <div id="menu-list" class="menu-list">
        a
      </div>
    </div>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

xor*_*xor 0

我在 mozilla IRC 网络的 #servo 频道上与 emilio 进行了一些交谈。他建议鼠标按下事件在菜单元素上触发,鼠标向上事件在外部元素上触发。浏览器假定这是一个拖动动作,并选择其间的文本。问题似乎是鼠标按下事件被放置在事件队列中的单击事件之后。因此,即使事件传播停止,队列中已经存在另一个事件,即mouse up,该事件最终将瞄准新放置的外部元素。这可能是一个错误,所以我要去https://bugzilla.mozilla.org/看看是否是这种情况。

已经建议了一些解决方法,例如使用 CSS 的用户选择来使文本不可选择,以及使用 Javascript 的PreventDefault()来避免运行默认事件处理程序。其他 stackoverflow 用户提到了这些,但不幸的是被否决了,随后删除了他们的答案。无论如何,我将这些解决方法留在这里,供任何可能需要它们的人使用。

感谢所有帮助调查此问题的人。