jQuery时间轴插件使用详解


Posted in Javascript onJuly 16, 2015

这个时间轴是工作上用到的,自己写了一个, qq空间有时间轴的控件, 百度文库也有时间轴的控件;

百度的时间轴大概是这样的:

jQuery时间轴插件使用详解

用户点击对应的锚链接,  那个三角会滚动, 然后左侧的界面也会滚动;

实际的效果如下图,用户点击左侧的按钮或者右侧的input,滚动条都会主动滚动, 这里有个小技巧就是用after和before伪类生成三角形, 用户点击按钮的滚动效果直接用jq的animate方法:

jQuery时间轴插件使用详解

<!--
//设置内容;
window.onWebMessage( '{"type":"setItems","data":{"items":[{"name":1111},{"name":2222}]}}' ) ;

//设置内容, 对应的item对象如果active为true为激活态;
window.onWebMessage( '{"type":"setItems","data":{"items":[{"name":1000},{"name":1111},{"name":2222},{"name":3333,"active":true}]}}' ) ;

//设置某个第n个位置的item;
window.onWebMessage('{"type":"setItem","data":[2,{ "name" : "add-item"}]}');

//激活第三个锚链接为选中态;
window.onWebMessage( '{"type":"active","data":2}' )

//获取目前的数据:
window.onWebMessage( '{"type":"getItem"}' );
-->

