仿qq新闻 按数据源均分时间点幻灯效果

仿qq新闻 按数据源均分时间点幻灯效果
var jsondata=[{...},{...},...];//数据源,一切皆因它而生,因它而灭

function itimepoint(itimeslideid, dateid, timelineid, titletop, titleid, defaultshow){
    /* 传入参数说明:
     * itimeslideid: 外围id名. 本样例dom中#itimeslide;
     * dateid: 日期id名. 本样例dom中#date;
     * timelineid: 时间点分布id名. 本样例dom中#timeline;
     * titletop: 标题容器上方小三角id名. 本样例dom中#titletop;
     * titleid: 标题容器id名. 本样例dom中#title;
     * defaultshow: 设定初始显示的时间点, 默认为0, 可不传值
     */

    //参数判断,测试用,成功运行后可删除
    if (arguments.length < 5 || arguments.length>6) {
        alert('参数传入错误,请传入5或6个值! :)');
        return false;
    }

 //通用方法
    var ibase = {
        //document.getelementbyid
        id: function(name){
            return document.getelementbyid(name);
        },
        //时间点动画显示
        pointslide: function(elem, val){
            //可通过修改i+=5中的5控制滑动速度
            for (var i = 0; i <= 100; i += 5) {
                (function(){
                    //这个pos定义很重要,若直接使用闭包获取到的不是上面的i
                    var pos = i;
                    //平滑移动
                    settimeout(function(){
                        elem.style.left = pos * val / 100 + 'px';
                    }, (pos + 1) * 10);
                })();
            }
        },
        //为元素添加样式
        addclass: function(elem, val){
            //若元素无class,直接赋值
            if (!elem.classname) {
                elem.classname = val;
            }else {
                //否则通过添加空格新增一个class
                var oval = elem.classname;
                oval += ' ';
                oval += val;
                elem.classname = val;
            }
        },
        //获取元素索引
        index: function(cur, obj){
            for (var i = 0; i < obj.length; i++) {
                if (obj[i] == cur) {
                    return i;
                }
            }
        }
    }
 //整个函数变量定义区
    var datalen = jsondata.length;
    var itimesilde = ibase.id(itimeslideid);
    var date = ibase.id(dateid);
    var timeline = ibase.id(timelineid);
    var titletop = ibase.id(titletop);
    var title = ibase.id(titleid);
    var itimesildew = itimesilde.offsetwidth;//幻灯区实际宽度
    var timepoint = document.createelement('ul');//用来存储时间点的ul
    var timepointleft = null;//时间点相对于父元素左边距离
    var timepointleftcur = null;//每两个时间点间距
    var pointindex = 0;//时间点在队列中的索引值
 var defaultshow = defaultshow || 0;//默认显示的时间
 var clearfun=null;//当用户无意识的划过时中止执行
 var that=null;
    //根据数据条数生成对应的时间点html
    for (var i = 0; i < datalen; i++) {
        timepoint.innerhtml += '<li></li>';
    }
    //将时间点插入到时间线div中
    timeline.appendchild(timepoint)
    var timepoints = timeline.getelementsbytagname('li');
    //时间点平滑显示
    for (var i = 0; i < timepoints.length; i++) {
  //每两个时间点间间距
        timepointleftcur = parseint(itimesildew / (datalen + 1));
  //计算对应时间点左边距
        timepointleft = (i + 1) * timepointleftcur;
  //时间点动画形式初始化
        ibase.pointslide(timepoints[i], timepointleft);
  //初始显示时间点
        settimeout(function(){
            timepoints[defaultshow].onmouseo教程ver();
        }, 1200);
  //获取时间点默认class值,为鼠标事件做准备
        timepoints[i].oldclassname = timepoints[i].classname;
        timepoints[i].onmouseover = function(){
   that = this;//确保clearfun中的this是当前的this
   //提升用户体验,当用户无意识地划过时不执行函数
   clearfun=settimeout(function(){
    //计算出当前时间点索引值,为鼠标划出做准备
          pointindex = ibase.index(that, timepoints);
    //去除上一个时间点高亮样式
    for (var m = 0; m < timepoints.length; m++) {
     if (m != pointindex) {
      timepoints[m].classname = timepoints[m].oldclassname
     }
    }
    //为当前时间点加载高亮样式
             ibase.addclass(that, 'hover');
    //切换日期及标题值
             date.innerhtml = '<span>' + (jsondata[pointindex]['date'] || '') + '</span><em></em>';
             title.innerhtml = '<a href="' + (jsondata[pointindex]['href'] || '') + '">' + (jsondata[pointindex]['title'] || '') + '</a>';
             //改变日期及标题的位置,此处减去的数字,可根据实际样式调整
             date.style.left = ((pointindex + 1) * timepointleftcur - 25) + 'px';
             titletop.style.left = ((pointindex + 1) * timepointleftcur + 6) + 'px';
             //当标题框左边距与标题框宽度之和大于外围宽度时,以右边为绝对点
             if ((title.offsetwidth + (pointindex + 1) * timepointleftcur) < itimesildew) {
                 title.style.left = ((pointindex + 1) * timepointleftcur - timepointleftcur) + 'px';
             }else {
                 title.style.left = (itimesildew - title.offsetwidth) + 'px';
             }
             //显示日期/时间点/标题
             date.style.display = 'block';
             titletop.style.display = 'block';
             title.style.display = 'block';
   },200);//200为认定无意识划过的时间,可自行调节
        }
        timepoints[i].onmouseout = function(){
   //若停留时间低于200ms,认定为无意识划过,中止函数
   cleartimeout(clearfun);
        }
    }
}

