为我家猫咪创建博客
起因
家里有只小橘猫,性格挺讨人喜欢的,就想着做个它的简易博客,记录其大小轶事,也用于记录我和他妈的养猫日常和感受。
demo:https://unuliha.github.io/zhongqiu/index.html
源码: https://gitee.com/unuliha/blog/tree/master/2021/08/29/zhongqiu
怎么做
需要记录的资料:照片、视频、文字信息
网页整体构造:参照《JavaScript DOM 编程艺术》(第2版)最后一章的综合实例
编程工具:WebStorm
思路:在整体框架不变的基础上,将内容样式修改为自己的,并添加上想要实现的功能。
主要功能及实现
功能1:鼠标放哪个标签,哪个标签高亮
思路:找到所有标签索引,为每一个标签添加两个事件:
onmouseover
事件:被触发时增加新类名,新类的背景样式为高亮onmouseout
事件:鼠标移走时恢复原来的类名,即可恢复原来类的样式
代码:
function highlightRows(){
var rows = document.getElementsByTagName("tr");
for (var i=0; i<rows.length; i++) {
rows[i].oldClassName = rows[i].className;
rows[i].onmouseover = function () {
addClass(this, "highlight");
}
rows[i].onmouseout = function () {
this.className = this.oldClassName;
}
}
}
function addClass(elem,theclass){
if (!elem.className){
elem.className = theclass;
} else {
var classNames = elem.className;
classNames += " ";
classNames += theclass;
elem.setAttribute("className",classNames);
}
}
功能2:给表格奇偶行设置不同样式
思路:直接给奇数行或偶数行添加新类名,让新类有不同的样式即可
代码:
function stripeTables(){
var tables = document.getElementsByTagName("table");
for (var i=0; i<tables.length; i++){
var odd = false;
var rows = tables[i].getElementsByTagName("tr");
for (var j=0; j<rows.length; j++){
if (odd == true){
addClass(rows[j],"odd");
odd = false;
} else {
odd = true;
// addClass(rows[j],"even")
}
}
}
}
这个功能也可以通过CSS伪类选择器nth-child(n)实现,其中“n”是其参数,而且可以是整数值(1,2,3,4),也可以是表达式(2n+1、-n+5)和关键词(odd、even),但参数n的起始值始终是1,而不是0。
功能3:图片索引上下翻页
思路:用了大佬的方法:https://www.cnblogs.com/starof/p/5732097.html
具体要实现:
- 当前页为第一页时,前翻按钮隐藏;当前页为最后一页时,后翻页按钮隐藏
- 点击上下翻页按钮,分别实现上下翻页,每次点击移动图片数量可设置
步骤:
(1)设置变量now
表示当前图片的位置、linum
表示总共图片数量、shownum
表示每页呈现数量。当前位置初始化为1,此时前翻按钮隐藏。如果当前位置为 linum-shownum+1
,说明已经在最后一页的第一张图片的位置,此时后翻按钮隐藏。其他时候,前后翻按钮都显示。
(2)前后翻按钮每点击一次,页面前翻或后翻一页,可通过now+=number
中的number
设置每次翻页移动的图片张数。
(3)上下翻页通过设置图片索引列表的margin-left
来实现,即wrap.stop(true).animate({"margin-left": -(now - 1) * 100})
,由于事先裁好每个小图片宽度100,所以这里直接乘了100。
代码:
function swichPic() {
//task growth
var switchPic = (function () {
/*
now:当前第几个li
linum:总共几个li
shownum:要展示几个li
w_li:li的宽度
marginR_li:li的右边距
*/
var now = 1;
var linum, shownum, pre, next, wrap;
function init(o) {
pre = o.preBtn;
next = o.nextBtn;
wrap = o.wrap;
bindBtn();
}
function btnShow() {
getInfo();
if (linum <= shownum) { //如果li总个数小于要展示的个数,pre和next都不显示
pre.hide();
next.hide();
} else if (now == 1) { //初始化,只显示next
pre.hide();
next.show();
} else if (now > linum - shownum + 1) { //到最后一组,只显示pre
pre.show();
next.hide();
} else { //中间pre,next都显示。
pre.show();
next.show();
}
}
function getInfo() {
linum = $("#imagegallery").find("li").size();
shownum = 6;
}
function bindBtn() {
btnShow();
next.on("click", function () {
now += 5;
btnShow();
// wrap.stop(true).animate({"margin-left": -(now - 1) * offset});
wrap.stop(true).animate({"margin-left": -(now - 1) * 100});
});
pre.on("click", function () {
now -= 5;
btnShow();
wrap.stop(true).animate({"margin-left": -(now - 1) * 100});
});
$(window).resize(function () {
now = 1;
btnShow();
wrap.animate({"margin-left": 0});
});
}
return {init: init}
})();
功能4:点击图片索引在下方呈现完整图片,并能够呈现视频
思路:先在下方放一个placeholder
用于呈现图片,再放一个placeholder1
用于呈现视频。当点击上方索引时,获取的src
为mp4
时,placeholder
隐藏,否则就placeholder1
隐藏。
代码:
function prepareGallery(){
if (!document.getElementsByTagName) return false; //检查浏览器是否有该DOM方法
if (!document.getElementById) return false;
if (!document.getElementById("imagegallery")) return false;//检查是否存在钙元素
var gallery = document.getElementById("imagegallery")
links = gallery.getElementsByTagName("a");
for (var i = 0;i<links.length;i++){
links[i].onclick = function (){
return showPic(this);
}
}
}
function preparePlaceholder(){
var gallery = document.getElementById("picSwichArrow");
var bigImage = document.createElement('div');
bigImage.setAttribute("id","bigImage");
var placeholder = document.createElement('img');
placeholder.setAttribute("id","placeholder");
placeholder.setAttribute("src","images/chuyou.jpg");
placeholder.setAttribute("alt","my image gallery");
var placeholder1 = document.createElement('video');
placeholder1.setAttribute("id","placeholder1");
placeholder1.setAttribute("controls","all");
placeholder1.setAttribute("src","images/bodou.mp4");
bigImage.append(placeholder);
bigImage.append(placeholder1);
insertAfter(bigImage,gallery);
placeholder1.style.display = "none";
}
function showPic(whichpic){
var source = whichpic.getAttribute("href");
var placeholder = document.getElementById("placeholder");
if (source.split(".")[1] == 'jpg'){
placeholder1.style.display ="none";
placeholder.style.display = "block";
placeholder.setAttribute("src",source);
} else {
placeholder.style.display = "none";
placeholder1.style.display ="block";
placeholder1.setAttribute("src",source);
}
return false;
}
功能5:大图片添加翻页按钮,并与索引的翻页联动
具体功能:
(1)为了确定当前图片排在第几个,需要将所有图片索引放到一个数组里,通过当前图片在数组中的索引确定大图片按钮隐藏状态:
如果索引为0,说明是第一张图片正在呈现,前翻按钮隐藏;如果索引是length-1
,说明是最后一张图片在呈现,后翻按钮隐藏。
(2)每次前后翻页,将current_img_index
加1或减1,由于上方(功能3中的图片索引)也可以点击查看图片,上方点击后下面原本的current_img_index
需要同时更新,因此点击翻页按钮时要先重新确定当前图片的索引。
(3)由于同时有视频文件和图片文件,相互切换时需要同步调整placeholder
和placeholder1
的隐藏状态。通过current_img_index
所指资源的后缀名进行判断。
代码:
function bigSwich() {
//添加箭头
let $left_arrow = $("<div id='big_left'>" +
"<img src='images/left_arrow.png' style='width: 100%'/>" +
"</div>");
let $right_arrow = $("<div id='big_right'>" +
"<img src='images/right_arrow.png' style = 'width:100%'/>" +
"</div>")
$("#bigImage").append($left_arrow);
$("#bigImage").append($right_arrow);
//将图片保存在数组中
let arr = new Array();
let linum = $("#imagegallery").find("li").size();
for (let i = 0; i < linum; i++) {
arr.push($(`#imagegallery li:eq(${i}) a`).attr("href"));
}
//创建对象封装功能
let bigSwichVa = (function () {
let current_img_index, place,pre,next;
function init(o) {
pre = o.preBtn;
next = o.nextBtn;
bindBtn();
}
function bigBtnShow() {
if (current_img_index < 1) {
pre.hide();
next.show();
} else if (current_img_index > arr.length - 2) {
pre.show();
next.hide();
} else {
pre.show();
next.show();
}
}
function getplace(index) {
if (arr[index].split(".")[1] == 'jpg') {
$("#placeholder").css("display" , "block");
$("#placeholder1").css("display" , "none");
place = $("#placeholder");
} else {
$("#placeholder").css("display" , "none");
$("#placeholder1").css("display" , "block");
place = $("#placeholder1");
}
return place;
}
function getIndex(){
let nowplace = ($("#placeholder").is(":hidden"))?
($("#placeholder1")):($("#placeholder"));
let nowPic = nowplace.attr("src");
current_img_index = arr.indexOf(nowPic);
}
function bindBtn() {
window.onclick = function (){
getIndex();
bigBtnShow();
}
next.on("click", function () {
getIndex();
current_img_index++;
getplace(current_img_index);
place.attr("src",arr[current_img_index]);
bigBtnShow();
})
pre.on("click", function () {
getIndex();
current_img_index--;
place = getplace(current_img_index);
place.attr("src",arr[current_img_index]);
bigBtnShow();
});
}
return {init: init}
})();
bigSwichVa.init({
preBtn: $("#big_left img"),
nextBtn: $("#big_right img"),
})
}
功能6:点击文本标题显示该部分文本,其他部分隐藏
思路:首先给每个文本标签添加destination
属性,指向文本的id
,初始时所有文本隐藏。标签被点击时,其指向的文本显示,其余文本隐藏。
代码:
function showSection(id){
var sections = document.getElementsByTagName("section");
for (var i=0; i<sections.length; i++){
if (sections[i].getAttribute("id") != id){
sections[i].style.display = "none";
} else {
sections[i].style.display = "block";
}
}
}
function prepareInternalnav(){
var articles = document.getElementsByTagName("article");
if (articles.length == 0) return false;
var navs = articles[0].getElementsByTagName("nav");
if (navs.length==0) return false;
var nav = navs[0];
var links = nav.getElementsByTagName("a");
for (var i=0; i<links.length; i++){
var sectionId = links[i].getAttribute("href").split("#")[1];
if (!document.getElementById(sectionId)) continue;
document.getElementById(sectionId).style.display = "none";
links[i].destination = sectionId;
links[i].onclick = function (){
// alert(this.destination);
showSection(this.destination);
return false;
}
}
}