简体   繁体   English

如果在上下文菜单事件中调用,则输入类型颜色单击事件将失败

[英]Input type color click event fails if called within contextmenu event

This is pretty tricky, so I'll try to explain it well.这很棘手,所以我会尽量解释清楚。

I have a web app where I want to allow my users to change background color of some divs.我有一个网络应用程序,我想允许我的用户更改某些 div 的背景颜色。 To do so I'd like to use a color picker interface, and I want to use contextmenu event on target divs to open it, as they already have another behaviour attached to click event.为此,我想使用颜色选择器界面,并且我想在目标 div 上使用contextmenu事件来打开它,因为它们已经有另一个附加到 click 事件的行为。

So the idea is to have an input type color hidden in the screen, attach its click event to contextmenu event on target divs and change background color of target divs on input type color change event.所以想法是在屏幕中隐藏输入类型颜色,将其单击事件附加到目标 div 上的contextmenu事件,并在输入类型颜色更改事件上更改目标 div 的背景颜色。

The funny thing is that when I try to chain events, color picker doesn't open if its click event is called from within contextmenu event handler, but it does if called from within click event.有趣的是,当我尝试链接事件时,如果从contextmenu事件处理程序中调用它的 click 事件,则颜色选择器不会打开,但如果从 click 事件中调用它就会打开。

Using jQuery for code simplicity and clearness:使用 jQuery 实现代码简单和清晰:

//this works perfectly, color picker opens
$("#myTargetDiv").on("click", function() {
    $("#inputTypeColor").trigger("click");
});

//this fails miserably
$("#myTargetDiv").on("contextmenu", function() {
    $("#inputTypeColor").trigger("click");
    return false;
});

The most weird fact is that, if I use a third element to pass the event, say, for example that I call to an intermediate input type text which passes the call from myTargetDiv to inputTypeControl , the click event in the intermediate element fires (even when called from within contextmenu event handler) while the event in the input type color doesn't fire.最奇怪的事实是,如果我使用第三个元素来传递事件,例如,我调用一个中间输入类型文本,该文本将调用从myTargetDivinputTypeControl ,则中间元素中的 click 事件会触发(甚至当从contextmenu事件处理程序中调用时),而输入类型颜色中的事件不会触发。

But if you click directly on the intermediate input type text the color picker opens!但是如果您直接单击中间输入类型文本,颜色选择器会打开!

//If you right click on myTargetDiv "firing!" appears on console, but color picker doesn't opens
$("#myTargetDiv").on("contextmenu", function() {
    $("#intermediateElement").trigger("click");
    return false;
});

//If you click on intermediateElement, however, the color picker opens!!!
$("#intermediateElement")on("click", function() {
    console.log("firing!");
    $("#inputTypeColor").trigger("click");
});

I've reproduced this behaviour in Firefox and Chrome, and I'm not very sure if it's an expected feature, a bug in browsers input type color implementation or a problem with event handling from jQuery (I haven't tried launching the events myself yet).我已经在 Firefox 和 Chrome 中重现了这种行为,我不太确定它是否是预期的功能、浏览器输入类型颜色实现中的错误或 jQuery 的事件处理问题(我还没有尝试自己启动事件然而)。

https://jsfiddle.net/bardobrave/0z6ev4rd/1 If you click on "FIRE!" https://jsfiddle.net/bardobrave/0z6ev4rd/1如果你点击“FIRE!” the color picker opens, but if you right click on it the color picker doesn't opens despite if you click on input type text it does.颜色选择器打开,但如果您右键单击它,尽管您单击输入类型文本,颜色选择器也不会打开。

Anyone can give some insight on the matter?任何人都可以就此事提供一些见解吗?

Ok, I've found a way to fix the functionality.好的,我找到了修复功能的方法。

To trigger color picker opening through a div context menu event.通过 div 上下文菜单事件触发颜色选择器打开。

As this event cannot call the input type color click event (for reason unknown), a feasible solution is to add a hidden div which pops on mouse position when context menu event is called on target div.由于此事件无法调用输入类型颜色点击事件(原因未知),一个可行的解决方案是添加一个隐藏的 div,当在目标 div 上调用上下文菜单事件时,该隐藏 div 会在鼠标位置弹出。

This hidden div poses as a context menu and can include a message: "click to open color picker" or something like that.这个隐藏的 div 作为一个上下文菜单,可以包含一条消息:“点击打开颜色选择器”或类似的东西。

Then, you attach color input click event to this hidden div click event.然后,您将颜色输入点击事件附加到这个隐藏的 div 点击事件。

Coming from another click event, the color picker opens correctly, you've forced your user to make one click more than desired (one right click to open the fake context menu and another one to open de color picker), but functionality works in the end and it's quite consistent with the effect seeked.来自另一个点击事件,颜色选择器正确打开,你强迫你的用户多点击一次(一次右键打开假上下文菜单,另一次打开去颜色选择器),但功能在结束,它与所寻求的效果非常一致。

The real question still applies:真正的问题仍然适用:

Why input type color click event fires when called from within any other click event handler but fails if called from within context menu event handler?为什么从任何其他单击事件处理程序中调用输入类型颜色单击事件会触发,但如果从上下文菜单事件处理程序中调用则失败?

So to execute your own contextual menu, you may want to bind to the following:因此,要执行您自己的上下文菜单,您可能需要绑定到以下内容:

  $("#firestarter").on("contextmenu", function(e) {
    // Execute your menu with Color Picker Option
    return false;
  });

This could be something simple like a List wrapped in a div, or more complex like JQuery UI Menu.这可以是简单的,比如包裹在 div 中的 List,或者更复杂的,比如 JQuery UI 菜单。

<div id="menu">
  <ul>
    <li class="menuItem" id="menuOption-1" data-action="color" data-rel="#myColor">Select Color</li>
    <li class="menuItem" id="menuOption-2" data-action="reset">Reset to Default</li>
  </ul>
</div>

Now the user has something to click on, which can be carried over:现在用户可以click一些东西,可以继续:

$("#menu li.menuItem").on("click", function(){
  switch($(this).data("action")){
    case "color":
      $("#menu").hide();
      var target = $(this).data("rel");
      $(target).trigger("click");
      break;
    case "reset":
      $("#menu").hide();
      // Do something else
      break;
    default:
      $("#menu").hide();
  }
});

I have not found all the details on the HTML5 input type='color' .我还没有找到关于 HTML5 input type='color'所有细节。 This is a good start: https://www.w3.org/TR/html5/forms.html#color-state-%28type=color%29 I suspect that since the Color Picker dialog is generated by the browser itself as well as a Contextual Menu, I am guessing it's a security or control feature that is preventing it being triggered by a Right-Click type of event.这是一个好的开始: https : //www.w3.org/TR/html5/forms.html#color-state-%28type=color%29我怀疑因为颜色选择器对话框也是由浏览器本身生成的作为上下文菜单,我猜它是一种安全或控制功能,可以防止它被右键单击类型的事件触发。

一些DOM事件需要以编程方式发射用户交互,,即你可以触发一个click只有在处理一些其他的过程编程clickkeyup等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM