使用原生js来替换title属性的悬浮文字提示-可自定义样式和出现时间-简单实现

简介

要让一个DOM元素出现悬浮文字提示,一般情况下,我们都会选择使用H5的title属性。例如:

<div title="456">123</div>

这样设置之后,当鼠标在div上悬浮过了一段时间之后,网页上鼠标位置附近就会出现悬浮文字提示,例如这样:
使用原生js来替换title属性的悬浮文字提示-可自定义样式和出现时间-简单实现但是,不同的浏览器,悬浮等待的时间和悬浮文字的样式都可能会不一样,例如chrome上显示是白底灰字,firefox上就可能是黄底黑字,时长可能是3s或者1s,如果为了确保不同浏览器的用户体验的效果趋于一致的话,那么我们就需要禁用默认的title属性,改用js手动实现悬浮文字的提示。

1.需求分析

为了提高组件的简洁性,所以这里我采用原生js进行编码,不兼容IE 6 7 8,并且没有做过渡动画,只是简单是隐藏显示,有兴趣的同学可以改用jquery重构来提高代码兼容性,用fadeIn fadeOut等动画效果代替直接的显示隐藏。
经分析,H5的title属性的作用逻辑如下:

  1. 鼠标进入元素时,延时一定时间后显示悬浮文字提示,并且当鼠标在元素内移动时移除文字提示
  2. 鼠标离开元素时,移除文字提示
  3. 文字提示为一个inline-block的div或span,固定定位,位置在鼠标位置的附近。
    因为这个组件比较简单,所以我就直接上代码啦:

2.代码解析

js和html测试代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        .box{
            margin-top: 100px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="box" title="456">123</div>
    <div>
        <span title="hello world!">asdjkasl</span>
        <span title="aslkdjsakl">fjksdkfj</span>
    </div>
<script>
    function test(){
        alert(1);
    }
    //使用自定义的悬浮文字提示代替原生的title属性,采用addEventListner进行事件绑定,不兼容IE 6 7 8
    var titleTools = {
        _init : function(time){
            var temp = time;
            time = parseInt(time);
            if(!isNaN(time)&&time>=0){
                this.timeout = time;
            }else{
                console.warn("param "+time+" is not a number or out of range! using default timeout setting");
            }
            //选中所有含有title属性的节点
            var eles = document.querySelectorAll('*[title]');
            for(var i=0;i<eles.length;i++){
                //隐藏原先的title属性,改用js进行控制
                if(eles[i].title){
                    eles[i].dataset.title = eles[i].title;
                    eles[i].title = '';
                }
                //绑定函数
                eles[i].timeoutms = this.timeout;
                eles[i].addEventListener("mouseenter",this.title);
                eles[i].addEventListener("mouseleave",this.clear);
                eles[i].leaveAction = this.clear;
            }
        },
        //延时显示文字
        timeout : 500,
        //显示提示文字的函数绑定在mouseenter中
        title : function(e){
            clearTimeout(this.timer);
            var self = this;
            self.removeEventListener("mousemove",this.leaveAction);
            this.timer = setTimeout(function(){
                var div = document.createElement('div');
                div.innerHTML = self.dataset.title;
                div.style.cssText = 'display:inline-block;padding:0 5px;line-height:1.3;color:#000;background:#fff;border:1px solid #000;font-size:13px;position:fixed;left:'+(e.clientX+5)+'px;top:'+(3+e.clientY)+'px;z-index:999';
                document.body.appendChild(div);
                self.titleElement = div;
                self.addEventListener("mousemove",self.leaveAction);
            },this.timeoutms);
        }
        ,
        //清除文字提示框的函数,绑定在mousemove和mouseleave上
        clear : function(e){
        clearTimeout(this.timer);
        var div = this.titleElement;
        if(div&&div.parentNode){
            div.parentNode.removeChild(div);
        }
    }
    };
</script>
<script>
    titleTools._init(300);
</script>
</body>
</html>

上面这个代码还是比较简单,涉及的知识点主要有:
1.原生js获取节点的方法,document.querySelector()和document.querySelectorAll().这两个函数,接受的参数都是一个css选择器字符串,例如’.box’, ".father .son:nth-of-type(1)"之类的,总之只要能够写在css中的选择器,这里都可以使用。其中,document.querySelector()返回的是第一个匹配的原生DOM节点,和document.getElementById()有点类似,但是更加强大,而document.querySelectorAll()返回的是一个原生节点数组,存储所有匹配到的节点,和document.getElementsByClassName()有点像,但是更好用。
2.通配符选择器*用于选中网页上的所有节点,属性选择器[]用于选中含有某个属性或属性值为某个特定值的节点。搭配在一起后*[title]用于选中所有含有title属性的节点。
3. JavaScript中函数和对象this的指向问题,函数的this通常指向函数的上一层对象,上面的代码中频繁地使用到了this,如果大家对js的this的概念含糊不清的话可能会看不懂,建议大家百度一下或参考:JS this指向总结

3.结语

这个组件比较简单,测试什么的我就不贴图啦,大家自己把代码拷到本地运行就知道效果了,先写到这里吧,本文作者郑伟斌,写于2019/4/26,转载请注明出处