给hexo静态博客添加动态相册功能

小鸡
阅读3559喜欢17·教程发表2019-5-7更新2019-5-17

兰州小红鸡

昨天突发奇想给博客写了个相册页面,使用腾讯云cos作为相册的存储桶,使用api在线获取相册里面的存储桶里的照片并且实时生成相册内容。之前也有看过一些人做的相册页面,但是对于我来说,还是感觉不方便。网上的大多是在本地项目文件夹存放照片,然后更改一系列的主题文件来实现相册页面。

比如这位制作的Hexo NexT 博客增加瀑布流相册页面,然而他做的过程已经算是比较简洁了,没有改动太多主题配置。但是这种相册,每次添加新照片的时候,还是需要手动在相册页面添加相应的图片链接与代码。

所以我想能不能做一个直接后台上传图片,不用再改动代码的静态博客的相册页面呢,就像一个动态博客一样,或者像qq相册那样,只需要上传照片就可以了。

答案是可以的,机智的我使用了腾讯云的cos存储桶作为相册后台,调用cos存储桶的xml文件api在线获取图片链接,再使用JavaScript代码动态生成相册内容。

兰州小红鸡的博客相册

效果如下

前方轻微秀恩爱预警

2019-05-07更新
之前写的这篇教程没想到有这么多朋友采纳
不过教程也确实有很多问题
之前写的比较粗糙,让朋友们遇到各种麻烦
现在更新一下
写一下我能想到的各种bug的解决方法

步骤如下:

创建腾讯云cos存储桶

这个比较简单,搜索腾讯云,注册账号登陆,在云产品中选择对象存储,新建一个存储桶。就OK了。

兰州小红鸡

跨域访问cors设置

在基础配置中找到cors设置

兰州小红鸡

操作选择GET,来源Origin填写你的域名,带http或者https,其他默认不要填,如下图

兰州小红鸡

注意:如果填了域名还是遇到跨域问题,那么就把origin源填为*,比如下面这样(其实刚开始弄的话建议都填成*好了)

读写权限

一般情况下默认是共有读私有写,policy权限就不要设置了

访问域名

然后记住这个地方访问域名,这里就是我们动态生成相册,获取链接时需要用到的xml链接,下面要用到

兰州小红鸡

复制这个访问域名,看能不能在浏览器中打开,如果可以打开并且没有显示error节点,那么就可以继续下面的操作,否则查看上面哪一步出错并进行改正

上传照片

上传照片方式有很多(推荐用coscmd命令行写个脚本),不过这里教程中你就直接上腾讯云后台上传就好了,想要其他骚操作等相册做好了再自己百度吧。

重要事项

  1. 上传照片前,先在存储桶中建立一个文件夹,也就是你的相册名字,当然你也可以新建多个文件夹。
  2. 但是有一点需要需要注意的是,不能直接上传一个文件夹,那样会出bug,见完文件夹后往里面上传照片,文件夹里面不能再新建文件夹了(除非你自己改造下面的相应代码)
  3. 每个文件中需要一张命名为封面的图片,它会作为你的该文件夹相册的封面

然后就ok了

hexo本地配置

在本地项目新建一个相册页面

$ hexo new page photos

19-01-15更新:将照片地展示分不同相册加载

编辑sourcephotos路径下的index.md文件,写入以下代码

记得在下面的代码中填写xmllink的值,也就是上面提到的你的存储桶访问域名

<style type="text/css">
.main-inner{
width: 100%;
}
.main {
padding-bottom: 150px;
margin-top: 0px;
background: #121212;
}
.main-inner{
margin-top: unset;
}
.page-post-detail .post-meta{
display: none;
}
body {
background-image: unset;
background-attachment: unset;
background-size: 100%;
/*background-position: top left;*/
}
.header{
background: rgba(28, 25, 25, 0.6);
border-bottom: unset;
}
.menu .menu-item a{
font-weight: 300;
color: #e6eaed;
}

