文字搬运工 【总结】
需求
需求分析
1.文字挨个从左往右移:左边删掉第一个,右边添加刚刚删掉的
2.移动过程中,按钮不能重复点击
3.有进度条,进度条延迟消失
4.有统计数字
难点
无
难点解决方案
无
解决不了的难点
无
涉及的新知识
str.substring()字符串截取方法
优化方向
少用全局变量,开头空格也能移动
备注
将来可以用jQ写的更简洁一点
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> *{ margin: 0; padding: 0; } .wrap{ position: absolute; top: 10%; left: 15%; } .wrap > *{ float: left; } input[type = 'button']{ border: none;width: 80px; height: 30px; background: #9C27B0; color: #fff; cursor: pointer; outline: none; margin-left: 35px; } input[type = 'button']:hover{ background: #831f94; } input[type = 'button']:active{ background: #673ab7; } #act{ width: 150px; } li{ list-style-type: none; } </style> </head> <body> <div class="wrap"> <textarea style="resize: none; width: 400px; height: 200px; font-size: 18px;"></textarea> <div id="act"> <input type="button" value="文字移动"> </div> <p style="overflow-y: scroll; word-wrap: break-word; width: 400px; height: 200px; font-size: 18px; border: 1px solid #999;"></p> </div> <script src="getId.js"></script> <script src="doMove.js"></script> <script src="main.js"></script> </body> </html>
// moveStr(oTextarea); 为文字移动的函数,要传入输入区 // moveStrip(); 为进度条跑动函数 // hideStrip(); 为渐隐进度条的函数,透明度为0后翻转开关,moveStrip();的下一次定时器会检测到开关已关闭而停止进度条走动 // rateStrip(); 为生成进度条的函数 //找输入区和输出区 var oTextarea = document.getElementsByTagName('textarea')[0]; var p = document.getElementsByTagName('p')[0]; //按钮 var btnWrap = $('act'); var oBtn = btnWrap.getElementsByTagName('input')[0]; var rStrip = rateStrip(); //开关,用于禁止连续点击 oBtn.onOff = true; oBtn.onclick = function(){ if(oBtn.onOff){ //点击设置开关为关闭,显示进度条,清空输出区,再调用文字移动函数和进度条跑动函数 oBtn.onOff = !oBtn.onOff; rStrip.style.opacity = 1; p.innerHTML = ''; moveStr(oTextarea); moveStrip(); } } function moveStr(oTextarea){ /*原理:substring从下标1截取后面的字符存在newStr中, substring从0开始取1个字符存在cutStr中, 输入区用newStr更新,输出区添加上cutStr */ //当截取第一个字符为空证明所有文字都移过去了,此时清除定时器,调用透明度渐隐函数 var oriStr = null, newStr = null, cutStr = null, cnt = 0, strLen = oTextarea.value.length, oSpan = btnWrap.getElementsByTagName('span')[0]; clearTimeout(oTextarea.timer); oTextarea.timer = setTimeout(function timerFn(){ oriStr = oTextarea.value; newStr = oriStr.substring(1); cutStr = oriStr.substring(0,1); oTextarea.value = newStr; p.innerHTML += cutStr; oSpan.innerHTML = cnt +'/'+ strLen; cnt++; if( oriStr != '' ){ oTextarea.timerInner = setTimeout(timerFn,50); }else{ clearTimeout(oTextarea.timer); clearTimeout(oTextarea.timerInner); hideStrip(); } },50); } function moveStrip(){ /* timer为外部定时器只执行一次, timerInner为主要重复执行的定时器, oLi是进度条每个格子, oldCube初始化为第一个并成深色 i为下标 */ var timer = null, timerInner = null; oLi = rStrip.getElementsByTagName('li') oldCube = oLi[0]; i = 0; oldCube.style.background = '#3f51b5'; timer = setTimeout(function timerFn(){ //恢复老的小方块,设置新的小方块颜色,更新oldCube,i++,i %= oLi.length重复循环,每个30ms调用一次自己 oldCube.style.background = '#03a9f4'; oLi[i].style.background = '#3f51b5'; oldCube = oLi[i]; i++; i %= oLi.length; timerInner = setTimeout(timerFn,30); if(oBtn.onOff){ clearTimeout(timer); clearTimeout(timerInner); } },30); } function hideStrip(){ //每次减0.05的透明值 var timer = null; var timerInner = null; var step = -0.05; timer = setTimeout(function timeFn(){ var opc = parseFloat(getStyle(rStrip,'opacity')); opc += step; console.log(opc); (opc <= 0) && (opc = 0); rStrip.style.opacity = opc; if(opc != 0){ timerInner = setTimeout(timeFn,30); }else{ clearTimeout(timerInner); //完全透明后翻转开关 oBtn.onOff = !oBtn.onOff; } },30); } function rateStrip(){ var eSpan = document.createElement('span'); eSpan.innerHTML = '0/0'; eSpan.style.display = 'block'; eSpan.style.width = '100%'; eSpan.style.textAlign = 'center'; eSpan.style.marginTop = '14px'; var eUl = document.createElement('ul'); eUl.style.margin = 16 + 'px'; eUl.style.opacity = 0; var eLi = null; for(var i=0; i<6; i++){ eLi = document.createElement('li'); eLi.style.width = 14 + 'px'; eLi.style.height = 14 + 'px'; eLi.style.background = '#03a9f4'; eLi.style.float = 'left'; eLi.style.marginLeft = 5 + 'px'; eUl.append(eLi); } btnWrap.append(eSpan); btnWrap.append(eUl); return eUl; }