腾讯新闻详情页有一个事件进展效果, 觉得挺有意思. 于是, 就有了本文的效果: 按数据源均分时间点幻灯. 花了三个多小时写的, 当然, 包括样式与调试. 兼容主流, 建议在chrom,firefox,opera,safari等标准浏览器中查看. ie下没有阴影及圆角.
实现了根据源数据(样例中是一个json数据组)总条数, 均分出时间点以平滑向右动画方式显示在时间线上, 当鼠标划过时间点时, 显示对应的日期及标题. 鼠标划过事件, 充分考虑了用户体验, 当用户快速(无意识移动)从时间点上划

看整个实例源码。

<style>
#itimeslide{position:relative;margin:0 20px;padding:15px 0}
#itimeslide #date{display:none;position:absolute;left:74px;top:3px;width:70px}
#itimeslide #date span{display:block;height:14px;padding:0 3px;background:#4e7db3;color:#fff;font-size:12px;line-height:14px}
#itimeslide #date em{display:block;width:5px;height:3px;margin:0 auto;background:url(yun_qi_img/20101224sprite.gif) no-repeat -61px 0}
#itimeslide #timeline{overflow:visible;width:100%;height:2px;margin:16px 0 20px;background:#c7c7c7}
#itimeslide #timeline li{display:block;position:absolute;left:0;top:24px;width:17px;height:17px;background:url(yun_qi_img/20101224sprite.gif) no-repeat 0 0;text-indent:-999px;cursor:pointer}
#itimeslide #timeline li.hover{background-position:-20px 0}
#itimeslide span#titletop{display:none;position:absolute;top:45px;width:12px;height:8px;background:url(yun_qi_img/20101224sprite.gif) no-repeat -88px -21px;z-index:1}
#itimeslide #title{display:none;position:absolute;top:52px;padding:15px 10px;background:#f8f8ff;border:1px solid #708bab;border-radius:5px;-weblit-border-radius:5px;-moz-border-radius:5px;-webkit-box-shadow:3px 3px 3px #c7c7c7;
-moz-box-shadow:3px 3px 3px #c7c7c7}
</style>
<script>
 /*******************************
 * @author mr.think
 * @author blog http://mrthink.net/
 * @2010.12.24
 * @可自由转载及使用,但请注明版权归属
 *******************************/
