原生JavaScript实现图片轮播及前端学习心得

作者:代码拾荒时间:2026-10-30 12:36:02浏览:584

本文详细讲解如何使用原生JavaScript实现图片轮播效果,涵盖HTML结构、CSS样式控制及JS逻辑实现。同时分享了前端初学者从HTML5到JavaScript的学习路径,针对学习过程中遇到的迷茫期提供实用建议,强调通过动手实践和巩固基础来建立前端知识体系。

前端学习心得与规划

开发过程中频繁听到对各类插件的依赖请求。虽然引入第三方插件能显著提升开发效率,但作为初学者,笔者更倾向于自主实现功能,主要原因在于拥有充足的学习时间。

原生JS轮播实现教程

本文将分享使用原生JavaScript编写图片轮播组件的具体方法。

经验丰富的开发者可跳过以下个人经验分享部分。

在正式进入技术细节前,先总结自接触前端以来约两个月的学习体会。目前每天保持6至10小时的学习投入,完全依靠自学。尽管外界有观点认为培训效果有限,但笔者目前仅掌握HTML5、CSS3和JavaScript这三大基础技术,其他知识模块均列入后续学习计划。当前处于方向迷茫期,不确定下一步的学习重点,因此决定先扎实掌握这三大基础技术,恳请资深前辈给予指导建议。

从HTML5到CSS3,一路过来,感觉前端挺简单的,就有点信心满满,动力十足,接着学JS,以前学过C#、苹果的swift,都是面向对象的强类型的语言,比较先进,不过我还是喜欢前端,所以转到这里来了,开始学JS也觉得挺容易的,就是感觉这门语言有点乱,跟别人不太一样!而权威指南有些东西不容易弄明白,没办法,就多百度,多看别人对一些比如闭包、原型等概念的理解,慢慢的也就能掌握的7788了,到了这个阶段,你也许已经慢慢的了解到,原来前端它包括很多东西!一堆的第三方类库、框架等等,还有很多其它东西,总之,新名词不断的在你眼前冒出来,有的说这个要过时了,那个即将是主流,好乱!好乱!接下去我该怎么走?先学什么?后学什么?

笔者当前正经历这一迷茫阶段,有时连续两天无法专注学习,甚至影响睡眠,感到心烦意乱,仿佛陷入“走火入魔”的状态。

反思当前状态,试图理清原因未果。于是决定暂时休息,通过跑步和散步来调整身心状态,思考如何重新进入高效学习模式。

最终的解决策略是:通过完成一些简单的实例来重建信心(即“给自己点糖吃”)。

实践发现,这种策略效果显著。成功完成简单实例带来了强烈的成就感,从而恢复了学习动力。通过逐个实例的编写,遇到不懂之处或API不熟悉时,先查阅官方文档,在参考他人代码前先尝试独立编写,实在无法解决再寻求外部帮助。逐步地,笔者感觉重新找回了状态,学习步入正轨。

此外,笔者调研了当前大多数招聘前端岗位的公司对人才的需求,据此重新制定了学习计划。鉴于目前时间充裕,计划先集中一段时间巩固HTML、CSS和JavaScript这三大基础,通过大量练习加深理解,随后再系统回顾文档,深入探究其底层原理。这样无论后续学习何种新技术,都能更快上手。同时,持续了解前端技术发展趋势及职业前景,旨在构建完整的前端知识世界观,以避免在学习过程中迷失方向。

关于具体应学习哪些第三方类库或框架,目前尚不明确。例如jQuery是否已过时、是否需要学习等问题,暂且搁置,优先专注于原生JavaScript的实践,未来自然会清晰。

接下来进入实战环节,展示相关代码及演示效果。