<html>
  <head>
    <meta charset="utf-8" />
    <script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.js"></script>
  </head>
  <style>
    /*初始的reset样式*/
    *{
      margin:0;
      padding:0;
    }
    .time-line-wrap{
      position: relative;
      width: 400px;
      margin:0 auto;
    }
    ul{
      list-style: none;
    }
    body,html{
      height: 100%;
    }
    body{
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }


    /*样式开始*/
    .scroll-time-line{
      height:100%;
      overflow: hidden;
    }
    .time-line-wrap{
      position: relative;
    }
    .time-line-ul{
      position: relative;
    }
    /**
    时间轴的轴用伪类实现;
    */
    .time-line-ul::before{
      display: block;
      position:absolute;
      content:"";
      height:100%;
      width:1;
      left:27px;
      top:0;
      background: #eee;
    }
    .time-line-ul li{
      padding:14px;
      position: relative;
    }
    .time-line-ul input {
      vertical-align: super;
      border-radius: 4px;
      border:1px solid #eee;
      padding:4px;
      line-height: 22px;
      margin-left:10px;
    }
    /**
    使用after和before伪类实现input前面的三角形;
    */
    .time-line-ul li::before{
      position: absolute;
      content: "";
      display: block;
      top: 21px;
      left: 40px;
      width: 0px;
      height: 0px;
      border: 10px solid rgba(0, 0, 0, 0);
      border-right: 10px solid #EEE;
    }
    .time-line-ul li::after{
      position: absolute;
      content: "";
      display: block;
      top: 21px;
      left: 41px;
      width: 0px;
      height: 0px;
      border: 10px solid rgba(0, 0, 0, 0);
      border-right: 10px solid #fff;
    }
    /**
    默认时间轴锚链接的样式
    */
    .time-line-icon{
      width: 26px;
      height: 28px;
      display: inline-block;
      background: url(http://images0.cnblogs.com/blog2015/497865/201507/131424386411828.png);
    }
    /**
    鼠标移动上来,或者锚链接有active时候的背景图样式
    */
    .time-line-icon.active,.time-line-icon:hover{
      background-position: 0px 28px;
    }
  </style>

  <!--模板,勿删!-->
  <script type="text/tempate" id="li-tpl">
    <% for(var i=0; i<items.length; i++ ) {%>
      <li class="li-<%=i%>">
        <a href="###" class="time-line-icon <% if(items[i].active){ %> <%="active"%> <%}%> "></a>
        <input type="text" value="<%=items[i].name%>"/>
      </li>
    <% } %>
  </script>

  <body>
    <!--
    滚动出现在这个div里面
    -->
    <div class="scroll-time-line">

      <!---
      时间轴相关的html结构
      -->
      <div class="time-line-wrap">
        <ul class="time-line-ul">
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
          <li>
            <a href="###" class="time-line-icon"></a> <input type="text" value="2015"/>
          </li>
        </ul>
      </div>
      <!---
      时间轴相关的html结构结束
      -->
    </div>
    <script>
      //模板引擎的代码
      (function () {
        //underscore抄的模板引擎;
        var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;

        var escapes = {
          "'":   "'",
          '\\':   '\\',
          '\r':   'r',
          '\n':   'n',
          '\t':   't',
          '\u2028': 'u2028',
          '\u2029': 'u2029'
        };

        $.templateSettings = {
          evaluate  : /<%([\s\S]+?)%>/g,
          interpolate : /<%=([\s\S]+?)%>/g,
          escape   : /<%-([\s\S]+?)%>/g
        }
        $.template = function(text, data, settings) {
          var render;
          settings = $.extend({}, settings, $.templateSettings);

          // Combine delimiters into one regular expression via alternation.
          var matcher = new RegExp([
            (settings.escape || noMatch).source,
            (settings.interpolate || noMatch).source,
            (settings.evaluate || noMatch).source
          ].join('|') + '|$', 'g');

          // Compile the template source, escaping string literals appropriately.
          var index = 0;
          var source = "__p+='";
          text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
            source += text.slice(index, offset)
                .replace(escaper, function(match) { return '\\' + escapes[match]; });

            if (escape) {
              source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
            }
            if (interpolate) {
              source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
            }
            if (evaluate) {
              source += "';\n" + evaluate + "\n__p+='";
            }
            index = offset + match.length;
            return match;
          });
          source += "';\n";

          // If a variable is not specified, place data values in local scope.
          if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';

          source = "var __t,__p='',__j=Array.prototype.join," +
              "print=function(){__p+=__j.call(arguments,'');};\n" +
              source + "return __p;\n";

          try {
            render = new Function(settings.variable || 'obj', '_', source);
          } catch (e) {
            e.source = source;
            throw e;
          }

          if (data) return render(data, _);
          var template = function(data) {
            return render.call(this, data);
          };

          // Provide the compiled function source as a convenience for precompilation.
          template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';

          return template;
        };
      })();

      (function( fn ) {

        $( fn.call( $ ,$) );

      })(function ($) {

        $.timeLineSetting = {
          offsetTop : 100
        };
        $.extend($.fn, {
          timeLine : function() {
            $.each(this, function() {

              var _this = this;

              $(this).delegate(".time-line-ul>li", "click", function( ev ) {

                $(".time-line-icon.active").removeClass("active");

                $(this).find(".time-line-icon").addClass("active");

                $(_this).animate({scrollTop: this.offsetTop - $.timeLineSetting.offsetTop},300);

                ev.preventDefault();

              });
            });
          }
        });
      });
      $(function() {
        var compile= $.template( $("#li-tpl").html() || "");

        //与客户端的交互事件;
        var orginalData = {};
        window.onWebMessage = function( msg ) {
          msg = JSON.parse(msg);
          switch( msg.type ) {
            case "setItems" :
              $(".time-line-ul").html( compile(msg.data) );
              //结构化复制;
              orginalData = JSON.parse(JSON.stringify(msg.data));
              break;

            case "setItem" :
              orginalData.items&&orginalData.items.splice(msg.data[0],0,msg.data[1]);
              $(".time-line-ul").html( compile(orginalData) );
              break;

            case "getItem" :
                alert(JSON.stringify( orginalData ));
              break;

            case "active" :
              $(".time-line-icon.active").removeClass("active");
              $(".time-line-ul>li").eq( msg.data).find(".time-line-icon").addClass("active")
              break;

          };

        };

        //启用插件;
        $(".scroll-time-line").timeLine();
      })
    </script>
  </body>
</html>

 

模板用了underscore,tempate方法挂到了$下, 作为$的工具方法(依赖于jQuery),模板的js代码直接放这里方便一些小项目直接用:

