一个有意思的图片鼠标切换

Posted sp42a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个有意思的图片鼠标切换相关的知识,希望对你有一定的参考价值。

做淘宝活动页面的时候,用到最多的就是锚点,一个图片标签,然后不断地在上面画热区。不过我想问的是有多少人研究过,用矩形画热点,四个坐标值各自表示的含义,还有它和background-position有什么相同或相似的地方吗?

我们都知道 map 的代码大概是这样的:

 <area shape="rect" coords="17,66,243,355" href="#" />

这四个坐标值,前两个值分别表示左上角的点相对图片的坐标点,简单可以理解成background-position,后两个值分别表示右下角的点相对图片的坐标点。小张画了一个简单的图,大家可以理解下。

画的比较丑,请大家见谅。图中的黑框区域是一张图片,红框表示画的热区。coords 的数值从左往右分别表示 A1,B1,A2,B2 的长度。根据这四个值,我们可以求出这个热区的长度是 A2-A1,高度是 B2-B1。OK,那让我来分析这样一个效果,照理先贴代码:

<!DOCTYPE
 html PUBLIC "-//W3C//DTD HTML 4.01//EN" 
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
    <meta http-equiv="Content-Type" 
content="text/html;charset=UTF-8">
    <title>图片切换</title>
    <style type="text/css">
        
html,body,div,h1,h2,h3,h4,h5,h6,ul,ol,dl,li,dt,dd,p,blockquote,pre,form,fieldset,table,th,tdmargin:0;padding:0;

        .wq_page width:100%; font:normal 12px/1.5 Arial, Helvetica, 
sans-serif; overflow:hidden; zoom:1; background:#000
        .wq_page img vertical-align:top;border: none;
        .wq_tab width:990px; margin:0px auto; overflow:hidden; 
display:block;
        .tab_left width:370px; height:860px; float:left;
        .tab3 .tab_left 
