网站首页 » 前端开发 » JavaScript » 纯 JavaScript 实现单条新闻滚动效果
上一篇:
下一篇:

纯 JavaScript 实现单条新闻滚动效果

前言

单条新闻滚动效果相信你已经见过不少了,这个效果在很多导航页面中或多或少都会出现。最近我们360导航中就看到了这个效果,可当我研究下这是怎么实现的时候,竟然有意外的收获,这个页面里用到的方法是我从来都没有想过的,不过我也不知道我的猜测对不对,光从页面中的 HTML 结构及运动效果我大概地想到了这是如何实现的,但到底不是不真的像我想的那样,那就不一定了。好了费话不多说,我们还是来看看这个效果是怎么实现的。

在实现之前我们还是来看看这个页面当中的效果是怎么样子的。这里给你贴个传送门 https://hao.360.cn/,你可以看看页面右上角的新闻滚动效果。这个效果看起还是蛮不错的,也非常实用,所以自己收藏一个这样的插件还是非常有必要的。

效果示例: http://yunkus.com/demo/news-scroll/javascript-news-scroll-demo.html

思路分析

我一开始还以为360导航这个页面的新闻滚动效果是用我一往认的的方法实现上下滚动标题的,但当我仔细一看HTML代码结构及运动过程时才发现,这个效果的实现方法超乎我想象。大概的过程是先让第一个上标题的margin-top:移动一个标题高度,当移动完之后,随即把第一个子元素通过appendChild()方法放到了其它子元素的后面,如此类推,就实现了新闻滚动效果。说起来简单,那用代码实现起来究竟是不是也如此简单呢?我们直接来看代码。

代码实现

下面我就把这个效果的完整的一套实现方案贴出来,这里只是给你分析一个大概的思路,如果想做更加个性化的修改那你得自己动动手了,不过就下面这个例子应该都够你用了。

CSS样式

