ColorPicker material-ui-颜色,鼠标弹起时设置颜色

ColorPicker material-ui-color, set color on mouse up

我正在使用 material-ui-color 中的 ColorPicker,我在设置值 onChange 时遇到问题。

问题是,当我开始在 ColorPicker 中拖动鼠标时,它会不断调用 onChange。 我希望当我停止拖动鼠标时它会调用 onChange.

关于如何实现预期结果的任何想法? Link to CodeSandBox

尝试在 ColorPicker 中添加 deferred 属性。当 deferred 设置为 true 时,更改处理程序仅在您单击 SET 按钮提交更改时触发:

<ColorPicker value={color} onChange={handleChange} deferred />

编辑:如果你真的很想听mouseup事件,你需要使用纯JS做一些肮脏的工作:

function MyColorPicker({ onChange }) {
  const [open, setOpen] = useState(false);
  const [, forceRender] = useReducer((x) => ++x, 0);
  const colorRef = useRef<Color>();
  const handleChange = (newValue: Color) => {
    colorRef.current = newValue;
    forceRender();
  };

  React.useEffect(() => {
    let colorGradientEl = null;
    let hueSliderEl = null;
    let alphaSliderEl = null;
    let inputEls = [];
    const handleMouseUp = () => onChange(colorRef.current);

    if (open) {
      setTimeout(() => {
        colorGradientEl = document.querySelector(
          '[data-testid="hsvgradient-color"]'
        );
        hueSliderEl = document.querySelector('[data-testid="hueslider"]');
        alphaSliderEl = document.querySelector('[data-testid="alphaslider"]');
        inputEls = [...document.querySelectorAll("input")];
        const colorPickerPopoverEl = document.querySelector(
          ".ColorPicker-MuiPopover-root"
        );

        const observer = new MutationObserver((mutations) => {
          mutations.forEach((mutation) => {
            if (mutation.removedNodes) {
              setOpen(false);
            }
            observer.disconnect();
          });
        });

        observer.observe(colorPickerPopoverEl!, { childList: true });
        colorGradientEl?.addEventListener("mouseup", handleMouseUp);
        hueSliderEl?.addEventListener("mouseup", handleMouseUp);
        alphaSliderEl?.addEventListener("mouseup", handleMouseUp);

        inputEls.forEach((el) => {
          el.addEventListener("change", handleMouseUp);
        });
      }, 10);
    }

    return () => {
      colorGradientEl?.removeEventListener("mouseup", handleMouseUp);
      hueSliderEl?.removeEventListener("mouseup", handleMouseUp);
      alphaSliderEl?.removeEventListener("mouseup", handleMouseUp);

      inputEls.forEach((el) => {
        el.removeEventListener("change", handleMouseUp);
      });
    };
  }, [open]);

  return (
    <ColorPicker
      onOpen={() => setOpen(true)}
      value={colorRef.current}
      onChange={handleChange}
    />
  );
}

用法

MyColorPicker 现在仅在用户停止拖动鼠标时触发 change 处理程序:

<MyColorPicker onChange={handleChange} />

useEffect 的帮助下,我们可以在用户停止拖动鼠标后的某个时间(在本例中为 0.2 秒后)执行实际的 setState 或本例中的 console.log(color)在 colorPicker 中或在不透明度中移动滑块等

useEffect(() => {
    const timeoutId = setTimeout(
      () => {
        if (color != null) {
          //Do your things
          console.log(color);
        }
      },

      200
    );
    return () => clearTimeout(timeoutId);
  }, [color]);

CodeSandbox