最近学习了一些设计知识,就是想让自己用一个例子来检验一下自己的学习有啥进步。因此想到了用一个简单的小功能来检验。
需求如下,我们知道基本上很多html元素都有一个title属性,一旦鼠标移动到这个元素上,就会显示一个黄色的小框,然后将title的值显示出来;当鼠标移开以后,这个黄色的框就会消失。
这个基本的功能总的说来能达到一定的目的,但是UI体验上不是那么优秀。因此,我尝试用另外一种方式来实现。

尽可能让标签简单
<a href="#" title="我是一个特别有意思的提示信息">link</a>
<span href="#" title="这个是一个很有用的提示">提示</span>
首先,我希望标签尽可能的简单,其次,我希望这个tooltip尽可能通用。为了让它通用,我想到了实现为一个JQuery插件。
调用尽可能简单
$("article a[title]").tooltips();
$("article div[title]").tooltips();
有了这个基本的API,我能梳理出我需要完成的分步骤的工作,这个我用联结a元素作为demo
1、循环遍历每个链接。
2、为每一个链接创建一个(隐藏的)div.tooltip,里面的文本匹配链接title属性。
3、删除链接title属性(摆脱默认黄色框弹出的唯一方法)。
4、处理鼠标移到链接的事件(hover out)。
5、定位tooltip,然后慢慢显示出来。
6、处理鼠标移出链接的事件(hovered off)
7、tooltip平滑的消失。
有了以上的思路步骤以后,我的实现代码如下:
// IIFE to ensure safe use of $
(function( $ ) {
// Create plugin
$.fn.tooltips = function(el) {
var $tooltip,
$body = $('body'),
$el;
// Ensure chaining works
return this.each(function(i, el) {
$el = $(el).attr("data-tooltip", i);
// Make DIV and append to page
var $tooltip = $('<div class="tooltip" data-tooltip="' + i + '">' + $el.attr('title') + '<div class="arrow"></div></div>').appendTo("body");
// Position right away, so first appearance is smooth
var linkPosition = $el.position();
$tooltip.css({
top: linkPosition.top - $tooltip.outerHeight() - 13,
left: linkPosition.left - ($tooltip.width()/2)
});
$el
// Get rid of yellow box popup
.removeAttr("title")
// Mouseenter
.hover(function() {
$el = $(this);
$tooltip = $('div[data-tooltip=' + $el.data('tooltip') + ']');
// Reposition tooltip, in case of page movement e.g. screen resize
var linkPosition = $el.position();
$tooltip.css({
top: linkPosition.top - $tooltip.outerHeight() - 13,
left: linkPosition.left - ($tooltip.width()/2)
});
// Adding class handles animation through CSS
$tooltip.addClass("active");
// Mouseleave
}, function() {
$el = $(this);
// Temporary class for same-direction fadeout
$tooltip = $('div[data-tooltip=' + $el.data('tooltip') + ']').addClass("out");
// Remove all classes
setTimeout(function() {
$tooltip.removeClass("active").removeClass("out");
}, 300);
});
});
}
})(jQuery);
最后,我的css实现如下:
.tooltip, .arrow:after {
background: black;
border: 2px solid white;
}
.tooltip {
pointer-events: none;
opacity: 0;
display: inline-block;
position: absolute;
padding: 10px 20px;
color: white;
border-radius: 20px;
margin-top: 20px;
text-align: center;
font: bold 14px "Helvetica Neue", Sans-Serif;
font-stretch: condensed;
text-decoration: none;
text-transform: uppercase;
box-shadow: 0 0 7px black;
}
.arrow {
width: 70px;
height: 16px;
overflow: hidden;
position: absolute;
left: 50%;
margin-left: -35px;
bottom: -16px;
}
.arrow:after {
content: "";
position: absolute;
left: 20px;
top: -20px;
width: 25px;
height: 25px;
box-shadow: 6px 5px 9px -9px black,
5px 6px 9px -9px black;
transform: rotate(45deg);
}
.tooltip.active {
opacity: 1;
margin-top: 5px;
transition: all 0.2s ease;
}
.tooltip.out {
opacity: 0;
margin-top: -20px;
}
好了,一个有趣的demo实现啦,感兴趣的可以试试额。