英文:
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(() => {
if (isOpen) {
ref.current?.close();
ref.current?.showModal();
document.body.classList.add("modal-open"); // prevent bg scroll
} else {
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>
);
};
and I'm generating it by clicking button which sets isOpen
to true
. How can I animate it?
答案1 {#1}
得分: 1
您可以制作一些漂亮的 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);
}
</code></pre>
<p>然后,您需要一些 JavaScript 来在触发时添加和移除 CSS 类。将以下代码添加到您的 Modal 组件中:</p>
<pre><code>export const Modal = ({ isOpen, children, onOutsideClick }: Props) => {
const ref = useRef<HTMLDialogElement>(null);
useEffect(() =&gt; {
if (isOpen) {
ref.current?.close();
ref.current?.showModal();
ref.current?.classList.add(&quot;show&quot;); // 添加 show 类
document.body.classList.add(&quot;modal-open&quot;);
} else {
ref.current?.classList.remove(&quot;show&quot;); // 移除 show 类
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;
);
};
<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
.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);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you'll need some JS to add and remove the css classes on trigger. Add this to your Modal component&lt;/p&gt;
&lt;pre tabindex=&quot;0&quot; style=&quot;color:#f8f8f2;background-color:#272822;&quot;&gt;&lt;code&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#66d9ef&quot;&gt;export&lt;/span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;Modal&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; ({ &lt;span style=&quot;color:#a6e22e&quot;&gt;isOpen&lt;/span&gt;, &lt;span style=&quot;color:#a6e22e&quot;&gt;children&lt;/span&gt;, &lt;span style=&quot;color:#a6e22e&quot;&gt;onOutsideClick&lt;/span&gt; }&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;Props&lt;/span&gt;) &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;gt&lt;/span&gt;; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;ref&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;useRef&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;lt&lt;/span&gt;;&lt;span style=&quot;color:#a6e22e&quot;&gt;HTMLDialogElement&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;gt&lt;/span&gt;;(&lt;span style=&quot;color:#66d9ef&quot;&gt;null&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;useEffect&lt;/span&gt;(() &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;gt&lt;/span&gt;; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#a6e22e&quot;&gt;isOpen&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;ref&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;current&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;ref&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;current&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;showModal&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;ref&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;current&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;classList&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;add&lt;/span&gt;(&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;&lt;span style=&quot;color:#a6e22e&quot;&gt;show&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;); &lt;span style=&quot;color:#75715e&quot;&gt;// Add show class
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;&lt;/span&gt; document.&lt;span style=&quot;color:#a6e22e&quot;&gt;body&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;classList&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;add&lt;/span&gt;(&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;&lt;span style=&quot;color:#a6e22e&quot;&gt;modal&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; } &lt;span style=&quot;color:#66d9ef&quot;&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;ref&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;current&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;classList&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;remove&lt;/span&gt;(&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;&lt;span style=&quot;color:#a6e22e&quot;&gt;show&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;); &lt;span style=&quot;color:#75715e&quot;&gt;// Remove show class
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color:#75715e&quot;&gt;&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;ref&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;current&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;?&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;close&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; document.&lt;span style=&quot;color:#a6e22e&quot;&gt;body&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;classList&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;remove&lt;/span&gt;(&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;&lt;span style=&quot;color:#a6e22e&quot;&gt;modal&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; }, [&lt;span style=&quot;color:#a6e22e&quot;&gt;isOpen&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;handleOutsideClick&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; (&lt;span style=&quot;color:#a6e22e&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;any&lt;/span&gt;) &lt;span style=&quot;color:#f92672&quot;&gt;=&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;gt&lt;/span&gt;; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;let&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;isHidden&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;e&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;target&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;hidden&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;if&lt;/span&gt; (&lt;span style=&quot;color:#f92672&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;isHidden&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;amp&lt;/span&gt;;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;amp&lt;/span&gt;; &lt;span style=&quot;color:#f92672&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;isClickInsideRectangle&lt;/span&gt;(&lt;span style=&quot;color:#a6e22e&quot;&gt;e&lt;/span&gt;, &lt;span style=&quot;color:#a6e22e&quot;&gt;ref&lt;/span&gt;.&lt;span style=&quot;color:#a6e22e&quot;&gt;current&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;!&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;onOutsideClick&lt;/span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;amp&lt;/span&gt;;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;amp&lt;/span&gt;; &lt;span style=&quot;color:#a6e22e&quot;&gt;onOutsideClick&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#66d9ef&quot;&gt;return&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;lt&lt;/span&gt;;&lt;span style=&quot;color:#a6e22e&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;className&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;&lt;span style=&quot;color:#a6e22e&quot;&gt;mw&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;modal&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;; &lt;span style=&quot;color:#a6e22e&quot;&gt;onClick&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;{&lt;span style=&quot;color:#a6e22e&quot;&gt;handleOutsideClick&lt;/span&gt;}&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;gt&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;lt&lt;/span&gt;;&lt;span style=&quot;color:#a6e22e&quot;&gt;dialog&lt;/span&gt; &lt;span style=&quot;color:#a6e22e&quot;&gt;className&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;;&lt;span style=&quot;color:#a6e22e&quot;&gt;mw&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;modal&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;dialog&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;quot&lt;/span&gt;; &lt;span style=&quot;color:#a6e22e&quot;&gt;ref&lt;/span&gt;&lt;span style=&quot;color:#f92672&quot;&gt;=&lt;/span&gt;{&lt;span style=&quot;color:#a6e22e&quot;&gt;ref&lt;/span&gt;}&lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;gt&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; {&lt;span style=&quot;color:#a6e22e&quot;&gt;children&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;lt&lt;/span&gt;;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;/dialog&amp;amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; &lt;span style=&quot;color:#f92672&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#a6e22e&quot;&gt;lt&lt;/span&gt;;&lt;span style=&quot;color:#960050;background-color:#1e0010&quot;&gt;/div&amp;amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt; );
&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;display:flex;&quot;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
</code></pre>
<p></code></pre></p>