.imgbox{
width: 100%;
overflow: hidden;
height: 250px;
border-right: 1px solid #bcbcbc;
}
.box{
visibility: visible;
overflow: auto;
zoom: 1;
}
.box li{
float: left;
width: 25%;
position: relative;
overflow: hidden;
text-align: center;
list-style: none;
margin: 0;
/*display: inline;*/
padding: 0;
height: 360px;
}
.box li span{
display: block;
padding: 4% 7% 10% 7%;
min-height: 80px;
background: #fff;
color: #fff;
font-size: 16px;
background: #121212;
font-weight: 600;
line-height: 26px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}

img.imgitem{
padding: unset;
padding: unset;
border: unset;
position: relative;
padding: 0px;
height: auto;
width: 100%;
}


div#posts.posts-expand {
border: unset;
padding: unset;
margin-bottom: 10px;
}
.posts-expand .post-body img{
padding: 0px !important;
}
.box p{
display: block;
background: #121212;
color: #fff;
font-size: 12px;
font-family: 'SwisMedium';
-webkit-box-sizing: border-box;
box-sizing: border-box;
text-align: center;
}

.box span strong{
background: rgba(0,0,0,0.4);
padding: 20px;
}

.posts-expand .post-title {
display: none;
}
.title{
display: inline-block;
vertical-align: middle;
background: url(https://image.idealli.com/bg11.jpg);
font: 85px/250px 'ChaletComprimeMilanSixty';
background-position: left bottom !important;
color: #fff;
background-size: 100% auto !important;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
width: 100%;
text-align: center;
border: unset;
height: 700px;
cursor: unset !important;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.btn-more-posts{
display: inline-block;
vertical-align: middle;
font: 85px/250px 'ChaletComprimeMilanSixty';
color: #000;
width: 100%;
text-align: center;
border: unset;
height: 400px;
background-color: #121212;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}

@media (max-width: 767px){
.box li {
width: 100%;
}
.title {
height: 200px;
}

.box span {
min-height: 80px;
border-right: unset;
font-size: 17px;
}
.box p{
border-right: unset;
font-size: 12px;

}
.posts-expand {
margin: unset;
}
div#comments.comments.v {
width: 96%;
padding-top: 50px;
}


}

@media (min-width: 1600px){
.container .main-inner{
width: 100%;
}
}

.footer{
background-color: #121212 !important;
}
.v * {
color: #f4f4f4 !important;
}

.v .vwrap .vmark .valert .vcode {
background: #00050b !important;
}

</style>

<div id="box" class="box"></div>


<script type="text/javascript">

function loadXMLDoc(xmlUrl)
{
try //Internet Explorer
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
}
catch(e)
{
try //Firefox, Mozilla, Opera, etc.
{
xmlDoc=document.implementation.createDocument("","",null);
}
catch(e) {alert(e.message)}
}

try
{
xmlDoc.async=false;
xmlDoc.load(xmlUrl);
}
catch(e) {
try //Google Chrome
{
var chromeXml = new XMLHttpRequest();
chromeXml.open("GET", xmlUrl, false);
chromeXml.send(null);
xmlDoc = chromeXml.responseXML.documentElement;
//alert(xmlDoc.childNodes[0].nodeName);
//return xmlDoc;
}
catch(e)
{
alert(e.message)
}
}
return xmlDoc;
}

var xmllink="你的访问域名链接"
//访问域名链接就是我上面提到的那个访问域名xml链接

xmlDoc=loadXMLDoc(xmllink);
var urls=xmlDoc.getElementsByTagName('Key');
var date=xmlDoc.getElementsByTagName('LastModified');
var wid=250;
var showNum=12; //每个相册一次展示多少照片
if ((window.innerWidth)>1200) {wid=(window.innerWidth*3)/18;}
var box=document.getElementById('box');
var i=0;

var content=new Array();
var tmp=0;
var kkk=-1;
for (var t = 0; t < urls.length ; t++) {
var bucket=urls[t].innerHTML;
var length=bucket.indexOf('/');
if(length===bucket.length-1){
kkk++;
content[kkk]=new Array();
content[kkk][0]={'url':bucket,'date':date[t].innerHTML.substring(0,10)};
tmp=1;
}
else {
content[kkk][tmp++]={'url':bucket.substring(length+1),'date':date[t].innerHTML.substring(0,10)};
}
}

for (var i = 0; i < content.length; i++) {
var conBox=document.createElement("div");
conBox.id='conBox'+i;
box.appendChild(conBox);
var item=document.createElement("div");
var title=content[i][0].url;
item.innerHTML="<button class=title style=background:url("+xmllink+'/'+title+"封面.jpg"+");><span style=display:inline;><strong style=color:#f0f3f6; >"+title.substring(0,title.length-1)+"</strong></span></button>";
conBox.appendChild(item);

for (var j = 1; j < content[i].length && j < showNum+1; j++) {
var con=content[i][j].url;
var item=document.createElement("li");
item.innerHTML="<div class=imgbox id=imgbox style=height:"+wid+"px;><img class=imgitem src="+xmllink+'/'+title+con+" alt="+con+"></div><span>"+con.substring(0,con.length-4)+"</span><p>上传于"+content[i][j].date+"</p>";
conBox.appendChild(item);
}
if(content[i].length > showNum){
var moreItem=document.createElement("button");
moreItem.className="btn-more-posts";
moreItem.id="more"+i;
moreItem.value=showNum+1;
let cur=i;
moreItem.onclick= function (){
moreClick(this,cur,content[cur],content[cur][0].url);
}
moreItem.innerHTML="<span style=display:inline;><strong style=color:#f0f3f6;>加载更多</strong></span>";
conBox.appendChild(moreItem);
}
}

function moreClick(obj,cur,cont,title){
var parent=obj.parentNode;
parent.removeChild(obj);
var j=obj.value;
var begin=j;
for ( ; j < cont.length && j < Number(showNum) + Number(begin); j++) {
console.log( Number(showNum) + Number(begin));
var con=cont[j].url;
var item=document.createElement("li");
item.innerHTML="<div class=imgbox id=imgbox style=height:"+wid+"px;><img class=imgitem src="+xmllink+'/'+title+con+" alt="+con+"></div><span>"+con.substring(0,con.length-4)+"</span><p>上传于"+cont[j].date+"</p>";
parent.appendChild(item);
}
if(cont.length > j){
obj.value=j;
parent.appendChild(obj);
}
}

</script>

然后刷新hexo渲染

$ hexo clean
$ hexo d -g

再往cos存储桶里上传照片,就可以了!效果如下
重要的是以后更新照片都不用改动代码。往腾讯云cos上传照片就好了,而且腾讯云页提供了很多工具可以再本地命令行上传照片,非常方便,感兴趣可以自行百度。

兰州小红鸡

嘻嘻女朋友真可爱!

兰州小红鸡

自己写界面样式

注意

以上教程是基于我自己的博客主题(next主题Mist样式)做的适配
所以可能会出现一些样式问题
强烈建议会前端的朋友自己写样式和逻辑代码,确保不会出错。
不会前端的朋友也可以学一学css自己改改,挺有趣的
另外都在搞这个了,应该也都会一点了
自己写css样式也不麻烦,一个小时就能把相册改造成自己喜欢的风格

代码核心

上面的photo界面的核心代码是获取腾讯云xml文件的那段

function loadXMLDoc(xmlUrl) 
{
try //Internet Explorer
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
}
catch(e)
{
try //Firefox, Mozilla, Opera, etc.
{
xmlDoc=document.implementation.createDocument("","",null);
}
catch(e) {alert(e.message)}
}

try
{
xmlDoc.async=false;
xmlDoc.load(xmlUrl);
}
catch(e) {
try //Google Chrome
{
var chromeXml = new XMLHttpRequest();
chromeXml.open("GET", xmlUrl, false);
chromeXml.send(null);
xmlDoc = chromeXml.responseXML.documentElement;
//alert(xmlDoc.childNodes[0].nodeName);
//return xmlDoc;
}
catch(e)
{
alert(e.message)
}
}
return xmlDoc;
}

