jQ插件--时间线插件和拖拽API

时间:2023-03-09 09:51:17
jQ插件--时间线插件和拖拽API

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

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

  jQ插件--时间线插件和拖拽API

  用户点击对应的锚链接,  那个三角会滚动jQ插件--时间线插件和拖拽API, 然后左侧的界面也会滚动;

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

  jQ插件--时间线插件和拖拽API

  点击查看DEMO:打开

<!--
//设置内容;
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>

  插件效果图:

jQ插件--时间线插件和拖拽API

  最后完成的插件代码:

<!--
//设置内容;
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>

  FileReader的API

  FILE的API

  HTML拖拽API

作者: NONO
出处:http://www.cnblogs.com/diligenceday/

QQ:287101329