单击按钮时使悬停的工具提示消失

Make hovered tooltip disappear when clicking button

我正在尝试为我的网站上需要它的任何内容创建一个工具提示,例如一个按钮,文本等。到目前为止,我有这样的东西:

https://jsfiddle.net/f06q3cLg/

.content {
  display: grid;
  width: 100vw;
  height: 100vh;
  place-content: center;
}

.content .parent {
  border: 1px red solid;
  padding: 10px;
  position: relative;
}

.content .parent:hover .tooltip-wrapper {
  animation: 0.1s fadeInTooltip;
  animation-fill-mode: forwards;
  animation-delay: 0.4s;
}

.content .parent:hover:before {
  animation: 0.1s fadeInTooltip;
  animation-fill-mode: forwards;
  animation-delay: 0.4s;
}

.content .parent:active .tooltip-wrapper {
  animation: 0.05s fadeOutTooltip;
  animation-fill-mode: forwards;
}

.content .parent:active:before {
  animation: 0.05s fadeOutTooltip;
  animation-fill-mode: forwards;
}

.content .parent:before {
  content: "";
  display: block;
  width: 0;
  height: 0;
  position: absolute;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
}

.content .parent .tooltip-wrapper {
  position: absolute;
  display: grid;
  left: 0;
  width: 300px;
  height: 100%;
  opacity: 0;
  pointer-events: none;
}

.content .parent .tooltip-wrapper.bottom {
  top: calc(100% + 8px);
}

.content .parent .tooltip-wrapper .tooltip {
  max-width: 300px;
  width: fit-content;
  padding: 8px;
  position: absolute;
  display: inline-block;
  background: blue;
  border-radius: 5px;
  padding: 8px;
  color: white;
  font-size: 11px;
  box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
  line-height: 1.3;
  text-align: left;
}


/* Keyframes */