var xmllink="你的访问域名链接"
//访问域名链接就是我上面提到的那个访问域名xml链接

xmlDoc=loadXMLDoc(xmllink);
var urls=xmlDoc.getElementsByTagName(Key);

urls便是获取了相册的所有链接,之后要做的事情就是用js动态生成img元素
我的是这样写的,当然你也可以使用别的写法,写适合自己风格的相册样式

var urls=xmlDoc.getElementsByTagName(Key);
var date=xmlDoc.getElementsByTagName(LastModified);
var wid=(window.innerWidth*3)/18;
var box=document.getElementById(box);
var i=0;

for ( ; i < 21 && i<urls.length; i++) {
var bucket=urls[i].innerHTML;
var length=bucket.indexOf(/);
if(length===bucket.length-1){
var item=document.createElement("div");
item.innerHTML="<button class=btn-more-posts><span style=display:inline;><strong style=color:#f0f3f6; >"+bucket.substring(0,length)+"</strong></span></button>";
box.appendChild(item);
continue;
}

var item=document.createElement("li");
item.innerHTML="<div class=imgbox id=imgbox style=height:"+wid+"px;><img class=imgitem src="+xmllink+/+bucket+" ></div><span>"+bucket+"</span><p>"+date[i].innerHTML.substring(0,10)+"</p>";
box.appendChild(item);

}

