《锋利的JS》之 超链接提示

这是《锋利的JQ》第三章里的案例,主要实现的功能就是当鼠标划过链接时,用特定的提示代替a标签默认的title提示。

效果如图所示:

结构如下 :

<style type="text/css">
    body{ margin:0; padding:40px; background:#fff; font:80% Arial; color:#555; line-height:180%;}
    p{ clear:both; margin:0; padding:.5em 0;}
    #tooltip{position:absolute; border:1px solid #333; background:#f7f5d1; padding:1px; color:#333; display:none;}
</style>
</head>
<body>
    <p><a href="#" class="tooltip" title="这是我的超链接提示1.">提示1.</a></p>
    <p><a href="#" class="tooltip" title="这是我的超链接提示2.">提示2.</a></p>
    <p><a href="#" title="这是自带的提示1.">自带提示1.</a></p>
    <p><a href="#" title="这是自带的提示2.">自带提示2.</a></p>
</body>

建立了四个a标签,后两个默认不作处理以进行对比,CSS中定义了一个id为tooltip的样式,留作弹出提示用。

下面是它的JQ代码:

$(function(){
    var x = 10;
    var y = 20;
    $("a.tooltip").mouseover(function(e){
        this.myTitle = this.title;
        this.title = '';
        var tooltip = "<div id='tooltip'>" + this.myTitle + "</div>";
        $("body").append(tooltip);
        $("#tooltip").css({
            top : (e.pageY + y) + "px",
            left : (e.pageX + x) + "px"
        }).show("fast");
    }).mouseout(function(){
        this.title = this.myTitle;
        $("#tooltip").remove();
    }).mousemove(function(e){
        $("#tooltip").css({
            "top" : (e.pageY + y) + "px",
            "left" : (e.pageX + x) + "px"
        })
    })
})

虽然说JQ的实现思想可能跟我们JS的实现思想不同,但从这一个例子来说,个人觉得是一样的,所以,可以从JQ里总结出实现这效果的思路:

1.当然是先获取所要的两个a标签,添加鼠标onmouseover和onmouseout事件,由于html结构里有直接给了两个class,所以,我们可以直接通过class来获取到这两个a标签。

2.显示出提示效果。在这里,可以通过创建一个id为tooltip的div,并将a的title属性作为这个div的内容,最后添加到body上,并通过鼠标事件进行定位。

大概思路就是如此,我们还是直接用代码来解释吧。如下:

window.onload = function(){
    var aList = getElementsByClassName("tooltip");     //获取a元素
    var x = 10,y = 20;                         //定位用
    var tooltip;

    for(var i = 0,l = aList.length; i < l; i++){
        aList[i].onmouseover = function(evt){
            evt = fixEvt(evt);            //事件的兼容处理
            this.myTitle = this.title;      //如果有title属性的话,默认的提示效果还是会弹出来,所以,要将默认的取消
            this.title = '';

            var div = document.createElement("div");              //创建提示内容
            div.setAttribute("id","tooltip");
            var text = document.createTextNode(this.myTitle);
            div.appendChild(text);
            tooltip = document.body.appendChild(div);

            tooltip.style.top = (evt.pageY + y) + "px";           //提示内容的定位
            tooltip.style.left = (evt.pageX + x) + "px";
            tooltip.style.display = "block";
        }

        aList[i].onmouseout = function(){
            this.title = this.myTitle;          //将title内容还给title属性,如若不然,下次就获取不到title内容鸟
            document.body.removeChild(tooltip);            //移除div
        }

        aList[i].onmousemove = function(evt){              //鼠标移动时也进行定位
            evt = fixEvt(evt);
            tooltip.style.top = (evt.pageY + y) + "px";
            tooltip.style.left = (evt.pageX + x) + "px";
        }
    }
}

function getElementsByClassName(className,node){            //通过类名获取元素,返回一个元素数组
    node = node || document;
    if(node.getElementsByClassName){
        return node.getElementsByClassName(className);
    }
    var eles = node.getElementsByTagName('*');
    var reg = [];
    for(var i = 0,l = eles.length; i < l; i++){
        if(hasClass(className,eles[i])){
            reg.push(eles[i]);
        }
    }
    return reg;
}

function hasClass(className,node){             //判断是否含有某类名
    var eles = node.className.split(/\s+/);
    for(var i = 0,l = eles.length; i < l; i++){
        if(eles[i] == className){
            return true;
        }
    }
    return false;
}

function fixEvt(evt){                       //处理事件的兼容性
    evt = evt || window.event;
    if(!evt.pageX){
        evt.pageX = evt.clientX + document.documentElement.scrollLeft - 2;
        evt.pageY = evt.clientY + document.documentElement.scrollTop - 2;
    }
    return evt;
}

我在实现这个JS代码的过程中,主要收获是处理pageX的兼容性上,在这之前我没接触过,通过google后,才了解,在IE中并不兼容此属性,并找了相关解决方案。才知道IE下想实现pageX的效果是要通过cliendX加上滚动条的滚动距离再减去默认的滚动条2个边框像素。所以才有了fixEvt函数。

/**************************华丽的分界线***************************************/

经高手点拨,说不要通过固定的x=10; y=20;这样定位置,而应该根据所划过元素的宽高进行定位,可以通过offsetWidth和offsetHeigth获取到元素自身的绝对宽高。还有,最好就是通过控制显示隐藏来达到效果,而不是每次都创建而移除提示信息,因为这样会影响效率。最后,有必要的话,就给封装成函数。但这里只是访写,实现即可,具体的自己学习到了,将来应用到了,再应用。

posted @ 2011-05-04 11:02  肥杜  阅读(939)  评论(3编辑  收藏  举报