//模板引擎的代码
      (function () {
        //underscore抄的模板引擎;
        var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;

        var escapes = {
          "'":   "'",
          '\\':   '\\',
          '\r':   'r',
          '\n':   'n',
          '\t':   't',
          '\u2028': 'u2028',
          '\u2029': 'u2029'
        };

        $.templateSettings = {
          evaluate  : /<%([\s\S]+?)%>/g,
          interpolate : /<%=([\s\S]+?)%>/g,
          escape   : /<%-([\s\S]+?)%>/g
        }
        $.template = function(text, data, settings) {
          var render;
          settings = $.extend({}, settings, $.templateSettings);

          // Combine delimiters into one regular expression via alternation.
          var matcher = new RegExp([
            (settings.escape || noMatch).source,
            (settings.interpolate || noMatch).source,
            (settings.evaluate || noMatch).source
          ].join('|') + '|$', 'g');

          // Compile the template source, escaping string literals appropriately.
          var index = 0;
          var source = "__p+='";
          text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
            source += text.slice(index, offset)
                .replace(escaper, function(match) { return '\\' + escapes[match]; });

            if (escape) {
              source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
            }
            if (interpolate) {
              source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
            }
            if (evaluate) {
              source += "';\n" + evaluate + "\n__p+='";
            }
            index = offset + match.length;
            return match;
          });
          source += "';\n";

          // If a variable is not specified, place data values in local scope.
          if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';

          source = "var __t,__p='',__j=Array.prototype.join," +
              "print=function(){__p+=__j.call(arguments,'');};\n" +
              source + "return __p;\n";

          try {
            render = new Function(settings.variable || 'obj', '_', source);
          } catch (e) {
            e.source = source;
            throw e;
          }

          if (data) return render(data, _);
          var template = function(data) {
            return render.call(this, data);
          };

          // Provide the compiled function source as a convenience for precompilation.
          template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';

          return template;
        };
      })();

模板的使用的DEMO如下, 也可以参考官方的文档:http://underscorejs.org/#template:

<html>
  <head>
    <body>
      <script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.js"></script>
      <script>
      //模板引擎的代码
      (function () {
        //underscore抄的模板引擎;
        var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;

        var escapes = {
          "'":   "'",
          '\\':   '\\',
          '\r':   'r',
          '\n':   'n',
          '\t':   't',
          '\u2028': 'u2028',
          '\u2029': 'u2029'
        };

        $.templateSettings = {
          evaluate  : /<%([\s\S]+?)%>/g,
          interpolate : /<%=([\s\S]+?)%>/g,
          escape   : /<%-([\s\S]+?)%>/g
        }
        $.template = function(text, data, settings) {
          var render;
          settings = $.extend({}, settings, $.templateSettings);

          // Combine delimiters into one regular expression via alternation.
          var matcher = new RegExp([
            (settings.escape || noMatch).source,
            (settings.interpolate || noMatch).source,
            (settings.evaluate || noMatch).source
          ].join('|') + '|$', 'g');

          // Compile the template source, escaping string literals appropriately.
          var index = 0;
          var source = "__p+='";
          text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
            source += text.slice(index, offset)
                .replace(escaper, function(match) { return '\\' + escapes[match]; });

            if (escape) {
              source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
            }
            if (interpolate) {
              source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
            }
            if (evaluate) {
              source += "';\n" + evaluate + "\n__p+='";
            }
            index = offset + match.length;
            return match;
          });
          source += "';\n";

          // If a variable is not specified, place data values in local scope.
          if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';

          source = "var __t,__p='',__j=Array.prototype.join," +
              "print=function(){__p+=__j.call(arguments,'');};\n" +
              source + "return __p;\n";

          try {
            render = new Function(settings.variable || 'obj', '_', source);
          } catch (e) {
            e.source = source;
            throw e;
          }

          if (data) return render(data, _);
          var template = function(data) {
            return render.call(this, data);
          };

          // Provide the compiled function source as a convenience for precompilation.
          template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';

          return template;
        };
      })();
      </script>
      <script>
      //会输出 <div>haahah</div>;
      console.log( $.template('<div><%=data%></div>')( {data:"haahah"} ) );
      </script>
    </body>
  </head>
</html>

修改了时间轴的样式, 又为这个插件添加了拖拽的方法,代码一下变得好乱, 顺便普及一下拖拽的事件, ondrop, ondragover,ondrag, 如果要让元素可以拖拽, 就要为要拖拽的元素添加draggable="true",   元素可以拖拽以后 , 要为可以拖放到的的DIV或者其他块元素,绑定一个dragover方法, 这个方法就做一件事, ev.preventDefault(), 看代码撒:

运行下面代码

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8"/>
  <style type="text/css">
    #div1 {width:488px;height:70px;padding:10px;border:1px solid #aaaaaa;}
  </style>
  <script type="text/javascript">
    //当元素dragover时候一定要阻止默认事件, 否则把当前拖拽的元素就无法drop;
    function dragover(ev)
    {
      console.log(ev);
      ev.preventDefault();
    }

    //对于拖拽事件最重要的一个事件属性就是dataTransfer;
    function drag(ev)
    {
      console.log(ev);
      ev.dataTransfer.setData("Text",ev.target.id);
    }

    function drop(ev)
    {
      console.log(ev);
      var data=ev.dataTransfer.getData("Text");
      ev.target.appendChild(document.getElementById(data));
    }
  </script>