background:url(http://img03.taobaocdn.com/tps/i3/T17kWGXcdvXXXXXXXX-370-860.jpg)
 no-repeat;
        .tab_right width:620px; height:860px; float:left; 
overflow:hidden;
        .tab_right position:relative;
        .tab_right .tab_on display:none; position:absolute; 
overflow:hidden; background:#191919;
        .tab_on span display:block; position:absolute; width:100%; 
height:100%;
        .tab3 .tab_on span 
background-image:url(http://img04.taobaocdn.com/tps/i4/T1wMWIXkVcXXXXXXXX-620-860.jpg);
 background-repeat:no-repeat;
        .tab_on em display:block; width:100%; height:100%; 
margin-left:100%;
        .tab3 .tab_on em 
background-image:url(http://img01.taobaocdn.com/tps/i1/T1sgGIXX8dXXXXXXXX-620-860.jpg);
 background-repeat:no-repeat;
    </style>
</head>
<body>
<div class="wq_page" id="wq_page">
    <div class="wq_tab tab3" id="tab1">
        <div class="tab_left"></div>
        <div class="tab_right"><img 
src="http://img01.taobaocdn.com/tps/i1/T1sgGIXX8dXXXXXXXX-620-860.jpg" 
alt=""
                                    usemap="#Maptab3"/>
            <map name="Maptab3" id="Maptab3">
                <area shape="rect" coords="408,651,613,860"
                      
href="http://www.taobao.com/go/act/new/binfenshengdan10.php"/>
                <area shape="rect" coords="408,446,613,651"
                      
href="http://www.taobao.com/go/act/new/binfenshengdan2.php"/>
                <area shape="rect" coords="408,223,613,446"
                      
href="http://www.taobao.com/go/act/new/binfenshengdan5.php"/>
                <area shape="rect" coords="408,8,613,224" 
href="http://www.taobao.com/go/act/new/binfenshengdan6.php"/>
                <area shape="rect" coords="204,8,409,276" 
href="http://lelo2.xin.taobao.com/"/>
                <area shape="rect" coords="204,276,409,437" 
href="http://mayday.xin.taobao.com/"/>
                <area shape="rect" coords="204,437,409,704"
                      
href="http://www.taobao.com/go/act/new/binfenshengdan4.php"/>
                <area shape="rect" coords="204,704,409,860" 
href="http://adidas.xin.taobao.com/"/>
                <area shape="rect" coords="0,734,205,860" 
href="http://www.taobao.com/go/act/new/binfenshengdan7.php"/>
                <area shape="rect" coords="0,486,205,733" 
href="http://www.taobao.com/go/act/new/binfenshengdan1.php"/>
                <area shape="rect" coords="0,176,205,486" 
href="http://www.taobao.com/go/act/new/binfenshengdan9.php"/>
                <area shape="rect" coords="0,6,205,175" 
href="http://vivian.xin.taobao.com/"/>
            </map>
        </div>
    </div>
</div>
<script type="text/javascript">
    function getTag(id, tag) 
        if (tag) 
            return 
document.getElementById(id).getElementsByTagName(tag);
        
        else 
            return document.getElementById(id);
        
    
    //校验根据area取到的元素的父节点的name是否匹配正则
    function getChild(tags, re) 
        var tag = [];
        for (var i = 0,j = 0; i < tags.length; i++) 
            if (tags[i].parentNode.name.match(re)) 
                tag[j] = tags[i];
                j++;
            
        
        return tag;
    
    (function() 
        var subarea = getChild(getTag("wq_page", "area"), /( 
|^)(Maptab)(\\d)( |$)/);
        var coords;
        function autoMove(tag, flag) 
            tag.style.marginLeft = (parseInt(tag.style.marginLeft) + 
flag) + '%';
            var time = setTimeout(function() 
                autoMove(tag, flag)
            , 20)
            if (parseInt(tag.style.marginLeft) * flag >= 0) 
                clearTimeout(time);
                autoborder(tag, -1);
            
        
        function autoborder(tag, flag) 
            tag.style.top = (parseInt(tag.style.top) + flag) + 'px';
            tag.style.left = (parseInt(tag.style.left) + flag) + 'px';
            var t1 = setTimeout(function() 
                autoborder(tag, flag)
            , 20)
            if (parseInt(tag.style.top) * flag >= 0) 
clearTimeout(t1);
        
        function stopCount() 
            if (t)clearTimeout(t)
        
        for (var i = 0; i < subarea.length; i++) 
            (function(i) 
                subarea[i].onmouseover = function() 
                    var tab_on = document.getElementById("tab_on");
                    if (tab_on) 
                        tab_on.parentNode.removeChild(tab_on);
                    
                    var _div = document.createElement("div");
                    _div.className = 'tab_on';
                    _div.id = 'tab_on';
                    _div.innerHTML = '<a href="#" 
target="_blank"><span><em></em></span></a>';

                    subarea[i].parentNode.parentNode.appendChild(_div);
                    var _span = _div.getElementsByTagName("span")[0],
                            _em = _span.getElementsByTagName("em")[0],
                            _a = _div.getElementsByTagName("a")[0];
                    coords = 
subarea[i].getAttribute('coords').split(",");
                    var _h = coords[3] - coords[1];//高度
                    var _w = coords[2] - coords[0];//宽度
                    _a.setAttribute('href', 
subarea[i].getAttribute('href'));
                    _div.style.display = "block";
                    _div.style.left = coords[0] + "px";
                    _div.style.top = coords[1] + "px";
                    _div.style.width = _w + "px";
                    _div.style.height = _h + "px";
                    _span.style.top = "8px";
                    _span.style.left = "8px";
                    _span.style.marginLeft = "-100%";
                    _span.style.backgroundPosition = "-" + coords[0] + 
"px -" + coords[1] + "px";
                    _em.style.backgroundPosition = "-" + coords[0] + "px
 -" + coords[1] + "px";
                    autoMove(_span, 10)
                
            )(i);
        
    )();
</script>
</div>
</body>
</html>

还是简单说一下代码:先去取 area 元素,通过ID把所有的 area 元素取到,再通过正则表达式,把符合条件的给筛选出来(这里是判断它的父级元素即 map 标签的 name,因为考虑到一个页面中也许会有多个 map)。遍历 area 元素,给它加上鼠标移入事件。

图片切换,必然是新建一个层,覆盖掉原先的图片层,所以在移入事件中,如果层存在,即删除掉,创建一个层出来(这一步个人觉得处理的不是太好,如果 层存在,也可以不用删除层,当然也不需要再创建层出来,即可对当前层做修改即可,这个大家可以对代码做优化,小张就不做处理了),宽度和高度是热区的宽度 和高度。这里的创建的层的innerHTML还是有必要讲一下的:

<a href="#" target="_blank"><span><em></em></span></a>

span 值是用新图片的 background 来做定位,他一开始的位置出现在相对父级 -100% 的位置,因为要做运动,em 标签是用来存放老图片的 background 来做定位。假如去掉 em,即开始做运动时,那一块底是黑色背景的,css 代码在这里:

.tab_right .tab_on 
	display:none; position:absolute; overflow:hidden; background:#191919;

整个运动还有上下的运动,所以一开始可以给topleft设定一个值,然后在运动中慢慢地让他们的值回归到0。

再来分析下autoMove,它先将 span 的 margin-left 值慢慢地拉回 0,因为一开始的值为 -100%,每次 +10,是加10个百分 点,当值变成0时,停止运动,开启一个新的运动(如果不开启,那么此时的spanlefttop值为8),就是将left值和top值重新回归到0。

以上是关于一个有意思的图片鼠标切换的主要内容,如果未能解决你的问题,请参考以下文章

一个有意思的图片鼠标切换

很有点意思的特效,本人很喜欢

很有点意思的特效,本人很喜欢

Ant Design -- 图片可拖拽效果,图片跟随鼠标移动

js鼠标单击实现图片切换?

vue鼠标悬浮切换文字和图片