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]);
我正在使用 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]);