{"id":600,"date":"2023-08-13T05:40:08","date_gmt":"2023-08-13T02:40:08","guid":{"rendered":"https:\/\/shedov.top\/ru\/?p=600"},"modified":"2026-01-12T00:21:52","modified_gmt":"2026-01-11T21:21:52","slug":"animirovannoe-modalnoe-okno-v-react-s-ispolzovaniem-onanimationend","status":"publish","type":"post","link":"https:\/\/shedov.top\/ru\/animirovannoe-modalnoe-okno-v-react-s-ispolzovaniem-onanimationend\/","title":{"rendered":"\u0410\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0432 React \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u2014 onAnimationEnd"},"content":{"rendered":"\n\n<div class=\"blog_post_image_wrap\">\n<div class=\"blog_post_image blog_post_image_cover\"><a href=\"https:\/\/animated-modal-in-react.vercel.app\/\" target=\"_blank\" rel=\"noopener\"> <img decoding=\"async\" src=\"https:\/\/shedov.top\/wp-content\/images\/animated_modal_in_react_2.webp\" alt=\"\u0410\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0432 React \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c - onAnimationEnd\" \/> <\/a><\/div>\n<\/div>\n\n\n\n\n<p style=\"margin-top: 30px;\">\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435, \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u2013 onAnimationEnd, \u043a\u0430\u043a \u0438 \u0432 <a href=\"https:\/\/shedov.top\/ru\/animirovannoe-dropdown-menyu-v-react-s-ispolzovaniem-sobytiya-onanimationend\/\" target=\"_blank\" rel=\"noopener\">\u044d\u0442\u043e\u043c<\/a> \u0441\u043b\u0443\u0447\u0430\u0435. onAnimationEnd \u2013 \u044d\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u044f animationEnd, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f CSS-\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u0412 \u044d\u0442\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0438 \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u043e, \u043e\u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 DOM.<\/p>\n\n\n\n<p>&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-align-center\">App.jsx<\/h2>\n\n\n\n<pre class=\"wp-block-code lang-jsx line-numbers\"><code>import { useState } from \"react\";\nimport { Modal } from \".\/components\";\n\nfunction App() {\n\n  const &#91;showModal, setShowModal] = useState(false);\n\n  return (\n    &lt;div className=\"App\">\n      &lt;button\n        onClick={() => {\n          setShowModal(true);\n        }}\n      >\n        Open modal\n      &lt;\/button>\n      &lt;Modal\n        buttonShowModal={showModal}\n        setButtonShowModal={setShowModal} \/>\n    &lt;\/div>\n  );\n}\nexport default App;\n<\/code><\/pre>\n\n\n\n<p>&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-align-center\">Modal.jsx<\/h2>\n\n\n\n<pre class=\"wp-block-code lang-jsx line-numbers\"><code>import {\n  useState,\n  useEffect,\n  useRef\n} from \"react\";\nimport {\n  Horse,\n  Close\n} from \"..\/..\/components\";\n\nimport styles from \".\/Modal.module.css\";\n\nexport function Modal({\n  buttonShowModal,\n  setButtonShowModal\n}) {\n\n  const &#91;showModal, setShowModal] = useState(false);\n\n  useEffect(() => {\n    if (buttonShowModal) {\n      setShowModal(true);\n    }\n  }, &#91;buttonShowModal]);\n  \n  const &#91;fadeOut, setFadeOut] = useState(false);\n\n  \/\/ Click tracking outside the modal\n  const modalRef = useRef();\n  useEffect(() => {\n    if (modalRef.current) {\n      const handler = (e) => {\n        if (!modalRef.current.contains(e.target)) {\n          setFadeOut(true);\n        }\n      };\n      document.addEventListener(\"mousedown\", handler);\n      return () => {\n        document.removeEventListener(\"mousedown\", handler);\n      };\n    }\n  });\n\n  return (\n    &lt;>\n      {showModal &amp;&amp; (\n        &lt;div\n          className={\n            fadeOut\n              ? `${styles.modal_wrap} ${styles.modal_wrap__fade_out}`\n              : `${styles.modal_wrap}`\n          }\n          onAnimationEnd={(e) => {\n            if (e.animationName === styles.fadeOut) {\n              setFadeOut(false);\n            }\n          }}\n        >\n          &lt;div\n            ref={modalRef}\n            className={\n              fadeOut\n                ? `${styles.modal} ${styles.modal__fade_out}`\n                : `${styles.modal}`\n            }\n            onAnimationEnd={(e) => {\n              if (e.animationName === styles.fadeOut) {\n                setShowModal(false);\n                setFadeOut(false);\n                setButtonShowModal(false);\n              }\n            }}\n          >\n            &lt;Horse \/>\n            &lt;div\n              onClick={() => {\n                setFadeOut(true);\n                setButtonShowModal(false);\n              }}\n              className={styles.close_button}\n            >\n              &lt;Close \/>\n            &lt;\/div>\n          &lt;\/div>\n        &lt;\/div>\n      )}\n    &lt;\/>\n  );\n}\n<\/code><\/pre>\n\n\n\n<p>&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-text-align-center\">Modal.module.css<\/h2>\n\n\n\n<pre class=\"wp-block-code lang-css line-numbers\"><code>.modal_wrap {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  background: rgba(0, 0, 0, 0.069);\n  position: fixed;\n  width: 100%;\n  height: 100%;\n  animation: fadeInModalWrap 0.5s forwards;\n  opacity: 0;\n  left: 0;\n  top: 0;\n}\n\n.modal_wrap__fade_out {\n  animation: fadeOut 0.5s forwards;\n  opacity: 1;\n}\n\n@keyframes fadeInModalWrap {\n  from {\n    opacity: 0;\n  }\n\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes fadeOut {\n  from {\n    opacity: 1;\n  }\n\n  to {\n    opacity: 0;\n  }\n}\n\n.modal {\n  width: 100%;\n  max-width: 260px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  height: 250px;\n  border-radius: 5px;\n  position: relative;\n  animation: fadeInModal 0.8s forwards;\n  background-color: rgb(255, 255, 255);\n  margin-right: 15px;\n  margin-left: 15px;\n}\n\n.modal__fade_out {\n  animation: fadeOut 0.5s forwards;\n}\n\n@keyframes fadeInModal {\n  from {\n    opacity: 0;\n  }\n\n  to {\n    opacity: 1;\n  }\n}\n\n.close_button {\n  position: absolute;\n  right: 5px;\n  top: 5px;\n  border: 2px solid rgb(90, 90, 90);\n  cursor: pointer;\n  border-radius: 3px;\n}\n\n.close_icon {\n  fill: rgb(90, 90, 90);\n  width: 18px;\n  height: 18px;\n  transition: all 300ms ease;\n}\n\n.close_icon:hover {\n  transform: rotate(360deg);\n  transition: all 300ms ease;\n}<\/code><\/pre>\n\n\n\n<div class=\"blog_post_links_with_code\">\n<p><a style=\"color: var(--live_text_color);\" href=\"https:\/\/animated-modal-in-react.vercel.app\/\" target=\"_blank\" rel=\"noopener\">LIVE<\/a>&nbsp;&nbsp;&nbsp;<a href=\"https:\/\/github.com\/AndrewShedov\/animated-modal-in-react\" target=\"_blank\" rel=\"noopener\">GitHub<\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435, \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u2013 onAnimationEnd, \u043a\u0430\u043a \u0438 \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435. onAnimationEnd \u2013 \u044d\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u044f animationEnd, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f CSS-\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u0412 \u044d\u0442\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0438 \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0434\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u043e, \u043e\u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 DOM. &nbsp; App.jsx &nbsp; Modal.jsx &nbsp; Modal.module.css LIVE&nbsp;&nbsp;&nbsp;GitHub","protected":false},"author":1,"featured_media":604,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,4,15,18,16,10,17],"tags":[],"class_list":["post-600","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-css","category-js","category-modal","category-onanimationend","category-react","category-animation","category-animation-react"],"_links":{"self":[{"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/posts\/600","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/comments?post=600"}],"version-history":[{"count":48,"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/posts\/600\/revisions"}],"predecessor-version":[{"id":4369,"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/posts\/600\/revisions\/4369"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/media\/604"}],"wp:attachment":[{"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/media?parent=600"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/categories?post=600"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/shedov.top\/ru\/wp-json\/wp\/v2\/tags?post=600"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}