How to interact with a HTML element in React?
Use useRef
- Embed HTML content
import { useRef, useEffect } from 'react' const TestComponent = () => { const rootDiv = useRef(null) useEffect(() => { const root = rootDiv.current root.innerHTML = `<span>Hello</span>` }, []) return <div ref={rootDiv}></div> } export default TestComponent
- Focus an editable div element
import { useEffect, useRef, useState } from 'react' const Note = () => { const [isEditable, setEditable] = useState(false) const contentDiv = useRef(null) useEffect(() => { // After UI is updated if (isEditable) { const refContentDiv = contentDiv.current refContentDiv.focus() } }, [isEditable]) function onEditNote() { setEditable(true) // Schedule for UI update } function onSaveNote() { setEditable(false) // Schedule for UI update } return ( <> {isEditable ? ( <div onClick={onSaveNote}> Save Note </div> ) : ( <div onClick={onEditNote}> Edit Note </div> )} <div ref={contentDiv} contentEditable={isEditable} > Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusm od tempor incidi dunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation </div> </> ) } export default Note
How to render a React component into a DOM element?
- HTML file
<!DOCTYPE html> <html lang="en"> <body> <div id="id-component-test"></div> </body> </html>
- React component
import ReactDOM from 'react-dom' const TestComponent = () => { ... } ReactDOM.render(<TestComponent />, document.getElementById('id-component-test'))
How to style a component having content of an external HTML file (url)?
- Get html source code
export const fetchHtmlUrl = async (htmlUrl: string) => { // htmlUrl = https://xxx.xx/abc.html const { data } = await axios.get(htmlUrl) return data }
import { useRef, useEffect } from 'react' import { fetchHtmlUrl } from 'src/network/restful/restApi' import { useQuery } from 'react-query' import './index.scss' const TestComponent = ({ htmlUrl }) => { const { data, isLoading } = useQuery(['fetchHtmlUrl', htmlUrl], () => fetchHtmlUrl(htmlUrl) ) const rootDiv = useRef(null) useEffect(() => { if (!data) { return } const root = rootDiv.current root.innerHTML = data.trim() }, [data]) if (isLoading) { return null } return <div ref={rootDiv} className='test-component'></div> } export default TestComponent
- Create css file to style the page
// index.scss .test-component { line-height: 1.4em; color: #666; -webkit-font-smoothing: antialiased; h1, h2, h3, h4, h5, h6 { line-height: 1.4em; color: #666; } h1 { font-weight: 300; } ... }
How to render custom iframe in React?
const TestComponent = ({ }) => { //////////////////////////// // Define iframe reference const iframeRef = useRef(null); useEffect(() => { const iframe = iframeRef.current; let timer; if (!iframe) { return; } timer = setTimeout(() => { const win = iframe.contentWindow; //////////////////////////////////// // Communicate with iframe content win.addEventListener('message', (event) => { switch (event.data?.type) { case 'exitFullscreen': // do something; break; default: } }); ////////////////// // Inject style const doc = win.document; const { body } = doc; const style = doc.createElement('style'); style.innerHTML = ` html, body { width: 100%; height: 100%; } body { margin: 0; background: #000000; overflow: hidden; } ... @media only screen and (max-width: 629px) { .video-js:not(.vjs-has-started) .vjs-tech { opacity: 0.4!important; } }`; body.appendChild(style); ////////////////////////// // inject a HTML element const video = doc.createElement('video'); video.className = 'video-js vjs-fluid'; video.setAttribute('one-attribute', 'some-value'); body.appendChild(video); ////////////////////////// // inject script element const bcScript = doc.createElement('script'); bcScript.src = `https://xxxxx.xx/abcd.js`; bcScript.onload = () => { // do something ... }; body.appendChild(bcScript); }, 100); return () => { iframeRef.current = null; if (timer) { clearTimeout(timer); } }; }, []); return ( <iframe allowFullScreen={false} ref={iframeRef} /> ); }; export default TestComponent;
Useful DOM APIs
- Select all elements having a class name
- [id^=’someId’]: match all ids starting with someId
- [id$=’someId’]: match all ids ending with someId
- [id*=’someId’]: match all ids containing someId
const elements = document.querySelectorAll( 'div[class*="contain-a-class"]' )
Leave a Reply