对于面向对象的高级写法,笔者目前尚无法掌握,仅能编写函数式代码。图片素材来源于网络,也可自行制作300x200像素的图片进行测试,点击“渐进渐出”按钮即可启动效果。


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
  <style>
    *{
      margin: 0;
      padding: 0;
      list-style: none;
      text-decoration: none;
    }
    #slide{
      position: absolute;
      top: 100px;
      left: 50px;
      width: 300px;
      height: 200px;
      border: 1px solid gray;
    }
    #slide .blog-name{
      display: block;
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100%;
      height: 25px;
      line-height: 25px;
      background-color: rgba(155,155,155,0.5);
      z-index: 4;
      cursor: pointer;
      text-indent: 3px;
    }
    #slide-nav{
      position: absolute;
      right: 5px;
      bottom: 5px;
      z-index: 5;
    }
    #slide-nav li{
      display: inline-block;
      width: 16px;
      text-align: center;
      line-height: 16px;
      border-radius: 5px;
      cursor: pointer;
      overflow:hidden;
    }
    #slide-nav li:hover,.selected{
      background-color: #336699;
      color: white;
    }
    .slide-content1{
      position: absolute;
      width: 300px;
      height: 200px;
      font-size: 0;
    }
    .slide-content1 a{
      position: absolute;
      cursor: pointer;
    }
    .slide-content1 a:visited{color: black;}
    #model-btn{
      position: absolute;
      top: -25px;
      font-size: 20px;
    }
  </style>
  <script>
    window.onload = function(){
      var sufuImageScrooller = function(){
        //几个工具函数
        function show(img){
          var id;
          for ( var i = 0; i <= 21; i++) {
            var op = i * 5;
            id = setTimeout(function(e) {
              setOpacity(img, e)
            }.bind(this,op), i * 50);
          }
          clearTimeout(id);
        }
        function hide(img){
          var id;
          for ( var i = 0; i <= 21; i++) {
            var op = 100 - i * 5;
            id = setTimeout(function(e) {
              setOpacity(img, e)
            }.bind(this,op), i * 20);
          }
          clearTimeout(id);
        }
        function getById(id){
          return document.getElementById(id);
        }
        function setOpacity(elem,level){
          if(elem.filter){
            elem.style.filter = "alpha(opacity=" + level + ")"; //兼容IE
          }else{
            elem.style.opacity = level/100;
          }
        }
        //(渐进渐出模式)主体函数
        function inOutModel(nums,navId,imgContainerId,imgInfoId,delay){
          //防止多次点击模式选择按钮创建更多的li
          if(getById('slide-nav').childElementCount !== 0){return}
          //创建导航按钮
          var nav = [];
          var targetIdext = 0; //保存图片状态信息
          var cureentIdext = 0; //保存图片状态信息
          var frag = document.createDocumentFragment();
          for(var i=0;i<nums;i++){
            nav[i] = frag.appendChild(document.createElement('li')); //appendChild方法会返回该li
            nav[i].innerHTML = i+1;
          }
          getById(navId).appendChild(frag);
          //初始化为显示第一张图片
          var imgs = getById(imgContainerId).getElementsByTagName('a');
          var info = getById(imgInfoId);
          info.innerHTML = imgs[0].title.slice(0,12)+'...';
          nav[0].className = 'selected'; //动态改变li的className来改变它的样式
          for(var j=1;j<nav.length;j++){
            setOpacity(imgs[j],0);
          }
          //开始自动轮播
          var id;
          function start(delay){
            id = setInterval(function(){
              hide(imgs[cureentIdext]);
              nav[cureentIdext].className = '';
              if(targetIdext<nums-1){
                targetIdext ++;
              }else{
                targetIdext = 0;
              }
              cureentIdext = targetIdext;
              show(imgs[targetIdext]);
              nav[targetIdext].className = 'selected';
              info.innerHTML = imgs[targetIdext].title.slice(0,12)+'...';
            },delay);
          }
          start(delay);
          //为每个导航按钮添加事件
          for(var k=0;k<nav.length;k++){
            nav[k].onclick = function(event){
              var e = event||window.event; //兼容IE
              var t = event.target||event.srcElement; //兼容IE
              var idex = parseInt(t.innerHTML)-1;
              console.log('idex:'+idex+' t:'+targetIdext+' c:'+cureentIdext);
              if(idex === cureentIdext){return;}
              hide(imgs[cureentIdext]);
              nav[cureentIdext].className = '';
              cureentIdext = idex;
              show(imgs[idex]);
              nav[idex].className = 'selected';
              info.innerHTML = imgs[idex].title.slice(0,12)+'...';
            }
          }
          getById(navId).onmouseover = function(){clearInterval(id)};
          getById(navId).onmouseout = function(){start(delay)};
        }
        //从右向左模式函数
        function fromRightModel(nums,navId,imgContainerId,imgInfoId,delay){
          alert('博主偷懒,忘记实现这个函数了!需要请留言!');
        }
        function fromTopModel(nums,navId,imgContainerId,imgInfoId,delay){
          alert('博主偷懒,忘记实现这个函数了!需要请留言!');
        }
        return {
          inOutModel: inOutModel,
          fromRightModel: fromRightModel,
          fromTopModel: fromTopModel,
          getById: getById
        }
      }();
      sufuImageScrooller.getById('model-btn1').onclick = function(){
          sufuImageScrooller.inOutModel(5,'slide-nav','slide-main','slide-info',3500);
      };
      sufuImageScrooller.getById('model-btn2').onclick = function(){
        sufuImageScrooller.fromRightModel(5,'slide-nav','slide-main','slide-info',3500);
      };
      sufuImageScrooller.getById('model-btn3').onclick = function(){
        sufuImageScrooller.fromTopModel(5,'slide-nav','slide-main','slide-info',3500);
      };
    };
  </script>
