关于头像裁剪
1.上传图片的裁剪,并没有采用后端裁剪,而采用前端裁剪,基于cropbox进行了修改
编码使用一个隐藏的input框存放 存放到数据库
2.本来想在后端解析base64编码重新生成文件,后来发现并没有必要,如果图片不是很大直接保存字符串到数据库就行了,这样还可以少一些http请求,不过缺点是Ie6不支持date:url的解析
3.图片变成base64编码之后,保存在数据库的字符长度高达16W
个字符,后来想办法改成jpeg+中等保存之后,长度变成3W,可以接受
下面从代码说起 界面显示
如图所示,3个部分,一个用于显示图片 一个是按钮 右边的是图片裁剪之后的图,有3张 分别是180*180 128*128 64*64 就不多说了
1 1 <div class="imageBox"> 2 2 3 3 <div class="thumbBox"></div> 4 4 5 5 <div class="spinner" style="display: none"></div> 6 6 7 7 </div> 8 8 9 9 <div class="action"> 10 10 11 11 <div class="new-contentarea tc"> <a href="javascript:void(0)" class="upload-img"> 12 12 13 13 <label for="upload-file">请先选择图片...</label> 14 14 15 15 </a> 16 16 17 17 <input type="file" class="" name="upload-file" id="upload-file" /> 18 18 19 19 </div> 20 20 21 21 22 22 <input type="button" id="btnCrop" class="Btnsty_peyton" value="✔"> 23 23 24 24 <input type="button" id="btnZoomIn" class="Btnsty_peyton" value="+" > 25 25 26 26 <input type="button" id="btnZoomOut" class="Btnsty_peyton" value="-" > 27 27 28 28 <input type="button" class="Btnsty_peyton" value="✘" onclick="cancel_shield()"> 29 29 </div> 30 30 31 31 <div class="cropped"></div> 32 32 33 33 </div>
关于JS的
注意42行
JS控制代码
swal("操作成功!", "图片上传喽!", "success"); 这是用了sweet-alert的弹窗效果,要注意引入sweet-alert的js文件
对用户上传上来的图片进行裁剪 然后转成Base64 字符串分别保存在56 58 60行的img src里
通过apepnd标签添加到
<div class="cropped"></div> 预留的这个DIV里
40 $('#btnCrop').on('click', function(){ 41 42 swal("操作成功!", "图片上传喽!", "success"); 43 $("#IconMessage").html("头像选择成功,再次点击更换头像"); 44 var s=$("#haha1").attr("src"); 45 $("#hideInput").val(s); 46 cancel_shield(); 47 })
然后将这个SRC放到表单里的隐藏INPUT框里,提交到到后台传到数据库,数据里保存的是BASE64编码,对上传进行了一定的限制之后 一般字符串大小为3W~5W的样子 如图
直接用img的src 可以在浏览器解析出来
1 1 $(window).load(function() { 2 2 var options = 3 3 4 4 { 5 5 6 6 thumbBox: '.thumbBox', 7 7 8 8 spinner: '.spinner', 9 9 10 10 imgSrc: '' 11 11 12 12 } 13 13 14 14 var cropper = $('.imageBox').cropbox(options); 15 15 16 16 var img=""; 17 17 18 18 $('#upload-file').on('change', function(){ 19 19 20 20 var reader = new FileReader(); 21 21 22 22 reader.onload = function(e) { 23 23 24 24 options.imgSrc = e.target.result; 25 25 26 26 cropper = $('.imageBox').cropbox(options); 27 27 28 28 getImg(); 29 29 30 30 } 31 31 32 32 reader.readAsDataURL(this.files[0]); 33 33 34 34 this.files = []; 35 35 36 36 // getImg(); 37 37 38 38 }) 39 39 40 40 $('#btnCrop').on('click', function(){ 41 41 42 42 swal("操作成功!", "图片上传喽!", "success"); 43 43 $("#IconMessage").html("头像选择成功,再次点击更换头像"); 44 44 var s=$("#haha1").attr("src"); 45 45 $("#hideInput").val(s); 46 46 cancel_shield(); 47 47 }) 48 48 49 49 50 50 function getImg(){ 51 51 52 52 img = cropper.getDataURL(); 53 53 54 54 $('.cropped').html(''); 55 55 56 56 $('.cropped').append('<img src="'+img+'" align="absmiddle" style="180px;margin-top:4px;border-radius:180px;box-shadow:0px 0px 12px #7E7E7E;"><p>180px*180px</p>'); 57 57 58 58 $('.cropped').append('<img src="'+img+'" align="absmiddle" id="haha1" style="128px;margin-top:4px;border-radius:128px;box-shadow:0px 0px 12px #7E7E7E;"><p>128px*128px</p>'); 59 59 60 60 $('.cropped').append('<img src="'+img+'" align="absmiddle" style="64px;margin-top:4px;border-radius:64px;box-shadow:0px 0px 12px #7E7E7E;" ><p>64px*64px</p>'); 61 61 62 62 } 63 63 64 64 65 65 66 66 $(".imageBox").on("mouseup",function(){ 67 67 68 68 getImg(); 69 69 70 70 }); 71 71 72 72 73 73 $('#btnZoomIn').on('click', function(){ 74 74 75 75 cropper.zoomIn(); 76 76 77 77 }) 78 78 79 79 $('#btnZoomOut').on('click', function(){ 80 80 81 81 cropper.zoomOut(); 82 82 83 83 }) 84 84 85 85 });
跨音乐播放音乐
关于jframe的逻辑判断
首先一共有三个窗口 一个父窗口 两个子窗口 子窗口分别叫做显示框(给用户看的) 和音乐框(用来播放歌曲的)
总窗口-- 写一个公用方法 效果是将显示框的数值传递到音乐框(通过调用音乐框里的方法)
显示框:里面的按钮经过一个ajax 回调函数的时候调用 父窗口的公用方法,传递一个参数(歌曲列表playList)
父窗口: 调用音乐框里改变音乐列表的方法(传递一个歌曲列表参数playList)
显示框用于回调函数的方法(用于调用父方法,传递歌曲列表)
function passMusic(obj){
top.PassData(obj)
}
父方法里的方法是(调用音乐框方法,传递歌曲列表)
function PassData(obj){
obj.window.frames["音乐框"].changeMusic();
}
音乐框里的方法是(根据传递过来的歌曲列表进行改变)
function changeMusic(obj){
playlist=obj
}
然后是音乐列表的坑,先是直接把playlist直接remove掉了,找了半天没弄明白为什么不出列表,后来调用浏览器窗口才发现了问题所在,问题很快就解决了。
<a href="albumAction!goIntoAlbumDetails.action?dvd.dvdName='${d.dvdName }'">${d.dvdName }</a>
在JS中调用EL表达式的要加上单引号
但是这里是A标签 传值 就不用加了,不然后台的值会多个引号
根据名字查数值可能会查不到
发现两边多了个单引号...
另外一个关于A标签调用JS 不会影响页面GIF 同时又能保持A标签
在HTML页面的特性的方法
<a onclick="javascript:playSong('${d.dvdId}','${d.dvdIconSrc}');return false;" href="#" class="img">
关于分页 有时候看起来效果简单 做起来不是很容易
首先将样式写在class里面,对页码绑定js,让其被点中的时候变成被
选择的绿色,同时其他的变成未选择的白色
$("div[class='mod_page_nav js_pager']>a[class='js_pageindex'],div[class='mod_page_nav js_pager']>a[class='current']").click(function(){
$("div[class='mod_page_nav js_pager'] a[class='current']").attr('class','js_pageindex');
$(this).attr('class','current');
});
当前按钮变成被选中的clas 'current'类,同时其余的按钮变成未变选择的'js_pageindex' 类
/*下一页的绑定*/
$("a[class='next js_pageindex']").click(function(){
$("a[class='current']").next("a[class='js_pageindex']").attr('class','current');
$("a[class='current']").first().attr('class','js_pageindex');
});
/*上一页的绑定*/
$("a[class='previous js_pageindex']").click(function(){
$("a[class='current']").prev("a[class='js_pageindex']").attr('class','current');
$("a[class='current']").last().attr('class','js_pageindex');
});
接着对上一页 下一页的按钮进行绑定 让current类也就是当前被选择的页码变成未选择 ,同时根据上一页下一页让对应的页码被选择
本来的逻辑是这样的,但是事实上在做的时候发现,让current被选择的这个按钮变成未选择之后,之后的操作不管上一页还是下一页 都没有效果 因为上一页下一页都是根据current的位置来判断的 而这个current类已经被我删除了 所以操作不行
于是就改成了上面的代码, 比如说下一页的操作,先根据current类,将下一个按钮变成已选择
大概长这样子,先将第二页选中,接着选中所有被选中的按钮,将第一个按钮给变成未选择的
也就是上图所示的这行代码 $("a[class='current']").first().attr('class','js_pageindex');
于是效果就完成了
只有2被选中
上一页同理 ,本以为这样就结束了,但是又发现一个问题就是用户点击了不同页码,页面发生了跳转
而我页面每次重新载入之后 默认的初始选中都是第一页
也就是说 上面的这些效果在页面被点击之后就被重置了,说白了就是没什么用 于是乎 将当前页码currentPage放入session中,并用onload js函数 每次加载的时候对这些选项进行初始化
因为后台默认给currentPage一个1的默认值
发现前台代码就很简单了
var currentPage="${currentPage}";
$("div[class='mod_page_nav js_pager']>a").eq(currentPage).attr('class','current');
这样就完成了分页的页面效果
总结
一开始都不准备做分页的,因为觉得很简单,但事实上,只有自己去做才发现有些小效果并不是看起来那么容易实现的
缺点 很多问题没有来得及记录,有些问题自己都忘记当时是怎么解决的了 要想一会才能想出来
比如级联AJAX的问题 我忘记我怎么解决的了 好像是选择了传对象过去解决的 早上别人提起的时候我想了半天都没记起来 因为这个问题我也碰到了
项目开的有点大了 时间不太够 然后数据库设计的时候还是有点问题 中间项目做到一半发现少了一些字段 比如歌曲 歌手的多重分类 是有很多个分类的
很多功能都没做 只是做了个DEMO 还有这次项目想做的
多利用浏览器缓存去处理一些数据 比如说历史搜索记录之类的
还有搜索的利用拼音搜索 歌手页面的那种点击按钮实现多条件搜索包括分页
就把前台JS效果写好了 后台没时间去实现
有时间的话 最好重新整理一下 整个项目的结构 做到后面已经明显发现结构什么的可能有点开始混乱了 没有前面的那么清晰 就拿命名来说吧 Song SongList Singer SingerList 之类名词很相近 然后有些是排行榜的 有些是首页的 有些是歌单的 有些的独立显示的
名字很多 因为赶时间 没有对这些对象设立统一的命名规则 想到一个名字就用了 然后复制过去 虽然不会报错 但是估计以后看会很头疼 然后很多效果图快就做了 其实心里清楚这样做并不是什么很好的方式
写工具轮子,JAVA的封装继承平常做项目的就可以多利用 ,多写点工具类对自己很有帮助,尽量减少重复代码,这样效率会高很多
工具写多了,就是自己的东西了。
感觉有时候限定时间内做项目就像做数学卷子 感觉有强迫症 应该先做会做的 然后再做难的
但是比如说这次 前面比较注重代码质量还有一些验证判断之类的
包括头像裁剪什么的
登录注册之类的就搞了蛮久 后面时间很紧 再加上前面两天扒网页
爬数据 之类的 导致后面时间很紧 我几天前就觉得有限时间内根本完不成了.. 所以觉得项目开大了 或者说太扣细节了
不过和上次项目一样,多尝试一些自己不懂的,过程很痛苦,但这是正常最快的方式,所以不要把自己放在舒适区,那样进步的太慢。