//原数据 json :) 一般是由后台传入的
var jsondata=[
 {'date':'2010-12-25','title':'原生js实现按数据源均分时间点幻灯片','href':'http://mrthink.net/'},
 {'date':'2010-11-01','title':'原生js获取元素样式属性值的方法','href':'http://mrthink.net/'},
 {'date':'2010-10-22','title':'纯css教程实现列表鼠标划过变色','href':'http://mrthink.net/'},
 {'date':'2010-09-23','title':'实现checkbox的全选/全不选/点选/行内点选','href':'http://mrthink.net/'},
 {'date':'2010-09-05','title':'js计时器settimeout()与setinterval()方法的区别','href':'http://mrthink.net/'},
 {'date':'2010-06-07','title':'加载xml文档的函数(原生网页特效版及jquery版)','href':'http://mrthink.net/'},
 {'date':'2010-05-09','title':'限制字符输入数功能(jq版和原生js版)','href':'http://mrthink.net/'},
 {'date':'2010-04-13','title':'奇或偶数行高亮显示及鼠标划过高亮显示类','href':'http://mrthink.net/'},
 {'date':'2010-03-01','title':'结构/表现/行为完全分离的选项卡(jq版和原生js版)','href':'http://mrthink.net/'},
 {'date':'2010-02-22','title':'简易的点击展开/关闭效果(原生js版和jq版)','href':'http://mrthink.net/'},
 {'date':'2010-02-01','title':'网站基本优化:php教程的gzip压缩方法','href':'http://mrthink.net/'},
 {'date':'2010-01-20','title':'基于jquery的渐隐渐显图片轮换幻灯片','href':'http://mrthink.net/'}
];
 
