es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obtener un elemento creado por un script en React sin utilizar “ref”.

Tengo un botón de chat creado por un script (zendesk chat). Genera un iframe en la página con el ID “launcher”.
Estoy usando Nextjs e intento obtener este elemento, pero no puedo adjuntar una referencia ya que no tengo el código.
Estoy buscando en la web una solución y he intentado algo así (en el componente del pie de página porque está en todas las páginas y puedo averiguar en qué página estoy):

React.useLayoutEffect(() => {
    function checkElExist() {
      if (typeof document !== 'undefined') {
        const el = document.querySelector('#launcher');
        if (!isSingleVehiclePage) {
          console.log('NO ES PÁGINA DE VEHÍCULO', el);
          if (el) {
            el.classList.remove('inVehicle');
            el.classList.add('notInVehiclePage');
          }
        } else {
          console.log('EN PÁGINA DE VEHÍCULO', el);
          if (el) {
            el.classList.remove('notInVehiclePage');
            el.classList.add('inVehicle');
          }
        }
      }
    }
    window.addEventListener('load', checkElExist);
    return () => window.removeEventListener('load', checkElExist);
  }, [isSingleVehiclePage]);

No sé si es la solución correcta. Funciona más o menos, pero a veces el elemento es nulo, especialmente cuando accedo a esa página específica desde un enlace externo (no cuando navego por el sitio).
¿Es posible obtener este elemento? Mi objetivo es agregar/quitar una clase según las páginas específicas.

Gracias

EDIT: No sé si es relevante, pero en el HTML el iframe está fuera de mi div “_next”. En la imagen a continuación, he circulado el div “_next”, el div del pie de página (donde se ejecuta mi código useLayoutEffect) y el iframe que quiero obtener.

Estructura del código HTML

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Solución para acceder a un elemento iframe de botón de chat en Next.js

    Si tienes un botón de chat creado por un script (por ejemplo, Zendesk chat) que genera un elemento iframe en la página con el ID “launcher” y estás utilizando Next.js, pero no puedes adjuntar una referencia ya que no tienes el código, puedes usar document querySelector() para obtener el elemento.

    Aquí tienes una solución posible:

    React.useEffect(() => {
      function checkElExist() {
        let el = document.querySelector('#launcher');
        if (!el) {
          setTimeout(() => checkElExist(), 1000);
        } else {
          console.log(el);
          // Haz algo con el elemento, por ejemplo, añadir/eliminar una clase
          el.classList.add('miClase');
        }
      }
      checkElExist();
    }, []);
    

    Lo que hace este código es utilizar document.querySelector() para obtener el elemento “#launcher”. Si no se encuentra el elemento, esperará 1 segundo (utilizando setTimeout()) y volverá a comprobar. Si se encuentra el elemento, hará algo con él, por ejemplo, añadir una clase.

    Ten en cuenta que este código utiliza React.useEffect() en lugar de React.useLayoutEffect(). React.useEffect() es más adecuado para este caso de uso porque no bloquea el renderizado, a diferencia de React.useLayoutEffect().

    También ten en cuenta que si el iframe está fuera de la estructura DOM de tu componente React (como se indica en la pregunta editada), es posible que necesites esperar a que el iframe se cargue completamente antes de acceder a su contenido. En ese caso, puedes utilizar el evento “load” del iframe para esperar a que se cargue completamente antes de acceder a él.

    Por ejemplo:

    React.useEffect(() => {
      function checkElExist() {
        const iframe = document.querySelector('#launcher');
        if (iframe) {
          iframe.addEventListener('load', () => {
            console.log(iframe.contentDocument.querySelector('body'));
            // Haz algo con el contenido del iframe
          });
        }
      }
      checkElExist();
    }, []);
    

    Este código espera a que se cargue el iframe (utilizando el evento “load” del iframe) antes de acceder a su contenido (utilizando iframe.contentDocument.querySelector()). Ten en cuenta que esto solo funciona si el contenido del iframe se encuentra en el mismo dominio que la página principal. Si el contenido del iframe se encuentra en un dominio diferente, es posible que encuentres problemas de origen cruzado.

Comments are closed.