@keyframes fadeInTooltip {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeOutTooltip {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
<div class="content">
  <div class="parent">
    Hover me
    <div class="tooltip-wrapper">
      <span class="tooltip">This is my tooltip</span>
    </div>
  </div>
</div>

因此,它工作得还不错。我的问题是,当我单击按钮时,我希望工具提示消失。现在它消失了,然后像悬停效果一样以 0.4s 延迟返回。理想情况下,只要我的鼠标仍在按钮上,工具提示就应该消失,但是当我将其移除并重新进入按钮时,工具提示应该会重新出现。

我不确定这是否可以通过纯 CSS 实现,但任何 JS 都可以。

问题是 :active 仅在鼠标按下时应用。

mdn: :active:

The :active CSS pseudo-class represents an element (such as a button) that is being activated by the user. When using a mouse, "activation" typically starts when the user presses down the primary mouse button.

您可以做的(如果您只想保留 CSS)是在 <div class="parent">:focus 上使用 tabindex="0" 而不是 :active .但是你需要验证这里使用 tabindex="0" 不会影响可用性。

Ideally the tooltip should disappear as long as my mouse is still on the button, but when I remove it and re-enters the button, then the tooltip should re-appear.

这也不适用于 :focus。我很确定这种行为只能通过 JS 实现。如果仅 CSS 可行,那可能是一个非常棘手的解决方案。

但是从用户的角度来看,这似乎违反直觉,点击后工具提示不会出现。

一个 JavaScript 解决方案可以满足您的需求,如下所示。 它是工具提示的简化版本,仅显示相关部分。 每个具有工具提示的元素都有一个属性 data-has-tooltip.

// event delegation for all mouse down event:
// this ensures that the code also works for elements that have been added to the DOM after that script was executed.
document.addEventListener('mousedown', (evt) => {
  // check if the mousedown happened in an element with a tooltip
  const element = evt.target.closest('[data-has-tooltip]');
  if (element) {
    // if the user already clicked on the element ignore the click
    if (!element.classList.contains('active')) {
      // add the active class to the element so that hover won't show the toolip
      element.classList.add('active');

      function removeActiveOnLeave() {
        // remove the active class
        element.classList.remove('active');

        // remove the mouseleave event listener again
        element.removeEventListener('mouseleave', removeActiveOnLeave)
      }

      // add an event listener for mouseleave to remove the active class
      element.addEventListener('mouseleave', removeActiveOnLeave)
    }
  }

});
.parent {
   display: inline-block;
   border: 1px solid red;
   padding: 0.5rem;
   margin: 0.5rem;
}

.tooltip-wrapper {
  display: none;
}

.parent:hover .tooltip-wrapper {
  display: block;
}

.parent.active:hover .tooltip-wrapper {
  display: none;
}
<div class="content">
  <div class="parent" data-has-tooltip>
    Hover me A
    <div class="tooltip-wrapper">
      <span class="tooltip">This is my tooltip A </span>
    </div>
  </div>
</div>

<div class="content">
  <div class="parent" data-has-tooltip>
    Hover me B
    <div class="tooltip-wrapper">
      <span class="tooltip">This is my tooltip B</span>
    </div>
  </div>
</div>

操纵'display'属性.

const parent = document.querySelector('.parent');
const toolTip = document.querySelector('.tooltip');

parent.addEventListener('click', () => {
if(toolTip.style.display !== 'none') {
    toolTip.style.display = 'none';
}else {
  toolTip.style.display = 'grid';
}
    
});

使用jQuery 3.4.1的解决方案:

$(".parent").click(function () {
    $(".tooltip-wrapper").css("display", "none");
});

该解决方案的唯一缺点是一旦您在同一会话中单击并 re-hover,SCSS :hover 将无法正常工作。

无需强调,如果您需要该功能,只需添加以下内容:

$(".parent").hover(function () {
    $(".tooltip-wrapper").css("display", "block");
});

在附加的片段中尝试一下:

$(".parent").click(function () {
    $(".tooltip-wrapper").css("display", "none");
});

$(".parent").hover(function () {
    $(".tooltip-wrapper").css("display", "block");
});
.content {
  display: grid;
  width: 100vw;
  height: 100vh;
  place-content: center;
}

.content .parent {
  border: 1px red solid;
  padding: 10px;
  position: relative;
}

.content .parent:hover .tooltip-wrapper {
  animation: 0.1s fadeInTooltip;
  animation-fill-mode: forwards;
  animation-delay: 0.4s;
}

.content .parent:hover:before {
  animation: 0.1s fadeInTooltip;
  animation-fill-mode: forwards;
  animation-delay: 0.4s;
}

.content .parent:active .tooltip-wrapper {
  animation: 0.05s fadeOutTooltip;
  animation-fill-mode: forwards;
}

.content .parent:active:before {
  animation: 0.05s fadeOutTooltip;
  animation-fill-mode: forwards;
}

.content .parent:before {
  content: "";
  display: block;
  width: 0;
  height: 0;
  position: absolute;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
}

.content .parent .tooltip-wrapper {
  position: absolute;
  display: grid;
  left: 0;
  width: 300px;
  height: 100%;
  opacity: 0;
  pointer-events: none;
}

.content .parent .tooltip-wrapper.bottom {
  top: calc(100% + 8px);
}

.content .parent .tooltip-wrapper .tooltip {
  max-width: 300px;
  width: fit-content;
  padding: 8px;
  position: absolute;
  display: inline-block;
  background: blue;
  border-radius: 5px;
  padding: 8px;
  color: white;
  font-size: 11px;
  box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
  line-height: 1.3;
  text-align: left;
}


/* Keyframes */

@keyframes fadeInTooltip {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeOutTooltip {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="content">
  <div class="parent">
    Hover me
    <div class="tooltip-wrapper">
      <span class="tooltip">This is my tooltip</span>
    </div>
  </div>
</div>

或者,您可以看到它在这个 Fiddle. 中与您的初始 SCSS.

您可以取消对第二个函数的注释,以便在单击后再次看到悬停功能。

HTML

<div class="content">
   <div class="parent" onClick="myFunction()">
      Hover me
      <div class="tooltip-wrapper">
       <span class="tooltip" id="tooltip">This is mytooltip</span>
      </div>
   </div>
</div>

Javascript

function myFunction(){
  var tooltip=document.getElementById("tooltip");
  if (tooltip.style.display=="none") {        
 document.getElementById("tooltip").style.display="block";
  } else {
  document.getElementById("tooltip").style.display="none";
  }
}