var morep=document.getElementById(more);
morep.onclick=function(){
var temp=i+20;

for ( ; i < temp && i<urls.length; i++) {
var bucket=urls[i].innerHTML;
var length=bucket.indexOf(/);
if(length===bucket.length-1){
var item=document.createElement("div");
item.innerHTML="<button class=btn-more-posts><span style=display:inline;><strong style=color:#f0f3f6; >"+bucket.substring(0,length)+"</strong></span></button>";
box.appendChild(item);
continue;
}
var item=document.createElement("li");
item.innerHTML="<div class=imgbox id=imgbox style=height:"+wid+"px;><img class=imgitem src="+xmllink+/+urls[i].innerHTML+" ></div><span>"+urls[i].innerHTML+"</span><p>"+date[i].innerHTML.substring(0,10)+"</p>";
box.appendChild(item);

}
}

整个教程还是提供了一个思路,如果遇到问题了,请根据自己的实际情况进行
我的博客主题:Next主题Mist样式

注意事项

  1. 上传照片前,先在存储桶中建立一个文件夹,也就是你的相册名字,当然你也可以新建多个文件夹。
  2. 但是有一点需要需要注意的是,不能直接上传一个文件夹,那样会出bug,见完文件夹后往里面上传照片,文件夹里面不能再新建文件夹了(除非你自己改造下面的相应代码)
  3. 每个文件中需要一张命名为封面的图片,它会作为你的该文件夹相册的封面
  4. 确保存储桶的xml域名能在浏览器上访问
  5. 暂时不要设置policy权限啥的,等你相册制作完了,如果怕照片被盗可以添加这些东西
  6. 尽量自己修改样式,不然肯定不好看(除非你的主题和我的一样)
  7. css样式直接写在md文件中,不用写在全局里

下面是一些我的建站笔记汇总,平常做的小手工,希望对大家有帮助

hexo博客搭建以及next美化教程 原生js实现网页图片点击展示效果 用回valine评论系统,valine评论框样式美化 给hexo静态博客添加动态相册功能 hexo建站笔记之首页文章轮播图 模仿知乎的链接卡片 开始使用腾讯云图床 将公众号文章爬到hexo博客 使用腾讯云cdn加速博客 hexo建站笔记之彩色标签云
随想
博客
机器学习
教程
邻家酒肆
前端
深度学习
算法
小程序
资源
cpp
html
javascript
python
sql
node
wordpress

最近文章