.hover()和.append()追加多个元素

时间:2017-07-03 13:32:40

标签: javascript jquery html css

所以我得到了这段代码:

$(".l-definition").on({
  mouseenter : function() {
    var definition = $(".l-definition").attr('data-label');
    $(this).append("<div class='definition'>" + definition + "</div>");
    $(".definition").show(300);
  },
  mouseleave: function() {
    $(".definition").hide(300);
  }
});

使用jQuery在悬停上附加项目。

有时它会多次添加该项目,因为光标偶然会多次悬停元素,这会出现在.show().hide()的视觉错误中。

如何防止jQuery这样做呢?

这是一个片段:

$(function() {

  $(".l-definition").on({
    mouseenter: function() {
      var definition = $(".l-definition").attr('data-label');
      $(this).append("<div class='definition'>" + definition + "</div>");
      $(".definition").fadeIn(300);
    },
    mouseleave: function() {
      $(".definition").fadeOut(300);
    }
  });

});
p {
  margin-top: 100px;
}

.definition {
  display: none;
  padding: 5px 10px;
  border-radius: 5px;
  left: 50%;
  top: -70%;
  position: absolute;
  font-size: .8em;
  font-weight: 300;
  background-color: #ededed;
  -webkit-transform: translate(-50%, -100%);
  -moz-transform: translate(-50%, -100%);
  -ms-transform: translate(-50%, -100%);
  -o-transform: translate(-50%, -100%);
  transform: translate(-50%, -100%);
}

.definition::after {
  content: '';
  position: absolute;
  left: calc(50% - 10px);
  top: 100%;
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 10px solid #e8e8e8;
  clear: both;
}

