当它不应该

时间:2017-10-06 00:21:52

标签: javascript html css

尝试创建一个将鼠标悬停在元素上时显示的弹出窗口。然而,当我将鼠标移动到元素内部时,它会闪烁并移动。如果鼠标移动到弹出窗口,它也应保持打开状态。 尝试这样做没有像jQuery这样的库作弊。你不知道你是否使用它们。

如果您将鼠标悬停在下面的某个标签上,那正是我试图创建的内容。

认为错误在此代码中的某处:

function showPopup(e) {
    var popup = document.getElementById('popup');
    if (popup.style.display == 'none') {
        popup.style.display = 'block';

var bodyRect = document.body.getBoundingClientRect(),
    elemRect = e.target.getBoundingClientRect(),
    offsetX   = elemRect.left - bodyRect.left,
    offsetY   = elemRect.bottom - bodyRect.top;
        popup.style.left = offsetX + 'px';
        popup.style.top = offsetY + 'px';
        //console.log(e);
    }
}

function hidePopup(/*e*/) {
    setTimeout(function() {
        var popup = document.getElementById('popup');
        if (popup.style.display == 'block' && !window.inside_popup) {
            popup.style.display = 'none';
            window.inside_popup = false;
            console.log('hide');
        } else {
            setTimeout(hidePopup, 50); // try a little later
        }
    }, 50); // Give the events ability to catch up and tell us the mouse is inside the popup
}

var targ = document.querySelector('ul li')
    targ.addEventListener('mouseover', showPopup);
    targ.addEventListener('mouseout', hidePopup);

带有真实测试元素的完整javascript代码: https://jsfiddle.net/g8wvae8o/

2 个答案:

答案 0 :(得分:0)

正如@epascarello所说,mouseleavemouseenter正是您所寻找的。这里也不需要setTimeout。此外,您定位页面上的每个li(这是故意的吗?)我建议定位特定类别的元素以减少闪烁。

这很接近,但你需要按摩定位。

function createPopup() {
  var container = document.createElement('div');
  container.id = 'popup';
  container.style.width = '500px';
  container.style.height = '700px';
  container.style.display = 'none';
  container.style.position = 'absolute';
  container.style.borderRadius = '2px';
    container.style.border = '1px solid #242729';
    container.style.backgroundColor = '#535a60';
    container.style.color = '#e4e6e8';
    container.style.zIndex = '9999999';
  container.addEventListener('xmouseenter', function() {
    window.inside_popup = true;
    //console.log('window.inside_popup = true;');
  });
  container.addEventListener('xmouseleave', function() {
    window.inside_popup = false;
    //console.log('window.inside_popup = false;');
  });
  container.appendChild(document.createTextNode('This is a test'));
  (document.body || document.documentElement).appendChild(container);
}
window.inside_popup = false;
createPopup();


function showPopup(e) {
  var popup = document.getElementById('popup');
  if (popup.style.display == 'none') {
    popup.style.display = 'block';
  }
}

function hidePopup(/*e*/) {
  console.log('hiding')
  popup.style.display = 'none';
  window.inside_popup = false;
}

var bodyRect = document.body.getBoundingClientRect()
function updatePopup(e) {
  var elemRect = e.target.getBoundingClientRect(),
      offsetY   = elemRect.bottom - bodyRect.top,
      offsetX   = elemRect.left - bodyRect.left;
    popup.style.left = (e.clientX + offsetX) + 'px';
    popup.style.top = offsetY + 'px';
}

var targ = document.querySelector('ul li')
  targ.addEventListener('mouseenter', showPopup);
  targ.addEventListener('mouseleave', hidePopup);
  targ.addEventListener('mousemove', updatePopup)

Fiddle

答案 1 :(得分:0)

这是一个纯CSS解决方案(我只使用JS来创建弹出元素)



window.addEventListener("load", function () {
	var els = document.querySelectorAll("li");
    els.forEach(el => {
    	var popup = document.createElement("div");
        popup.innerHTML = el.getAttribute("popup");
        popup.className = "popup";
        el.appendChild(popup);
    });
});

*[popup]:hover > .popup {
    border: 1px solid #fff;
    padding: 0.5em;
    width: 400px;
    height: auto
}

.popup {
    overflow: hidden;
    box-sizing: border-box;
    background-color: black;
    color: #ccc;
    border-radius: 3px;
    position: absolute;
    height: 0px;
}

li {
    margin: 2em 0
}

<ul>
    <li popup="Some more info about this product">Move the mouse here</li>
    <li popup="Some more info about the 2nd product">Some other product</li>
</ul>
&#13;
&#13;
&#13;

关键是弹出窗口是悬停元素的子元素,因此将鼠标移到弹出窗口仍然算作悬停元素。