</head>
<body>

<p>请把图片拖放到矩形中:</p>

<div id="div1" ondrop="drop(event)" ondragover="dragover(event)"></div>
<br />
<img id="drag1" src="http://images0.cnblogs.com/news/24442/201507/081152502219706.gif" draggable="true" ondragstart="drag(event)" />

</body>
</html>

另外一个DEMO:

运行下面代码

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8"/>
  <style type="text/css">
  </style>
</head>
<body>
  <p>What fruits do you like?</p>
  <ol ondragstart="dragStartHandler(event)">
    <li draggable="true" data-value="fruit-apple">Apples</li>
    <li draggable="true" data-value="fruit-orange">Oranges</li>
    <li draggable="true" data-value="fruit-pear">Pears</li>
  </ol>
  <script>
    var internalDNDType = 'text/x-example'; // set this to something specific to your site
    function dragStartHandler(event) {
      if (event.target instanceof HTMLLIElement) {
        // use the element's data-value="" attribute as the value to be moving:
        event.dataTransfer.setData(internalDNDType, event.target.dataset.value);
        event.dataTransfer.effectAllowed = 'move'; // only allow moves
      } else {
        event.preventDefault(); // don't allow selection to be dragged
      }
    }
  </script>

  <p>Drop your favorite fruits below:</p>
  <ol ondrop="dropHandler(event)" ondragover="dragover(event)">
    <!-- don't forget to change the "text/x-example" type to something
    specific to your site -->
    <li>drop</li>
  </ol>
  <script>
    var internalDNDType = 'text/x-example'; // set this to something specific to your site
    function dropHandler(event) {
      var li = document.createElement('li');
      var data = event.dataTransfer.getData(internalDNDType);
      if (data == 'fruit-apple') {
        li.textContent = 'Apples';
      } else if (data == 'fruit-orange') {
        li.textContent = 'Oranges';
      } else if (data == 'fruit-pear') {
        li.textContent = 'Pears';
      } else {
        li.textContent = 'Unknown Fruit';
      }
      event.target.appendChild(li);
    };
    function dragover(ev) {
      ev.preventDefault();
    };
  </script>
</body>
</html>

 

HTML5的拖拽提供了 setDragImage ,  effectAllowed , setData.... 等很多便捷的方法给开发者,  通过FileReader读取File, 然后就可以用ajax与后台进行交互, 和前端DOM操作:

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8"/>
  <style type="text/css">
  </style>
</head>
<body>
  <div id="div0" ondragover="dragover(event)" ondrop="drop(event)">
    drop拖放文件进来
  </div>
  <script>
    function dragover(ev) {
      ev.preventDefault();
    };
    function drop(ev) {
      var reader = new FileReader();
      reader.onload = function ( ev ) {
        var oDiv = document.createElement("div");
        oDiv.innerHTML = ev.target.result;
        document.body.appendChild( oDiv );
      };
      reader.readAsText( ev.dataTransfer.files[0] );
      ev.preventDefault();
    }
  </script>
</body>
</html>

插件效果图:

jQuery时间轴插件使用详解

最后完成的插件代码:

<!--
//设置内容;
window.onWebMessage( '{"type":"setItems","data":{"items":[{"name":1111,"type":"doc"},{"name":2222,"type":"doc"}]}}' ) ;

window.onWebMessage( '{"type":"setItems","data":{"items":[{"name":"文档类型","type":"doc"},{"name":"音频类型","type":"audio","active":true},{"name":"视频类型","type":"video"},{"name":"单元测试","type":"test"},{"name":"图片类型","type":"pic"}]}}' ) ;

//设置内容, 对应的item对象如果active为true为激活态;
window.onWebMessage( '{"type":"setItems","data":{"items":[{"name":1111,"type":"doc"},{"name":2222,"type":"doc","active":true}]}}' ) ;

//设置某个第n个位置的item;
window.onWebMessage('{"type":"setItem","data":[2,{ "name" : "add-item", "type":"doc"}]}');

//激活第三个锚链接为选中态;
window.onWebMessage( '{"type":"active","data":2}' )

//获取目前的数据:
window.onWebMessage( '{"type":"getItem"}' )
-->

