简体   繁体   English

绝对定位、style.top、style.left 和“a”标签的奇怪行为

[英]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.我试图在 Javascript.info 上完成一个简单的任务,但我的屁股被一个“a”标签打败了。 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.任务是简单地在 hover 上的元素上方放置(并删除)一个工具提示,我对屋顶或房屋没有任何问题,但是当我尝试将框放在链接上方时,它会损坏并且我无法解决它为了我的生命。

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.我在这里寻求帮助,因为站点上的解决方案使用 position:fixed 而我正在尝试使用 position:absolute 并且简单地模仿解决方案不会帮助我学习任何东西。 The problem is all on line 77 and 78, when I try to assign tooltip.style.left and tooltip.style.top.当我尝试分配 tooltip.style.left 和 tooltip.style.top 时,问题都在第 77 行和第 78 行。

If I try to assign it usign a literal (for example, "-58px"), it works.如果我尝试为它分配一个文字(例如,“-58px”),它就可以工作。 Otherwise, it just defaults to whatever value the tooltip on "house" would have.否则,它只是默认为“house”上的工具提示将具有的任何值。 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)我希望有人解释正在发生的事情并可能有一些见解(指出如果我弄错了 position:absolute 的工作原理,元素大小属性的工作原理或这种性质的东西)

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):代码(我只制作了第 64 行脚本标记内的部分,rest 来自任务作者):

 <: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创建和 append 到<a>元素的工具提示元素
  2. The mouse is over the tooltip element鼠标在工具提示元素上
  3. Fire mouseout on the a element in preparation of firing mouseover on the tooltip.a元素上触发mouseout以准备在工具提示上触发mouseover
  4. mouseout handling removes the tooltip element mouseout处理删除工具提示元素
  5. The mouse is now over the a element,鼠标现在位于a元素上,
  6. Fire mouseover on the a element and repeat from step 1.a元素上mouseover并从步骤 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.屋顶和内部鼠标悬停事件不会触发循环,因为工具提示框位于具有data-tooltip属性的目标元素之外。

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想一想在锚元素上使用mousentermouseleave事件的创造性方法,这些事件在悬停在工具提示上时不会触发,因为它是锚元素的子元素,或者
  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.console.log引起的额外延迟确实导致工具提示框被渲染并在 Firefox 中可见,但日志 output 确实证实了反馈循环在起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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