function itimepoint(itimeslideid, dateid, timelineid, titletop, titleid, defaultshow){
    /* 传入参数说明:
     * itimeslideid: 外围id名. 本样例dom中#itimeslide;
     * dateid: 日期id名. 本样例dom中#date;
     * timelineid: 时间点分布id名. 本样例dom中#timeline;
     * titletop: 标题容器上方小三角id名. 本样例dom中#titletop;
     * titleid: 标题容器id名. 本样例dom中#title;
     * defaultshow: 设定初始显示的时间点, 默认为0, 可不传值
     */
 
    //参数判断,测试用,成功运行后可删除
    if (arguments.length < 5 || arguments.length>6) {
        alert('参数传入错误,请传入5或6个值! :)');
        return false;
    }
 
 //通用方法
    var ibase = {
        //document.getelementbyid
        id: function(name){
            return document.getelementbyid(name);
        },
        //时间点动画显示
        pointslide: function(elem, val){
            //可通过修改i+=5中的5控制滑动速度
            for (var i = 0; i <= 100; i += 5) {
                (function(){
                    //这个pos定义很重要,若直接使用闭包获取到的不是上面的i
                    var pos = i;
                    //平滑移动
                    settimeout(function(){
                        elem.style.left = pos * val / 100 + 'px';
                    }, (pos + 1) * 10);
                })();
            }
        },
        //为元素添加样式
        addclass: function(elem, val){
            //若元素无class,直接赋值
            if (!elem.classname) {
                elem.classname = val;
            }else {
                //否则通过添加空格新增一个class
                var oval = elem.classname;
                oval += ' ';
                oval += val;
                elem.classname = val;
            }
        },
        //获取元素索引
        index: function(cur, obj){
            for (var i = 0; i < obj.length; i++) {
                if (obj[i] == cur) {
                    return i;
                }
            }
        }
    }
 //整个函数变量定义区
    var datalen = jsondata.length;
    var itimesilde = ibase.id(itimeslideid);
    var date = ibase.id(dateid);
    var timeline = ibase.id(timelineid);
    var titletop = ibase.id(titletop);
    var title = ibase.id(titleid);
    var itimesildew = itimesilde.offsetwidth;//幻灯区实际宽度
    var timepoint = document.createelement('ul');//用来存储时间点的ul
    var timepointleft = null;//时间点相对于父元素左边距离
    var timepointleftcur = null;//每两个时间点间距
    var pointindex = 0;//时间点在队列中的索引值
 var defaultshow = defaultshow || 0;//默认显示的时间
 var clearfun=null;//当用户无意识的划过时中止执行
 var that=null;
    //根据数据条数生成对应的时间点html
    for (var i = 0; i < datalen; i++) {
        timepoint.innerhtml += '<li></li>';
    }
    //将时间点插入到时间线div中
    timeline.appendchild(timepoint)
    var timepoints = timeline.getelementsbytagname('li');
    //时间点平滑显示
    for (var i = 0; i < timepoints.length; i++) {
  //每两个时间点间间距
        timepointleftcur = parseint(itimesildew / (datalen + 1));
  //计算对应时间点左边距
        timepointleft = (i + 1) * timepointleftcur;
  //时间点动画形式初始化
        ibase.pointslide(timepoints[i], timepointleft);
  //初始显示时间点
        settimeout(function(){
            timepoints[defaultshow].onmouseover();
        }, 1200);
  //获取时间点默认class值,为鼠标事件做准备
        timepoints[i].oldclassname = timepoints[i].classname;
        timepoints[i].onmouseover = function(){
   that = this;//确保clearfun中的this是当前的this
   //提升用户体验,当用户无意识地划过时不执行函数
   clearfun=settimeout(function(){
    //计算出当前时间点索引值,为鼠标划出做准备
          pointindex = ibase.index(that, timepoints);
    //去除上一个时间点高亮样式
    for (var m = 0; m < timepoints.length; m++) {
     if (m != pointindex) {
      timepoints[m].classname = timepoints[m].oldclassname
     }
    }
    //为当前时间点加载高亮样式
             ibase.addclass(that, 'hover');
    //切换日期及标题值
             date.innerhtml = '<span>' + (jsondata[pointindex]['date'] || '') + '</span><em></em>';
             title.innerhtml = '<a href="' + (jsondata[pointindex]['href'] || '') + '">' + (jsondata[pointindex]['title'] || '') + '</a>';
             //改变日期及标题的位置,此处减去的数字,可根据实际样式调整
             date.style.left = ((pointindex + 1) * timepointleftcur - 25) + 'px';
             titletop.style.left = ((pointindex + 1) * timepointleftcur + 6) + 'px';
             //当标题框左边距与标题框宽度之和大于外围宽度时,以右边为绝对点
             if ((title.offsetwidth + (pointindex + 1) * timepointleftcur) < itimesildew) {
                 title.style.left = ((pointindex + 1) * timepointleftcur - timepointleftcur) + 'px';
             }else {
                 title.style.left = (itimesildew - title.offsetwidth) + 'px';
             }
             //显示日期/时间点/标题
             date.style.display = 'block';
             titletop.style.display = 'block';
             title.style.display = 'block';
   },200);//200为认定无意识划过的时间,可自行调节
        }
        timepoints[i].onmouseout = function(){
   //若停留时间低于200ms,认定为无意识划过,中止函数
   cleartimeout(clearfun);
        }
    }
}

//样例加载该函数
window.onload = function(){
    itimepoint('itimeslide', 'date', 'timeline', 'titletop','title');
}

</script>

<div id="demo">
 <div id="itimeslide">
  <div id="date"></div>
  <div id="timeline"></div>
  <span id="titletop"></span>
  <div id="title"></div>
 </div>
</div>

时间: 2024-09-17 09:27:03

仿qq新闻 按数据源均分时间点幻灯效果的相关文章

Android贝塞尔曲线初步学习第二课 仿QQ未读消息气泡拖拽黏连效果

上一节初步了解了Android端的贝塞尔曲线,这一节就举个栗子练习一下,仿QQ未读消息气泡,是最经典的练习贝塞尔曲线的东东,效果如下 附上github源码地址:https://github.com/MonkeyMushroom/DragBubbleView 欢迎star~ 大体思路就是画两个圆,一个黏连小球固定在一个点上,一个气泡小球跟随手指的滑动改变坐标.随着两个圆间距越来越大,黏连小球半径越来越小.当间距小于一定值,松开手指气泡小球会恢复原来位置:当间距超过一定值之后,黏连小球消失,气泡小球