</head>
<body>
<div id="slide">
  <a id="slide-info" class="blog-name" href="http://www.cnblogs.com/susufufu/" target="_blank">苏福的博客</a>

  <ul id="slide-nav">
  </ul>

  <div id="slide-main" class="slide-content1 slide-content2">
    <a class="a-img" title="用原生JS读写CSS样式的方法总结" href="http://www.cnblogs.com/susufufu/p/5749922.html" target="_blank">
      <div>
        <img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1247027539,1217965501&fm=21&gp=0.jpg">
      </div>
    </a>
    <a class="a-img" title="DOM中的事件处理概览与原理" href="http://www.cnblogs.com/susufufu/p/5768431.html" target="_blank">
      <div>
        <img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=4286855119,2694540617&fm=21&gp=0.jpg">
      </div>
    </a>
    <a class="a-img" title="选取文档元素的方法总结" href="http://www.cnblogs.com/susufufu/p/5738673.html" target="_blank">
      <div>
        <img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4042865154,1782505495&fm=21&gp=0.jpg">
      </div>
    </a>
    <a class="a-img" title="窗口、窗体之间的关系" href="http://www.cnblogs.com/susufufu/p/5714020.html" target="_blank">
      <div>
        <img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2603911195,1920098549&fm=21&gp=0.jpg">
      </div>
    </a>
    <a class="a-img" title="你真的知道setTimeout是如何运行的吗?" href="http://www.cnblogs.com/susufufu/p/5759480.html" target="_blank">
      <div>
        <img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4104312586,1589909074&fm=21&gp=0.jpg">
      </div>
    </a>
  </div>
  
  <div id="model-btn">
    <input type="button" id="model-btn1" value="渐进渐出">
    <input type="button" id="model-btn2" value="从右向左">
    <input type="button" id="model-btn3" value="从上至下">
  </div>
</div>

</body>
</html>

实现思路主要利用定时器控制图片切换,并通过改变图片的opacity属性来实现过渡动画效果。

HTML结构设计

一、HTML结构较为简单:


<ul id="slide-nav">
 </ul>

