英文:
How to add animation to Modal (ReactJS)
问题 {#heading}
我有以下的ReactJS模态对话框,并且通过点击按钮来生成它,将isOpen
设置为true
。如何为它添加动画效果?
如需进一步的帮助,请提出具体的问题。 英文:
I have the following Modal in ReactJS
const isClickInsideRectangle = (e: MouseEvent, element: HTMLElement) => {
if (!element) return;
const r = element.getBoundingClientRect();
let isInside =
e.clientX > r.left &&
e.clientX < r.right &&
e.clientY > r.top &&
e.clientY < r.bottom;
return isInside;
};
export const Modal = ({ isOpen, children, onOutsideClick }: Props) =\> {
const ref = useRef\<HTMLDialogElement\>(null);
useEffect(() =&gt; {
if (isOpen) {
ref.current?.close();
ref.current?.showModal();
document.body.classList.add(&quot;modal-open&quot;); // prevent bg scroll
} else {
ref.current?.close();
document.body.classList.remove(&quot;modal-open&quot;);
}
}, [isOpen]);
const handleOutsideClick = (e: any) =&gt; {
let isHidden = e.target.hidden;
if (!isHidden &amp;&amp; !isClickInsideRectangle(e, ref.current!)) {
onOutsideClick &amp;&amp; onOutsideClick();
}
};
return (
&lt;div className=&quot;mw-modal&quot; onClick={handleOutsideClick}&gt;
&lt;dialog className=&quot;mw-modal--dialog&quot; ref={ref}&gt;
{children}
&lt;/dialog&gt;
&lt;/div&gt;
);
`};
`
and I'm generating it by clicking button which sets isOpen
to true
. How can I animate it?
答案1 {#1}
得分: 1
您可以制作一些漂亮的 CSS 动画。这里有一个简单且不太复杂的示例:
将这些类添加到您的 CSS 文件中:
```css
.mw-modal--dialog {
opacity: 0;
transform: translateY(-10%);
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}
.mw-modal--dialog.show {
opacity: 1;
transform: translateY(0);
}
然后,您需要一些 JavaScript 来在触发时添加和移除 CSS 类。将以下代码添加到您的 Modal 组件中:
export const Modal = ({ isOpen, children, onOutsideClick }: Props) => {
const ref = useRef<HTMLDialogElement>(null);
useEffect(() => {
if (isOpen) {
ref.current?.close();
ref.current?.showModal();
ref.current?.classList.add("show"); // 添加 show 类
document.body.classList.add("modal-open");
} else {
ref.current?.classList.remove("show"); // 移除 show 类
ref.current?.close();
document.body.classList.remove("modal-open");
}
}, [isOpen]);
const handleOutsideClick = (e: any) => {
let isHidden = e.target.hidden;
if (!isHidden && !isClickInsideRectangle(e, ref.current!)) {
onOutsideClick && onOutsideClick();
}
};
return (
<div className="mw-modal" onClick={handleOutsideClick}>
<dialog className="mw-modal--dialog" ref={ref}>
{children}
</dialog>
</div>
);
};
<details>
<summary>英文:</summary>
You can do some neat css animations. Here is something easy and not too complex:
Add these classes to your css file
```css
.mw-modal--dialog {
opacity: 0;
transform: translateY(-10%);
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}
.mw-modal--dialog.show {
opacity: 1;
transform: translateY(0);
}
</code></pre>
<p>Then you'll need some JS to add and remove the css classes on trigger. Add this to your Modal component</p>
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;"><code><span style="display:flex;"><span><span style="color:#66d9ef">export</span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">Modal</span> <span style="color:#f92672">=</span> ({ <span style="color:#a6e22e">isOpen</span>, <span style="color:#a6e22e">children</span>, <span style="color:#a6e22e">onOutsideClick</span> }<span style="color:#f92672">:</span> <span style="color:#a6e22e">Props</span>) <span style="color:#f92672">=&</span><span style="color:#a6e22e">gt</span>; {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">ref</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">useRef</span><span style="color:#f92672">&</span><span style="color:#a6e22e">lt</span>;<span style="color:#a6e22e">HTMLDialogElement</span><span style="color:#f92672">&</span><span style="color:#a6e22e">gt</span>;(<span style="color:#66d9ef">null</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">useEffect</span>(() <span style="color:#f92672">=&</span><span style="color:#a6e22e">gt</span>; {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">isOpen</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ref</span>.<span style="color:#a6e22e">current</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">close</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ref</span>.<span style="color:#a6e22e">current</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">showModal</span>();
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ref</span>.<span style="color:#a6e22e">current</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">classList</span>.<span style="color:#a6e22e">add</span>(<span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>;<span style="color:#a6e22e">show</span><span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>;); <span style="color:#75715e">// Add show class
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> document.<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">classList</span>.<span style="color:#a6e22e">add</span>(<span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>;<span style="color:#a6e22e">modal</span><span style="color:#f92672">-</span><span style="color:#a6e22e">open</span><span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>;);
</span></span><span style="display:flex;"><span> } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">ref</span>.<span style="color:#a6e22e">current</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">classList</span>.<span style="color:#a6e22e">remove</span>(<span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>;<span style="color:#a6e22e">show</span><span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>;); <span style="color:#75715e">// Remove show class
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">ref</span>.<span style="color:#a6e22e">current</span><span style="color:#f92672">?</span>.<span style="color:#a6e22e">close</span>();
</span></span><span style="display:flex;"><span> document.<span style="color:#a6e22e">body</span>.<span style="color:#a6e22e">classList</span>.<span style="color:#a6e22e">remove</span>(<span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>;<span style="color:#a6e22e">modal</span><span style="color:#f92672">-</span><span style="color:#a6e22e">open</span><span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>;);
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }, [<span style="color:#a6e22e">isOpen</span>]);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">handleOutsideClick</span> <span style="color:#f92672">=</span> (<span style="color:#a6e22e">e</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">any</span>) <span style="color:#f92672">=&</span><span style="color:#a6e22e">gt</span>; {
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">let</span> <span style="color:#a6e22e">isHidden</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">e</span>.<span style="color:#a6e22e">target</span>.<span style="color:#a6e22e">hidden</span>;
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">if</span> (<span style="color:#f92672">!</span><span style="color:#a6e22e">isHidden</span> <span style="color:#f92672">&</span><span style="color:#a6e22e">amp</span>;<span style="color:#f92672">&</span><span style="color:#a6e22e">amp</span>; <span style="color:#f92672">!</span><span style="color:#a6e22e">isClickInsideRectangle</span>(<span style="color:#a6e22e">e</span>, <span style="color:#a6e22e">ref</span>.<span style="color:#a6e22e">current</span><span style="color:#f92672">!</span>)) {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">onOutsideClick</span> <span style="color:#f92672">&</span><span style="color:#a6e22e">amp</span>;<span style="color:#f92672">&</span><span style="color:#a6e22e">amp</span>; <span style="color:#a6e22e">onOutsideClick</span>();
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> };
</span></span><span style="display:flex;"><span> <span style="color:#66d9ef">return</span> (
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&</span><span style="color:#a6e22e">lt</span>;<span style="color:#a6e22e">div</span> <span style="color:#a6e22e">className</span><span style="color:#f92672">=&</span><span style="color:#a6e22e">quot</span>;<span style="color:#a6e22e">mw</span><span style="color:#f92672">-</span><span style="color:#a6e22e">modal</span><span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>; <span style="color:#a6e22e">onClick</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">handleOutsideClick</span>}<span style="color:#f92672">&</span><span style="color:#a6e22e">gt</span>;
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&</span><span style="color:#a6e22e">lt</span>;<span style="color:#a6e22e">dialog</span> <span style="color:#a6e22e">className</span><span style="color:#f92672">=&</span><span style="color:#a6e22e">quot</span>;<span style="color:#a6e22e">mw</span><span style="color:#f92672">-</span><span style="color:#a6e22e">modal</span><span style="color:#f92672">--</span><span style="color:#a6e22e">dialog</span><span style="color:#f92672">&</span><span style="color:#a6e22e">quot</span>; <span style="color:#a6e22e">ref</span><span style="color:#f92672">=</span>{<span style="color:#a6e22e">ref</span>}<span style="color:#f92672">&</span><span style="color:#a6e22e">gt</span>;
</span></span><span style="display:flex;"><span> {<span style="color:#a6e22e">children</span>}
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&</span><span style="color:#a6e22e">lt</span>;<span style="color:#960050;background-color:#1e0010">/dialog&gt;</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&</span><span style="color:#a6e22e">lt</span>;<span style="color:#960050;background-color:#1e0010">/div&gt;</span>
</span></span><span style="display:flex;"><span> );
</span></span><span style="display:flex;"><span>};
</span></span></code></pre>
<p></p>
</div>
```