React – How to interact with DOM?

How to interact with a HTML element in React?

Use useRef

  • Embed HTML content
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
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
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
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
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
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
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<!DOCTYPE html>
<html lang="en">
<body>
<div id="id-component-test"></div>
</body>
</html>
<!DOCTYPE html> <html lang="en"> <body> <div id="id-component-test"></div> </body> </html>
<!DOCTYPE html>
<html lang="en">

<body>
   <div id="id-component-test"></div>
</body>

</html>
  • React component
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import ReactDOM from 'react-dom'
const TestComponent = () => {
...
}
ReactDOM.render(<TestComponent />, document.getElementById('id-component-test'))
import ReactDOM from 'react-dom' const TestComponent = () => { ... } ReactDOM.render(<TestComponent />, document.getElementById('id-component-test'))
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
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
export const fetchHtmlUrl = async (htmlUrl: string) => { // htmlUrl = https://xxx.xx/abc.html
const { data } = await axios.get(htmlUrl)
return data
}
export const fetchHtmlUrl = async (htmlUrl: string) => { // htmlUrl = https://xxx.xx/abc.html const { data } = await axios.get(htmlUrl) return data }
export const fetchHtmlUrl = async (htmlUrl: string) => { // htmlUrl = https://xxx.xx/abc.html
  const { data } = await axios.get(htmlUrl)
  return data
}
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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
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
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
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 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;
}
...
}
// 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; } ... }
// 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?

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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;
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;
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
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const elements = document.querySelectorAll(
'div[class*="contain-a-class"]'
)
const elements = document.querySelectorAll( 'div[class*="contain-a-class"]' )
  const elements = document.querySelectorAll(
    'div[class*="contain-a-class"]'
  )

Be the first to comment

Leave a Reply

Your email address will not be published.


*