.news-list{list-style: none;height: 20px;overflow: hidden;}
.news-list li{line-height: 20px;font-size: 12px}
.news-list li a{color: #666;text-decoration: none}
.news-list li a:hover{text-decoration:underline;}

HMTL代码

<div id="news">
 <ul class="news-list">
  <li><a href="http://yunkus.com/centos7-nginx-service-install-config/" class="text">Centos 7 nginx 服务安装及配置</a></li>
  <li><a href="http://yunkus.com/centos7-ftp-apache-php-mariadb-uninstall/" class="text">Centos 7 Apache,php,MariaDB,FTP的卸载方法</a></li>
  <li><a href="http://yunkus.com/centos-7-php-service-install-config/">Centos 7 php 环境安装及配置</a></li>
  <li><a href="http://yunkus.com/meta-viewport-usage/" class="text">meta viewport 你真的了解吗?</a></li>
  <li><a href="http://yunkus.com/centos7-mariadb-database-service-install-config/" class="text">Centos 7 MariaDB 数据库服务安装及配置</a></li>
  <li><a href="http://yunkus.com/centos7-apache-service-install-config/" class="text">Centos 7 Apache 服务安装及配置</a></li>
  <li><a href="http://yunkus.com/centos7-ftp-service-install-config/" class="text">Centos 7 FTP(vsftp)服务安装及配置</a></li>
  <li><a href="http://yunkus.com/css-clip-path/" class="text">CSS3 clip-path 用法详解</a></li>
  <li><a href="http://yunkus.com/css-writing-mode-property/" class="text">CSS 中改变横纵方向 writing-mode 属性</a></li>
  <li><a href="http://yunkus.com/animate-css-tutorial/" class="text">Animate.css 使用教程(一个强大的 CSS3 动画库)</a></li>
 </ul>
</div>

JavaScript 代码

var newWrap = document.getElementById('news');
slideoneNews(newWrap);
function slideoneNews(warap){
 var newsMain = newWrap.getElementsByTagName('ul')[0];
 var newsItem = newsMain.getElementsByTagName('li');
 var newsItemH = newsItem[0].offsetHeight;
 var newsTimer = null;
 newsTimer = setInterval(function(){moveNews(newsItem[0],newsItemH)},3000);
 function moveNews(obj,target){
  var moveTimter = null;
  var num = 0;
  var temp = null;
  moveTimter = setInterval(function(){
   if(num != target || num > target){
    num = num+0.5;
    newsItem[0].style.marginTop = -num + 'px';
   }else{
    for(var i=0;i<newsItem.length;i++){
      newsItem[i].style.marginTop = '';
    }
     clearInterval(moveTimter);
     newsMain.appendChild(newsItem[0]);
   }
  },10)
}
 newWrap.onmouseover = function(){
  clearInterval(newsTimer);
 }
 newWrap.onmouseout = function(){
  newsTimer = setInterval(function(){moveNews(newsItem[0],newsItemH)},3000);
 }
}

就这样就实现了一个纯 JavaScript 实现的新闻滚动效果。值得高兴的是这个方法兼容性非常地强 IE5 也不在话下。这也是我意想不到的。比我想象中的强大。你也可以照猫画虎,把这个思路用到其它地方,实现其实不同的效果。只要你敢想敢试,还有什么是不可能的吗?

下面是另一种实现方式,代码得到了更好的组织,原理差不多,请看:

function ScrollList(option){
    this.el = option.el; 
    this.data = option.data;
    this.attr = option.attr || "title"; // 默认对象字段名
    this.time = option.time || 1500; //切换时间间隔
    this.showNum = option.showNum || 5;  // 显示条数
    this.dataNum = option.data.length;
    this.firstLi = null;
    this.lis = null;
    this.dataIndex = this.showNum;
    this.itemHeight;
    this.supportEvent;
    if(this.dataNum <= this.showNum){
        this.isEnough = false;
        this.showNum = this.dataNum;
    }else{
        this.isEnough = true;
    }
}

ScrollList.prototype.init = function(){
    this.create();
    this.setStyle();
    this.getSupportEvent();
    this.addEvent(this.firstLi);
    this.runScroll();
}

ScrollList.prototype.getSupportEvent = function(){
    var  transitions = {
        'transition':'transitionend',
        'OTransition':'oTransitionEnd',
        'MozTransition':'transitionend',
        'WebkitTransition':'webkitTransitionEnd'
      }
      var t;
      for(t in transitions){
          if( this.firstLi.style[t] !== undefined ){
            this.supportEvent = transitions[t];
          }
      }
}

ScrollList.prototype.create = function(){
    if(this.isEnough){
        var eleN = this.showNum + 1;
    }else{
        eleN = this.showNum;
    }
    var fragment = document.createDocumentFragment();
    for(var i=0;i<eleN;i++){
       var oLi = document.createElement("li");
       fragment.appendChild(oLi);
    }
    this.el.appendChild(fragment);
   
    // 获取所创建的元素,并添加内容
    this.lis = this.el.getElementsByTagName("li");
    for(var k=0;k<eleN;k++){
        this.lis[k].innerText = this.data[k].title;
    }
}

ScrollList.prototype.setStyle = function(){
    var el = this.el;
    this.firstLi = el.firstElementChild;
    this.itemHeight = this.firstLi.offsetHeight;
    el.style.height = this.showNum * this.itemHeight + "px";
}

ScrollList.prototype.runScroll = function(){
    var _this = this;
    var el = _this.el;
    if(!this.isEnough){ // 如果条数小于要显示的数量则不自动滚动
        return;
    }
    setInterval(function(){
        var currentFirstLi = el.firstElementChild;
        _this.addEvent(el.firstElementChild);
        currentFirstLi.style.height = 0;
        currentFirstLi.style.transform = "scale(0)";
    },this.time);
}

ScrollList.prototype.addEvent = function(firstLi){
        var _this = this;
        this.supportEvent && firstLi.addEventListener(this.supportEvent,eventHandler);
        function eventHandler(){
            _this.el.appendChild(this);
            if(_this.dataIndex >= _this.dataNum){
                _this.dataIndex = 0;
            }
            this.innerText = _this.data[_this.dataIndex++][_this.attr];
            this.removeEventListener(_this.supportEvent,eventHandler,false);//销毁事件
            this.style = "";
            // this.removeAttribute("style");
        }
}

// 使用方法
var oUl = document.getElementById("new-list");
var scrollNews = new ScrollList({
    el:oUl,
    data:data,
    showNum:9
})
scrollNews.init();

第二个例子使用了 CSS3 的一些新特性,如果你想兼容更低版本,可以自行修改对应的代码。

知识点

说到最后我们还是得看看这个appendChild() 方法的定义和用法。

appendChild()方法向节点添加最后一个子节点。
提示:如果您需要创建包含文本的新段落,请记得添加到段落的文本的文本节点,然后向文档添加该段落。
您也可以使用appendChild()方法从一个元素向另一个元素中移动元素。

看完这个定义后,眼前突然就一亮了,并且发现很多东西都是你遇到了之后再去了解这是一个什么样的东西,它有什么用等等疑问,可能可以让你对这个东西更加有感触。

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/javascript-news-scroll/

Leave a Reply

Your email address will not be published. Required fields are marked *

评论 END