最近做一个练手的项目,模仿微信网页版,需要做一个QQ表情的列表功能。
长这个样子:
首先Nodejs获取文件夹下的图片目录,每张动态图片都要有一个原图和fix图~我在百度上面下的素材:
下面是nodejs代码,循环获取emotion下面的文件夹,然后循环文件夹下面的图片,添加到emotions中:
var fs = require("fs");
var emotions = {};
var initialized = false;
var path = "./public/images/emotion";
function explorer(path, filename) {
initialized = true;
fs.readdir(path, function(err, files){
if(err) {
console.log(err);
return;
}
files.forEach(function(file){
fs.stat(path + "/" + file, function(err, stat){
if(err) {
console.log(err);
return;
}
if(stat.isDirectory()) {
// 文件夹
explorer(path + '/' + file, file);
} else {
if(!emotions[filename]) {
emotions[filename] = [];
}
if(file.indexOf("fixed") == -1) {
var filePath = path.split("/public").join("");
emotions[filename].push({path: filePath + '/' + file, fixed: filePath + '/' + file + 'fixed'});
}
}
});
});
});
}
explorer(path, "");
exports.getImages = function(req, res){
if(!initialized) {
explorer(path, "");
}
res.send(emotions);
}
jade:
div#emotionCollection(role="tabpanel")
ul.nav.nav-tabs(role="tablist")
div.tab-content
button#emotion.btn.btn-default 表情
div#preview
css:
#emotionCollection {
background-color: rgb(246, 246, 246);
}
#emotionCollection .icon {
border: 1px transparent solid;
width: 20px;
}
#emotionCollection .icon:hover {
border: 1px blue solid;
}
#preview {
display: none;
position: absolute;
z-index: 1000;
background-color: rgb(246, 246, 246);
}
#preview img {
height: 100px;
}
backbone:(用了bootstrap的tab切换功能)
var EmotionView = Backbone.View.extend({
el: "#emotionCollection",
tabTemplate: _.template('<li role="presentation"><a href="#<%= id%>" aria-controls="<%= id%>" role="tab" data-toggle="tab"><%= id%></a></li>'),
contentTemplate: _.template('<div id="<%= id%>" class="tab-pane" role="tabpanel"></div>'),
imageTemplate: _.template('<img src="<%= fixed%>" data-source="<%= path%>" class="icon"/>'),
popTemplate: _.template('<img src="<%= path%>" class="pop"/>'),
events: {
"mouseover .icon" : "preview",
"mouseout .icon" : "hidePreivew"
},
initialize: function(){
_.bindAll(this, "render", "preview", "hidePreivew");
},
render: function(){
var self = this;
$.ajax({
url: "/getImages",
type: "GET",
data: {type: "normal"},
dataType: "JSON",
success: function(list){
var index = 0;
for(var key in list) {
var $tab = $(self.tabTemplate({id: key}));
$(self.el).find(".nav-tabs").append($tab);
var $content = $(self.contentTemplate({id: key}));
$(self.el).find(".tab-content").append($content);
list[key].forEach(function(path){
$content.append(self.imageTemplate(path));
});
if(index == 0) {
$content.addClass("active");
$tab.addClass("active");
}
index ++;
}
}
})
},
preview: function(e){
var $target = $(e.target);
$("#preview").html(this.popTemplate({path: $target.data("source")}));
var offset = $target.offset();
$("#preview").css({top: offset.top - 110, left: offset.left}).show();
},
hidePreivew: function(){
$("#preview").hide();
}
});
var emotionView;
$("#emotion").click(function(e){
if($(this).hasClass("active")) {
$(this).removeClass("active");
$(emotionView.el).hide();
} else {
if(!emotionView) {
emotionView = new EmotionView();
emotionView.render();
} else {
$(emotionView.el).show();
}
$(this).addClass("active")
}
})