Android自定义ListView实现仿QQ可拖拽列表功能_Android

我们大致的思路,其实是这样子的,也是我的设想,我们可以先去实现一个简单的ListView的数据,但是他的Adapter,我们可以用系统封装好的,然后传递进去一个实体类,最后自定义一个listview去操作,所以我们先把准备的工作做好,比如? list_item.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.a

Android插件化的思考——仿QQ一键换肤,思考比实现更重要!

Android插件化的思考--仿QQ一键换肤,思考比实现更重要! 今天群友希望写一个关于插件的Blog,思来想去,插件也不是很懂,只是用大致的思路看看能不能模拟一个,思路还是比较重要的,如果你有兴趣的话,也可以加群:555974449,你也可以说出你想看的Blog哦,嘿嘿!好的,不多说,我们进入正题: 关于QQ的换肤,他们的实现思路我不是很清楚,但是你可以看一下这张换肤的截图 我们想使用哪个主题就直接下载就好了,这一实现的过程我们大致的可以猜想: 首选是下载到本地指定文件夹,然后通过插件加载到我

Android仿QQ列表左滑删除操作_Android

最近学习了如何做一个像QQ的左滑RecyclerView的item显示选项的,主要是用到Scroller 我们首先新建一个自己的RecyclerView 定义好一些要用的的变量 重写构造方法,把前两个构造方法改为如下,使无论如何构造都要执行第三个构造方法 在第三个构造方法里初始化Scroller public class LeftSwipeMenuRecyclerView extends RecyclerView { //置顶按钮 private TextView tvTop; //删除按钮 p

Android自定义ListView实现仿QQ可拖拽列表功能

我们大致的思路,其实是这样子的,也是我的设想,我们可以先去实现一个简单的ListView的数据,但是他的Adapter,我们可以用系统封装好的,然后传递进去一个实体类,最后自定义一个listview去操作,所以我们先把准备的工作做好,比如? list_item.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.a

仿网易新闻客户端

https://github.com/xiangzhihong/newsApp newsApp是一款仿网易新闻的客户端产品,非官方版本,属于个人业余时间做的一个小项目: 界面有一些仿网易新闻客户端 主要用到了网络请求,下拉刷新,指示器,以及一些自定义的动画效果,由于现在流行将代码开源,如实我也开源了几个项目,希望大家喜欢. 主要分为四大板块: [文章] [视频] [论坛] [游戏]   整体架构采用了MVC的设计模式 项目中由于存在大量网络图片,所以采用了二级缓存 主要使用的第三方开源框架有:

SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)

 SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr 源码:http://pan.baidu.com/s/1dETGYGT 应用情景之一:     没太多连续的时间来研究SignalR,所以我把这篇文章分了三个阶段: 第一

Android特效专辑(六)——仿QQ聊天撒花特效,无形装逼,最为致命

Android特效专辑(六)--仿QQ聊天撒花特效,无形装逼,最为致命 我的关于特效的专辑已经在CSDN上申请了一个专栏--http://blog.csdn.net/column/details/liuguilin.html 日后我所写的特效专辑也会以一添加在这个专栏上,今天写的这个特效,是关于聊天的,你肯定遇到过,就是你跟人家聊天的时候,比如发送应(么么哒),然后屏幕上全部就是表情了,今天我们就是做这个,撒花的特效,国际惯例,上图 截图 实现这样的效果,你要知道贝塞尔曲线,何谓贝塞尔曲线?其实

将不定期开放“人人都说Swing丑,唯我独爱它—Swing高仿QQ” 源码

问题描述 从今天开始将会在CSDN上开放Swing高仿QQ的源码.所有信息第一时间在群里公布一起探讨java方面的问题.本群位置有限先来先得所以加群时请注名信息来源地packageclient.login;importjava.awt.EventQueue;importjava.awt.Image;importjava.awt.SplashScreen;importjava.awt.Window;importjava.awt.event.ActionEvent;importjava.awt.ev