<html>
  <head>
    <meta charset="utf-8" />
    <script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.js"></script>
  </head>
  <style>
    /*初始的reset样式*/
    *{
      margin:0;
      padding:0;
    }
    .time-line-wrap{
      position: relative;
      width: 400px;
      margin:0 auto;
    }
    ul{
      list-style: none;
    }
    body,html{
      height: 100%;
    }
    body{
      background:#303030;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }


    /*样式开始*/
    .scroll-time-line{
      height:100%;
      overflow: hidden;
    }
    .time-line-wrap{
      position: relative;
    }
    .time-line-wrap::before{
      display: block;
      content: "";
      position: absolute;
      border: 2px solid #616161;
      width: 7px;
      background: #303030;
      height: 7px;
      z-index: 2;
      border-radius: 100%;
      left: 12px;
      top: 0;
    }
    .time-line-wrap::after{
      display: block;
      content: "";
      position: absolute;
      border: 2px solid #616161;
      width: 7px;
      background: #303030;
      height: 7px;
      z-index: 2;
      border-radius: 100%;
      left: 12px;
      bottom:0;
    }
    .time-line-ul{
      position: relative;
    }
    /**
    时间轴的轴用伪类实现;
    */
    .time-line-ul::before{
      display: block;
      position:absolute;
      content:"";
      height:100%;
      width:1px;
      left:17px;
      top:0;
      background: #616161;
    }

    .time-line-ul li{
      padding: 14px;
      position: relative;
      color: #FFF;
      height: 26px;
    }
    .time-line-ul li>* {
      vertical-align: middle;
      display: inline-block;
    }

    /**
    为了更好的维护hover的样式, 背景图片通过js进行管理
    hover start;
    */
    .time-line-ul li b{
      width: 32px;
      height: 32px;
    }
    .time-line-ul li b.active{
      display: none;
    }
    .time-line-ul li:hover b{
      display: none;
    }
    .time-line-ul li:hover .active{
      display: inline-block;
    }
    /**
      当li被点击的时候添加的类,优先级
    */
    .time-line-ul li b.show{
      display: none;
    }
    .time-line-ul li b.active.show{
      display: inline-block;
    }
    /**
    hover end
    */

    .time-line-ul li span{
      display: inline-block;
      white-space: nowrap;
      word-wrap: normal;
      width: 100px;
      text-overflow: ellipsis;
      overflow: hidden;
    }
    /**
    当拖拽LI到某个LI上面,这个LI变透明
    */
    .over{
      opacity: 0.4;
    }
    /**
    占位DIV;
    */
    .blank{
      display: block;
      height:50px;
      line-height: 50px;
    }

    /**
    默认时间轴锚链接的样式
    */
    .time-line-icon{
      width: 7px;
      height: 7px;
      display: inline-block;
      background: #616161;
      border-radius: 100%;
    }
    /**
    鼠标移动上来,或者锚链接有active时候的背景图样式
    */
    .time-line-icon.active,.time-line-icon:hover{
      background: #fff;
    }
  </style>

  <!--模板,勿删!-->
  <script type="text/tempate" id="li-tpl">
    <% for(var i=0; i<items.length; i++ ) {%>
      <li class="li-<%=i%>" draggable="true">
        <a href="###" class="time-line-icon <% if(items[i].active){ %> <%="active"%> <%}%> "></a>
        <b class="">
          <img src="imgs/<%=items[i].type%>.png" />
        </b>
        <b class="active">
          <img src="imgs/<%=items[i].type%>1.png" />
        </b>
        <span>
          <%=items[i].name%>
        </span>
      </li>
    <% } %>
  </script>

  <body>
    <!--
    滚动出现在这个div里面
    -->
    <div class="scroll-time-line">

      <!---
      时间轴相关的html结构
      -->
      <div class="time-line-wrap">
        <ul class="time-line-ul">

          <!----假数据--->
          <li class="li-0" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/doc.png">
            </b>
            <b class="active">
              <img src="imgs/doc1.png">
            </b>
            <span>
              文档类型
            </span>
          </li>

          <li class="li-2" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/video.png">
            </b>
            <b class="active">
              <img src="imgs/video1.png">
            </b>
            <span>
              视频类型
            </span>
          </li>


          <li class="li-3" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/test.png">
            </b>
            <b class="active">
              <img src="imgs/test1.png">
            </b>
            <span>
              单元测试
            </span>
          </li><li class="li-1" draggable="true">
          <a href="###" class="time-line-icon active "></a>
          <b class="">
            <img src="imgs/audio.png">
          </b>
          <b class="active">
            <img src="imgs/audio1.png">
          </b>
          <span>
            音频类型
          </span>
        </li>

          <li class="li-4" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/pic.png">
            </b>
            <b class="active">
              <img src="imgs/pic1.png">
            </b>
          <span>
            图片类型
          </span>
          </li>

          <li class="li-0" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/doc.png">
            </b>
            <b class="active">
              <img src="imgs/doc1.png">
            </b>
            <span>
              文档类型
            </span>
          </li>

          <li class="li-2" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/video.png">
            </b>
            <b class="active">
              <img src="imgs/video1.png">
            </b>
            <span>
              视频类型
            </span>
          </li>


          <li class="li-3" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/test.png">
            </b>
            <b class="active">
              <img src="imgs/test1.png">
            </b>
            <span>
              单元测试
            </span>
          </li><li class="li-1" draggable="true">
          <a href="###" class="time-line-icon active "></a>
          <b class="">
            <img src="imgs/audio.png">
          </b>
          <b class="active">
            <img src="imgs/audio1.png">
          </b>
          <span>
            音频类型
          </span>
        </li>

          <li class="li-4" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/pic.png">
            </b>
            <b class="active">
              <img src="imgs/pic1.png">
            </b>
            <span>
              图片类型
            </span>
          </li>

          <li class="li-0" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/doc.png">
            </b>
            <b class="active">
              <img src="imgs/doc1.png">
            </b>
            <span>
              文档类型
            </span>
          </li>

          <li class="li-2" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/video.png">
            </b>
            <b class="active">
              <img src="imgs/video1.png">
            </b>
            <span>
              视频类型
            </span>
          </li>


          <li class="li-3" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/test.png">
            </b>
            <b class="active">
              <img src="imgs/test1.png">
            </b>
            <span>
              单元测试
            </span>
          </li><li class="li-1" draggable="true">
          <a href="###" class="time-line-icon active "></a>
          <b class="">
            <img src="imgs/audio.png">
          </b>
          <b class="active">
            <img src="imgs/audio1.png">
          </b>
          <span>
            音频类型
          </span>
        </li>

          <li class="li-4" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/pic.png">
            </b>
            <b class="active">
              <img src="imgs/pic1.png">
            </b>
            <span>
              图片类型
            </span>
          </li>

          <li class="li-0" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/doc.png">
            </b>
            <b class="active">
              <img src="imgs/doc1.png">
            </b>
            <span>
              文档类型
            </span>
          </li>

          <li class="li-2" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/video.png">
            </b>
            <b class="active">
              <img src="imgs/video1.png">
            </b>
            <span>
              视频类型
            </span>
          </li>


          <li class="li-3" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/test.png">
            </b>
            <b class="active">
              <img src="imgs/test1.png">
            </b>
            <span>
              单元测试
            </span>
          </li><li class="li-1" draggable="true">
            <a href="###" class="time-line-icon active "></a>
            <b class="">
              <img src="imgs/audio.png">
            </b>
            <b class="active">
              <img src="imgs/audio1.png">
            </b>
            <span>
              音频类型
            </span>
          </li>

          <li class="li-4" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/pic.png">
            </b>
            <b class="active">
              <img src="imgs/pic1.png">
            </b>
            <span>
              图片类型
            </span>
          </li>

          <li class="li-0" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/doc.png">
            </b>
            <b class="active">
              <img src="imgs/doc1.png">
            </b>
            <span>
              文档类型
            </span>
          </li>

          <li class="li-2" draggable="true">
            <a href="###" class="time-line-icon "></a>
            <b class="">
              <img src="imgs/video.png">
            </b>
            <b class="active">
              <img src="imgs/video1.png">
            </b>
            <span>
              视频类型
            </span>
          </li>


          <!---假数据end--->

        </ul>
      </div>
      <!---
      时间轴相关的html结构结束
      -->
    </div>
    <script>
      //模板引擎的代码
      (function () {
        //underscore抄的模板引擎;
        var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;

        var escapes = {
          "'":   "'",
          '\\':   '\\',
          '\r':   'r',
          '\n':   'n',
          '\t':   't',
          '\u2028': 'u2028',
          '\u2029': 'u2029'
        };

        $.templateSettings = {
          evaluate  : /<%([\s\S]+?)%>/g,
          interpolate : /<%=([\s\S]+?)%>/g,
          escape   : /<%-([\s\S]+?)%>/g
        }
        $.template = function(text, data, settings) {
          var render;
          settings = $.extend({}, settings, $.templateSettings);

          // Combine delimiters into one regular expression via alternation.
          var matcher = new RegExp([
            (settings.escape || noMatch).source,
            (settings.interpolate || noMatch).source,
            (settings.evaluate || noMatch).source
          ].join('|') + '|$', 'g');

          // Compile the template source, escaping string literals appropriately.
          var index = 0;
          var source = "__p+='";
          text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
            source += text.slice(index, offset)
                .replace(escaper, function(match) { return '\\' + escapes[match]; });

            if (escape) {
              source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
            }
            if (interpolate) {
              source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
            }
            if (evaluate) {
              source += "';\n" + evaluate + "\n__p+='";
            }
            index = offset + match.length;
            return match;
          });
          source += "';\n";

          // If a variable is not specified, place data values in local scope.
          if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';

          source = "var __t,__p='',__j=Array.prototype.join," +
              "print=function(){__p+=__j.call(arguments,'');};\n" +
              source + "return __p;\n";

          try {
            render = new Function(settings.variable || 'obj', '_', source);
          } catch (e) {
            e.source = source;
            throw e;
          }

          if (data) return render(data, _);
          var template = function(data) {
            return render.call(this, data);
          };

          // Provide the compiled function source as a convenience for precompilation.
          template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';

          return template;
        };
      })();

      (function( fn ) {

        $( fn.call( $ ,$) );

      })(function ($) {

        $.timeLineSetting = {
          offsetTop : 100
        };

        $.extend($.fn, {
          timeLine : function() {
            $.each(this, function() {

              var _this = this,
                  eleDrag;
              $(this).delegate(".time-line-ul>li", "click", function( ev ) {
                $(".time-line-icon.active").removeClass("active");
                $(this).find(".time-line-icon").addClass("active");
                $("b").removeClass("show");
                $(this).find("b").addClass("show");
                $(_this).animate({scrollTop: this.offsetTop - $.timeLineSetting.offsetTop},300);
                ev.preventDefault();
              }).delegate(".time-line-ul>li","dragstart" , function(ev) {
                //不允许img和a的拖拽;
                if( ev.target&&ev.target.tagName.toLocaleLowerCase() === "img" || ev.target.tagName.toLocaleLowerCase() === "a") {
                  return false;
                };
                /*拖拽开始*/
                //拖拽效果
                ev.originalEvent.dataTransfer.effectAllowed = "move";
                eleDrag = ev.originalEvent.target;
                return true;
              }).delegate(".time-line-ul>li","dragenter" , function(ev) {
                return true;
              }).delegate(".time-line-ul>li", "dragover" , function(ev) {
                $(".time-line-ul>li.over").removeClass("over");
                $(this).addClass("over");
                $(".blank").remove();
                var $blank = $("<li class='blank' draggable='true'></li>");
                $(this).after( $blank );
                /*拖拽元素在目标元素头上移动的时候*/
                ev.preventDefault();
                return true;
              });
              $(".time-line-ul").bind("drop" , function(ev) {
                if(ev.target.tagName.toLocaleLowerCase() === "li") {
                  $(ev.target).after( eleDrag );
                };
                $(".blank").remove();
                $(".time-line-ul>li.over").removeClass("over");
                return false;
              });
            });
          }
        });
      });

      $(function() {
        var compile= $.template( $("#li-tpl").html() || "");

        //与客户端的交互事件;
        var orginalData = {};
        window.onWebMessage = function( msg ) {
          msg = JSON.parse(msg);
          switch( msg.type ) {
            case "setItems" :
              $(".time-line-ul").html( compile(msg.data) );
              //结构化复制;
              orginalData = JSON.parse(JSON.stringify(msg.data));
              break;

            case "setItem" :
              orginalData.items&&orginalData.items.splice(msg.data[0],0,msg.data[1]);
              $(".time-line-ul").html( compile(orginalData) );
              break;

            case "getItem" :
                var result = [];
                var lis = $(".time-line-ul li");
                for(var i=0; i<lis.length; i++) {
                  result.push( {
                    index : i,
                    src : $(lis[i]).find("img").attr("src"),
                    name : $(lis[i]).find("span").text()
                  });
                };
                alert(JSON.stringify( result ));
              break;

            case "active" :
              $(".time-line-icon.active").removeClass("active");
              $(".time-line-ul>li").eq( msg.data).find(".time-line-icon").addClass("active")
              break;

          };

        };

        //启用插件;
        $(".scroll-time-line").timeLine();
      })
    </script>
  </body>