.l-definition {
  font-weight: 600;
  cursor: pointer;
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Lorem ipsum dolor sit amet consetetur sadipscing <span class="l-definition" data-label="Chromium is a chemical element">Chromium</span></p>

6 个答案:

答案 0 :(得分:3)

如果您所做的只是显示工具提示,为什么不使用after伪选择器,那么您将不需要任何jquery。

我评论了下面的代码

p {
  margin-top: 100px;
}

.l-definition:after {
  content: attr(data-label);   /* use attr for text */
  padding: 5px 10px;
  border-radius: 5px;
  left: 50%;
  top: -10px;                  /* minus height of arrow */
  position: absolute;
  font-size: .8em;
  font-weight: 300;
  background-color: #ededed;
  opacity:0;                   /* opacity */
  transition: opacity 0.3s;    /* transition opacity over 300ms */
  pointer-events:none;         /* this is so you can mouse things under hidden tooltip */
  
  -webkit-transform: translate(-50%, -100%);
  -moz-transform: translate(-50%, -100%);
  -ms-transform: translate(-50%, -100%);
  -o-transform: translate(-50%, -100%);
  transform: translate(-50%, -100%);
}

.l-definition::before {
  content: '';
  position: absolute;
  left: calc(50% - 10px);
  bottom: 100%;
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 10px solid #e8e8e8;
  clear: both;
  transition: opacity 0.3s;
  pointer-events:none;
  opacity:0;
}

.l-definition:hover:after,    /* change opacity to 1 when hovered */
.l-definition:hover:before{
   opacity:1;
   pointer-events:auto;
}

.l-definition {
  font-weight: 600;
  cursor: pointer;
  position: relative;
}
<p>Lorem ipsum dolor sit amet consetetur sadipscing <span class="l-definition" data-label="Chromium is a chemical element">Chromium</span></p>

如果你想坚持使用jQuery,那么我会这样做:

$(".l-definition").each(function() {
  var label = $(this),
    definition = $('<div class="definition">' + label.data('label') + '</div>');  // cache these objects for better performance

  label.on({
    mouseenter: function() {
      label.append(definition.fadeIn(300));  // append definition and fade in
    },
    mouseleave: function() {
      definition.fadeOut(300, function() {  // fadeout definition and then remove once animation complete
         $(this).remove();            
      });
    }
  });
});
p {
  margin-top: 100px;
}

.definition {
  display: none;
  padding: 5px 10px;
  border-radius: 5px;
  left: 50%;
  top: -70%;
  position: absolute;
  font-size: .8em;
  font-weight: 300;
  background-color: #ededed;
  -webkit-transform: translate(-50%, -100%);
  -moz-transform: translate(-50%, -100%);
  -ms-transform: translate(-50%, -100%);
  -o-transform: translate(-50%, -100%);
  transform: translate(-50%, -100%);
}

.definition::after {
  content: '';
  position: absolute;
  left: calc(50% - 10px);
  top: 100%;
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 10px solid #e8e8e8;
  clear: both;
}

.l-definition {
  font-weight: 600;
  cursor: pointer;
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Lorem ipsum dolor sit amet consetetur sadipscing <span class="l-definition" data-label="Chromium is a chemical element">Chromium</span></p>

答案 1 :(得分:2)

您是否可以检查definition标记是否已存在,例如:

if ($(this).find('.definition').length<=0) 
    $(this).append("<div class='definition'>" + definition + "</div>");

还添加stop(true,true)以停止以前的动画。

$(".definition").stop(true,true).show(300);

我也修复了它,因此它适用于更多定义,因为您忘记使用$(this)并且所有定义都是在鼠标悬停/退出时触发的。!

演示修补:

$(".l-definition").on({
  mouseenter : function() {
    var definition = $(this).attr('data-label');
    if ($(this).find('.definition').length<=0)
        $(this).append("<div class='definition'>" + definition + "</div>");
    $(this).find(".definition").stop(true,true).show(300);
  },
  mouseleave: function() {
    $(this).find(".definition").hide(300);
  }
});
p{
margin-top:100px;
}
.definition{
	display:none;
	padding:5px 10px;
	border-radius:5px;
  left: 50%;
  top: -70%;
  position: absolute;
  font-size:.8em;
  font-weight:300;
  background-color: #ededed;
  -webkit-transform: translate(-50%, -100%);
  -moz-transform: translate(-50%, -100%);
  -ms-transform: translate(-50%, -100%);
  -o-transform: translate(-50%, -100%);
  transform: translate(-50%, -100%);
}
.definition::after{
	content: '';
  position: absolute;
  left: calc(50% - 10px);
  top: 100%;
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 10px solid #e8e8e8;
  clear: both;
}
.l-definition{
	font-weight: 600;
	cursor:pointer;
	position:relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>Lorem ipsum dolor sit amet consetetur sadipscing <span class="l-definition" data-label="Chromium is a chemical element">Chromium</span></p>
<span class="l-definition" data-label="You were creating duplicate definition, but never checked does it already exists (or remove before append).">What was wrong?</span>

答案 2 :(得分:2)

您确实希望维护事件发生的元素的 context ,否则您将始终获得第一个label并应用您的对所有这些元素的操作,如果你有多个具有相同类的元素。

因此,改变:

var definition = $(".l-definition").attr('data-label');

要:

var definition = $(this).data('label'); //also take advantage of the data method.

您也可以考虑更改:

$(".definition").....

致:

$(".definition", this).....

如果您不希望对所有现有的.definition元素进行操作。

答案 3 :(得分:1)

致电.stop()停止任何正在进行的动画,并确保.remove()添加了内容。

但我会建议一个更好的方法。现在你有:

<div class="l-definition" data-label="Label text">Main text</div>

但为什么不这样做呢?

<div class="l-definition">
  Main text
  <div class="definition">Label text</div>
</div>

+ CSS:

.l-definition>.definition {
    display: none;
    animation: fade 300ms linear both;
}
.l-definition:hover>.definition {
    display: block;
}
@keyframes fade {
    from {opacity: 0}
    to   {opacity: 1}
}

这样可以更好地完成工作,更好地支持搜索引擎和纯文本浏览器!

答案 4 :(得分:1)

$(".l-definition").on({
  mouseenter : function() {
    var definition = $(".l-definition").attr('data-label');
    if (!$(this).find('.definition').length) {
      $(this).append("<div class='definition'>" + definition + "</div>");
      $(".definition").show(300);
    }

  },
  mouseleave: function() {
    $(".definition").hide(300);
  }
});

答案 5 :(得分:0)

在添加新内容之前清除它们

$(".definition").remove();
$(this).append("<div class='definition'>" + definition + "</div>");