<div id="slide-main" class="slide-content1">
    <a class="a-img" title="" href="" target="_blank">
      <div>
        <img src="lg1.png">
      </div>
    </a>
    ...
</div>
...

其中,slide-info用于显示图片标题,slide-nav为数字导航按钮容器,slide-main为图片容器,内部存放图片链接。

注意,HTML标签中未预先编写li元素,因为这些列表项是通过JavaScript动态创建的。

CSS样式关键点

二、CSS样式设置方面,通过亲自实践即可理解,需注意以下几点:

在自定义布局前,建议先为父元素添加边框(border),以便清晰观察布局结构,确认无误后再移除边框。

ul、li等标签默认带有padding值,因此需将其设置为0以消除默认间距。


*{ margin: 0; padding: 0; list-style: none; text-decoration: none; }

height: 25px;和line-height: 25px;两个相等,可以让字居中

z-index属性仅对兄弟元素及子元素生效,对非直接关联的元素无效。若需将某元素置于其他元素前方,需调整其祖先元素的层级,例如,若你的父辈地位高于旁系亲属的父辈,则你的层级自然高于旁系亲属。

position: absolute;属性的定位参照物是其最近的已定位祖先元素。若父元素未设置定位,则需继续向上查找,直至找到设置了定位属性的祖先元素为止。

若需实现从右向左的轮播效果,需注意设置font-size: 0;以清除图片间的空白间距,使图片紧密排列。

俗话说熟能生巧,只有CSS基础扎实,才能精准把控布局。例如双飞翼布局,无需定位即可实现。


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
  <style>
    body{
      margin: 0;
      padding: 0;
    }
    .header,.footer{
      width: 100%;
      height: 50px;
      line-height: 50px;
      text-align: center;
      background-color: greenyellow;
    }
    .container{
      overflow: hidden;
      *zoom: 1;
    }
    .left{
      float: left;
      width: 100px;
      height: 100px;
      margin-left: -100%;
      background-color: green;
    }
    .main{
      float: left;
      width: 100%;
      height: 100px;
      background-color: gray;
    }
    .right{
      float: left;
      width: 200px;
      height: 100px;
      margin-left: -200px;
      background-color: gold;
    }
    .center{
      padding-left: 100px;
      padding-right: 200px;
    }
  </style>
</head>
<body>
<div class="header">header</div>
<div class="container">
  <div class="main">
    <div class="center">main-center</div>
  </div>
  <div class="left">left</div>
  <div class="right">right</div>
</div>
<div class="footer">footer</div>
</body>
</html>

JavaScript代码实现

三、代码实现部分

首先编写代码大纲:


var sufuImageScrooller = function(){
function getById(id){...} //通用获取元素对象
function setOpacity(elem,level){...} //设置透明度
function hide(img){...} //淡入
function show(omg){...} //淡出
function inOutModel(nums,navId,imgContainerId,imgInfoId,delay){ ... } //主函数体
return {
inOutModel: inOutModel,
...
}
}();

通过sufuImageScrooller对象调用inOutModel方法即可实现功能,调用示例为:sufuImageScrooller.inOutModel(5,'slide-nav','slide-main','slide-info',3500);。参数说明如下:nums指定创建的li数量,必须与图片数量一致;navId为数字按钮容器的id;imgContainerId为图片容器的id;imgInfoId为显示图片标题信息的id;delay指定切换图片的延迟时间(毫秒)。

大纲完成后,项目已完成大半,剩余部分为具体细节代码的实现。笔者代码编写能力有限,仅实现了基本功能,欢迎大家提出改进建议。从inOutModel函数入手,逐步深入细节,关键在于动手编写代码,仅阅读代码难以获得深刻体会。

介绍至此结束,如有疑问请多查阅文档API,也可在评论区留言咨询。

以上关于原生JavaScript实现轮播效果及前端学习心得的内容分享完毕,希望能对大家有所帮助,欢迎支持本站。

作者最新文章