</html>

以上所述就是本文的全部内容了,希望大家能够喜欢。

Javascript 相关文章推荐
jQuery中:has选择器用法实例
Dec 30 Javascript
原生javascript实现简单的datagrid数据表格
Jan 02 Javascript
JavaScript实现快速排序的方法
Jul 31 Javascript
详解JavaScript逻辑And运算符
Dec 04 Javascript
JavaScript算法系列之快速排序(Quicksort)算法实例详解
Sep 04 Javascript
JS实现的简单图片切换功能示例【测试可用】
Feb 14 Javascript
xmlplus组件设计系列之树(Tree)(9)
May 02 Javascript
使用jQuery.Pin垂直滚动时固定导航
May 24 jQuery
JavaScript表单即时验证 验证不成功不能提交
Aug 31 Javascript
详解webpack 入门与解析
Apr 09 Javascript
原生JS实现拖拽功能
Dec 16 Javascript
如何在VUE中使用vue-awesome-swiper
Jan 04 Vue.js
jQuery实现定时读取分析xml文件的方法
Jul 16 #Javascript
Javascript函数的参数
Jul 16 #Javascript
Javascript简单改变表单元素背景的方法
Jul 15 #Javascript
JavaScript基于ajax编辑信息用法实例
Jul 15 #Javascript
JavaScript实现对下拉列表值进行排序的方法
Jul 15 #Javascript
jQuery简单实现验证邮箱格式
Jul 15 #Javascript
JavaScript截断字符串的方法
Jul 15 #Javascript
You might like
PHP学习之输出字符串(echo,print,printf,print_r和var_dump)
2011/04/17 PHP
详解PHP中mb_strpos的使用
2018/02/04 PHP
PHP使用Curl实现模拟登录及抓取数据功能示例
2018/04/27 PHP
tp5(thinkPHP5)框架连接数据库的方法示例
2018/12/24 PHP
对laravel的session获取与存取方法详解
2019/10/08 PHP
JavaScript获取页面上某个元素的代码
2011/03/13 Javascript
JavaScript高级程序设计 XML、Ajax 学习笔记
2011/09/10 Javascript
js自动生成对象的属性示例代码
2013/10/28 Javascript
jquery禁止输入数字以外的字符的示例(纯数字验证码)
2014/04/10 Javascript
extjs 如何给column 加上提示
2014/07/29 Javascript
JS打字效果的动态菜单代码分享
2015/08/21 Javascript
谈一谈jQuery核心架构设计
2016/03/28 Javascript
JavaScript中的原型继承基础学习教程
2016/05/06 Javascript
基于jQuery倒计时插件实现团购秒杀效果
2016/05/13 Javascript
jQuery插件学习教程之SlidesJs轮播+Validation验证
2016/07/12 Javascript
浅析JavaScript中的array数组类型系统
2016/07/18 Javascript
前端弹出对话框 js实现ajax交互
2016/09/09 Javascript
详解MVC如何使用开源分页插件(shenniu.pager.js)
2016/12/16 Javascript
浅谈MUI框架中加载外部网页或服务器数据的方法
2018/01/31 Javascript
微信小程序支付功能 php后台对接完整代码分享
2018/06/12 Javascript
Vue 中文本内容超出规定行数后展开收起的处理的实现方法
2019/04/28 Javascript
浅谈微信小程序列表埋点曝光指南
2019/10/15 Javascript
vue路由分文件拆分管理详解
2020/08/13 Javascript
Vue页面跳转传递参数及接收方式
2020/09/09 Javascript
ant design vue嵌套表格及表格内部编辑的用法说明
2020/10/28 Javascript
使用优化器来提升Python程序的执行效率的教程
2015/04/02 Python
详解Django中的form库的使用
2015/07/18 Python
python 调试冷知识(小结)
2019/11/11 Python
利用PyQt5+Matplotlib 绘制静态/动态图的实现代码
2020/07/13 Python
CSS3 Flex 弹性布局实例代码详解
2018/11/01 HTML / CSS
娇韵诗法国官网:Clarins法国
2019/01/29 全球购物
LACOSTE波兰官网:Polo衫、服装和鞋类
2020/09/29 全球购物
白鹤梁导游词
2015/02/06 职场文书
2016年公务员六五普法心得体会
2016/01/21 职场文书
斗罗大陆八大特殊魂兽,龙族始祖排榜首,第五最残忍(翠魔鸟)
2022/03/18 国漫
Centos7 Shell编程之正则表达式、文本处理工具详解
2022/08/05 Servers