Estoy trabajando en un proyecto de hobby similar a markup.io donde puedes cargar cualquier sitio web y anotarlo. No sé cómo agregar una anotación que se comporte como lo hace en markup.io:
Por lo que puedo ver, colocan un div de posición absoluta dentro del elemento en el que hizo clic. Según tengo entendido, al leer los documentos , div se posicionaría en función del antepasado posicionado más cercano. ¿Cómo calcularía los valores superior e izquierdo correctos para colocar la anotación donde el usuario hizo clic? ¿Hay una mejor manera de hacer esto?
Estoy usando React si eso importa.
Cosas que he probado:
<div style="width:0px; height:0px; position:relative;"> <div style="width:50px;height:50px;position:absolute; ">this is the annotation </div> </div>Problema: esto afectaría el diseño de la página debido a que el flujo del documento no ignora el div de posición relativa.
Problema: cada vez que el usuario se desplaza o cambia el tamaño de la ventana, la anotación debe volver a dibujarse en la nueva posición del elemento. Utilicé getBoundintClientRect para obtener la nueva posición y esto provocaría un reflujo y provocaría que todo el sitio web tuviera graves problemas de rendimiento al tratar con más de 100 anotaciones.
¡Ojalá alguien me pueda señalar en la dirección correcta!
La idea general es la siguiente:
// In my case I put the webpage in an Iframe. If this is your own page // you can just use document. iframe.contentWindow.document.addEventListener( 'click', (e: MouseEvent) => { // step 1: find the parent. let parent = e.target.parentElement; let computedStyle = window.getComputedStyle(parent); // step 2 & 3: Look up the first positioned element and make this the // the element that you're going to append your badge/annotation to. while ( computedStyle.position === 'static' && parent.parentElement !== null ) { parent = parent.parentElement; computedStyle = window.getComputedStyle(parent); } // style the annotation the way you want to const badge = document.createElement('div'); const { top, left } = parent.getBoundingClientRect(); badge.style.position = 'absolute'; // step 4 and 5 get the mouse position through e.clientX and Y and // subtract the appropriate value like below to place it exactly at the mouse position badge.style.top = `${e.clientY - top - 5}px`; badge.style.left = `${e.clientX - left - 5}px`; badge.style.backgroundColor = 'red'; badge.style.width = '10px'; badge.style.height = '10px'; badge.style.borderRadius = '50%'; badge.style.zIndex = '9999'; parent.appendChild(badge); } );