公告 / Notice

  • 界面已全面升级(11/06)

    CSS & JS分别用SASS和Webpack编译,对资源进行了模块化处理;缓存规则使页面运行更快!

  • 移动端完成(07/22)

    做得比较随意,UI非常简便

  • 正式上线啦!(07/19)

    星博客V2.0已经正式上线,欢迎大家登录浏览!

  • 星博客V2.0启动(07/15)

    由于不满意1.0版本的UI风格,星博客V2.0今日进入开发阶段

基于jQuery的tooltip简单小插件

概述

不知何故,常常困于在互联网上找到满意的js库,或许是方法问题。

今天想找个简单的、独立的tooltip的js工具,未果!

jQuery-ui提供的tooltip需要引入一整套jQuery-ui的样式和脚本库,我觉得不值得,放弃了。

有个叫popoverjs的库,看似不错,但是用起来有一堆讲究,放弃。

Bootstrap需要引入一整套样式和脚本库,不可用。

花费了一段时间之后,才决定自己简单实现一套,也没用太多时间。

分析与思路

对tooltip的要求:

  1. 任何包含title属性的标签可启用tooltip功能,并取消系统默认的tooltip功能;
  2. 能自动调整tooltip浮动窗口的位置以确保它能被完整看到;
  3. 样式符合我的网站风格。

tooltip的实现思路:

  1. 用jQuery找到页面所有包含title属性的标签;
  2. 对每个标签绑定mouseenter和mouseleave事件处理函数;
  3. 在mouseenter中创建tooltip窗口元素并在合适的位置显示出来;
  4. 在mouseleave中移除当前tooltip元素。

难点:tooltip窗口元素的位置计算。

解决办法:

  1. tooltip窗口元素style.position为fixed;
  2. 确保tooltip窗口内容不换行,那么窗口的高度为padding + height (height = font-size),窗口宽度不设置,可自动调整并不换行;
  3. 基于mouse事件对象的clientX和clientY,即光标所在位置,对tooltip窗口top和left进行调整;
  4. 当空间充足,top = clientY + 14 * 2,left = clientX - 14 * (tooltip内容字符数 + 2),tooltip窗口在光标左下边;
  5. 当底边空间不足,top = clientY - 14 * 4(左上);
  6. 当左边空间不足,left = clientX(右下);

14 是font-size的值,单位是px。

* 2 是因为元素的内边距为1em(1em = 14px),我们需要让tooltip窗口下移2个字符高度,以确保在Y方向上离开光标位置。

* (tooltip内容字符数 + 2) 是在计算tooltip的宽度,一个字符近似1em宽,+2是为了包含padding值,这样可确保tooltip窗口整体向左偏移一个宽度。

以上是在假设底边和左边空间充足的情况下进行的位置计算,那么当底边、左边空间不足时,需要调整,如上5、6。

代码

代码很简单:

CSS

.x-tooltip {
    display: inline-block;
    padding: .6em 1em;
    border: 1px solid #DDD;
    border-radius: 3px 4px;
    position: fixed;
    top: 0;
    left: 0;
    opacity: 0;
    transition: opacity .3s;
    background-color: rgba(0, 0, 0, .8);
    color: #FFF;
    box-shadow: 3px 4px 5px rgba(0, 0, 0, .3);
    z-index: 1;
}

HTML

Hello

Js

// tooltip
function createTooltipElement(text_) {
    var el = document.createElement('div')
    $(el).addClass('x-tooltip').text(text_).appendTo(document.body);
    return el;
}

jQuery.fn.tooltip = function() {
    this.each(function(i, el) {
        if (!el.title) return;
        this.tooltipCfg = { };
        this._title = this.title;
        this.title = '';
        $(this).on('mouseenter', function(e) {
            this.tooltipCfg.el = createTooltipElement(this._title);
            this.tooltipCfg.charLen = this._title.length + 2;
            var pos = {
                top: e.clientY + 14 * 2,
                left: e.clientX - 14 * this.tooltipCfg.charLen
            };
            // Why 3 ? padding-top 1em + padding-bottom 1em + char height 1em
            if (G.viewH - e.clientY < 14 * 3) {
                pos.top = e.clientY - 14 * 4;
            }
            if (e.clientX < 14 * this.tooltipCfg.charLen) {
                pos.left = e.clientX;
            }
            $(this.tooltipCfg.el).css(pos);
            $(this.tooltipCfg.el).css('opacity', 1);
        }).on('mouseleave', function() {
            if (this.tooltipCfg.el) {
                $(this.tooltipCfg.el).remove();
            }
        });
    });
}

G.viewW、G.viewH的计算:

if (document.documentElement) {
    G.viewW = document.documentElement.clientWidth;
    G.viewH = document.documentElement.clientHeight;
} else {
    G.viewW = window.innerHeight;
    G.viewW = window.innerWidth;
}

使用

$(function() {
    $('[title]').tooltip();
});

效果

 

发布于 2018年02月23日 17:06
阅读 71 可以 1