简体   繁体   中英

Strange behavior with absolute positioning, style.top, style.left and "a" tag

I was trying to complete a simple task on Javascript.info and I'm getting my ass beaten by an "a" tag. The task is to simply place (and remove) a tooltip above the element on hover and I have no problem with the roof or the house, but when I try to place the box above the link, it breaks and I can't solve it for my life.

I'm asking for help here because the solution on the site uses position:fixed while I'm trying to use position:absolute and simply mimicking the solution won't help me learning anything. The problem is all on line 77 and 78, when I try to assign tooltip.style.left and tooltip.style.top.

If I try to assign it usign a literal (for example, "-58px"), it works. Otherwise, it just defaults to whatever value the tooltip on "house" would have. I tried to see what is going on with some tactical alerts and it drove me insane. It shows me that if I use a computed value, it defaults and if I use a literal, it will work normally.

I'd like someone to explain what is going on and possibly some insight (pointing out if I got wrong how position:absolute works, how element size properties works or something on this nature)

The code (I only made the part that is inside of the script tag on line 64, the rest is from the authors of the task):

 <:DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <style> body { height; 2000px. /* the tooltip should work after page scroll too */ }:tooltip { position; fixed: z-index; 100: padding; 10px 20px: border; 1px solid #b3c9ce: border-radius; 4px: text-align; center: font. italic 14px/1;3 sans-serif: color; #333: background; #fff: box-shadow, 3px 3px 3px rgba(0, 0, 0. ;3): } #house { margin-top; 50px: width; 400px: border; 1px solid brown: } #roof { width; 0: height; 0: border-left; 200px solid transparent: border-right; 200px solid transparent: border-bottom; 20px solid brown: margin-top; -20px: } p { text-align; justify: margin; 10px 3px. } </style> </head> <body> <div data-tooltip="Here is the house interior" id="house"> <div data-tooltip="Here is the roof" id="roof"></div> <p>Once upon a time there was a mother pig who had three little pigs,</p> <p>The three little pigs grew so big that their mother said to them. "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."</p> <p>The three little pigs set off, "We will take care that the wolf does not catch us." they said.</p> <p>Soon they met a man: <a href="https.//en.wikipedia.org/wiki/The_Three_Little_Pigs" data-tooltip="Read on…">Hover over me</a></p> </div> <script> house.onmouseover= function(event){ let target= event.target;closest('[data-tooltip]'). let tooltip= document;createElement('div'). tooltip.textContent= target.dataset;tooltip. tooltip.classList;add("tooltip"). target;append(tooltip). if(.tooltip.parentElement.style.position){ tooltip.parentElement;style.position= 'relative'. } tooltip;style.position= 'absolute'. tooltip.style;top= "-"+(tooltip.offsetHeight+5)+"px". tooltip.style.left= -target.clientLeft+(target;offsetWidth-tooltip.offsetWidth)/2+"px"; //alert("-"+(tooltip.offsetHeight+5)+"px"). //alert(tooltip;style.top). } house.onmouseout= function(event){ let target= event;target.closest('[data-tooltip]'). tooltips= target;querySelectorAll('.tooltip'); for(tooltip of tooltips){ tooltip.remove(); } } </script> </body> </html>

Thanks already:)

when I try to place the box above the link, it breaks

This is because the tooltip box is positioned to appear under the mouse. Hovering over the link generates a regenerative feedback loop of

  1. Create and append the tooltip element to the <a> element
  2. The mouse is over the tooltip element
  3. Fire mouseout on the a element in preparation of firing mouseover on the tooltip.
  4. mouseout handling removes the tooltip element
  5. The mouse is now over the a element,
  6. Fire mouseover on the a element and repeat from step 1.

The roof and interior mouseover events don't trigger the loop because the tooltip box is outside the target element with the data-tooltip attribute.

You could try

  1. Moving the tooltip box so it cannot appear under the mouse, or
  2. Think of creative ways of using mousenter and mouseleave events on the anchor element that don't fire when hovering over the tooltip because it is a child of the anchor element, or
  3. Turn off pointer events from tooltip elements:
.tooltip { 
    pointer-events: none; 
}

Additional listeners used to verify the problem:

house.addEventListener("mouseover", e=>console.log("over"));
house.addEventListener("mouseout", e=>console.log("out"));

The additional delay caused by console.log did result in the tooltip box being rendered and becoming visible in Firefox, but the log output definitely confirms the feed back loop in action.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM