鶸鷄折腾 FancyBox ,后来…

上一篇文章有点长呢,我还在考虑要不要分成两篇方便大家查看(胡说,这辈子也不可能凑更新呢),转念一想,上一篇还没做完就开了关于 FancyBox 的新坑,这里就折腾一下 FancyBox 吧。

FancyBox JavaScript lightbox library for presenting various types of media. Responsive, touch-enabled and customizable.

具体效果可以看它的官网,或者 Handsome 主题(适配的真好,我再适配不上我都想丢掉 Material 主题了)。Material 这点我一定要吐槽!居然图片连这种基本功能也不加,太反人类了!(开发者别打我,逃...

Quick start

<!-- 1. Add latest jQuery and fancybox files -->

<script src="//code.jquery.com/jquery-3.3.1.min.js"></script>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>
 

<!-- 2. Create links -->

<a data-fancybox="gallery" href="big_1.jpg">
    <img src="small_1.jpg">
</a>
<a data-fancybox="gallery" href="big_2.jpg">
    <img src="small_2.jpg">
</a>


<!-- 3. Have fun! -->

可以看到官网的示例非常亲和简单,先引用必要的 jQuery.js 再引用 FancyBox.js ,加上 FancyBox 必要的 FancyBox.css ,然后 FancyBox 就可以开始运行了,识别 data-fancybox 属性相同且包含 img 标签的 a 标签处理预览效果。
但是好像没有哪个编辑器解析图片写法 []() 会给他加 a data-fancy="" 这样的标签啊,这里参考友链大佬 OJHDT 的文章《使用 Fancybox 为博客添加图片放大预览功能》使用 js 替换(没学过 JS 但是发现学了一点点 C 语言之后真的能看懂更多的 JavaScript 了)

// 这里用了 .not('') 排除不需要的图片
$("img").not('.page__logo img').each(function () {
    // $(this).attr("data-fancybox", "gallery"); 
    // 直接给 img 添加 data-fancybox 会导致点击图片后图片消失
    var element = document.createElement("a");
    $(element).attr("data-fancybox", "gallery");
    $(element).attr("href", $(this).attr("src"));
    $(this).wrap(element);
});

这段代码用 js 方法给除了 .page_logo 样式的所有 img 标签外面套上 a 标签,其 data-fancybox 属性为 gallery 标签,href 属性为原来 img 标签的 src
参考 FancyBox 官方文档,了解到需要预览显示图片标题的话为 a 标签添加 data-caption 属性即可,所以我们照葫芦画瓢,参考这段 js 这样写: $(element).attr("data-caption", $(this).attr("alt"));
参考了《插件发布:SlimBox2 for Typecho【11/02/25更新】》的文章,我了解到第一行用的应该是 jQuery 选择器,查 jQuery 选择器参考手册 根据 Material 主题特性:文章内图片 Lazyload 处理之后 img 标签被添加了 lazy 属性,所以前面的选择器应该也可以写成 $("img.lazy") 。实测似乎不行,猜测 jQuery 选择器不是 JavaScript 原生组件,需要 jQuery 支持,根据上面的 SlimBox2 插件 Plugin.php 里面的代码我发现他是这样写的:

/**
 * 底部脚本
 *
 * @access public
 * @param unknown $footlink
 * @return unknown
 */
public static function footlink($links) {
    $Settings = Helper::options()->plugin('SlimBox2');
    $SlimBox2_url = Helper::options()->pluginUrl .'/SlimBox2/';
    $links= '<script type="text/javascript" src="'.$SlimBox2_url.'js/slimbox2.js"></script>';
    $links.= '<script type="text/javascript">';
    $links.= 'jQuery(function($) {
        $("'.$Settings->selectImg.'").slimbox({
            overlayOpacity: '.$Settings->overlayOpacity.',
            overlayFadeDuration: '.$Settings->overlayFadeDuration.',
            imageFadeDuration: '.$Settings->imageFadeDuration.',
            captionAnimationDuration: '.$Settings->captionAnimationDuration.',
            loop:'.$Settings->loop.',
            counterText:"'.$Settings->counterText.'"
        });
        });';
    $links.= '</script>';
    if($Settings->title != "true"){
        $links.= '<style>#lbBottomContainer{display:none;}</style>';
    }
    echo $links;
}

这段 php 代码通过 Typecho 的接口在 HTML 页面尾部输出了下面这样结构的代码,其中 '.$xxxx' 由 php 输出对应变量的值

<script type="text/javascript" src="'.$SlimBox2_url.'js/slimbox2.js"></script>
<script type="text/javascript">
jQuery(function($) {
    $("'.$Settings->selectImg.'").slimbox({
        overlayOpacity: '.$Settings->overlayOpacity.',
        overlayFadeDuration: '.$Settings->overlayFadeDuration.',
        imageFadeDuration: '.$Settings->imageFadeDuration.',
        captionAnimationDuration: '.$Settings->captionAnimationDuration.',
        loop:'.$Settings->loop.',
        counterText:"'.$Settings->counterText.'"
    });
    });
</script>
<style>#lbBottomContainer{display:none;}</style>

什么?你问我干嘛把 php 放出来?因为我在占篇幅啊略略略

OK,关键代码 find ,可能在 jQuery(function($) {}); 里调用 jQuery 选择器才会有效(我真傻啊,jQuery 选择器 jQuery 选择器,那当然需要在某种 jQuery 环境下才能引用啦)。搜索找到了初始化 FancyBox 的代码,但是官网示例好像直接不初始化也能用?管他呢,加上!
最后就这样写:

<script type="text/javascript" src="/path/to/fancybox.js"></script>
<script type="text/javascript">
jQuery(function($) {
    $("img.lazy").each(function () {
        var element = document.createElement("a");
        $(element).attr("href", $(this).attr("src"));
        $(element).attr("data-fancybox", "gallery");
        $(element).attr("data-caption", $(this).attr("alt"));
        $(this).wrap(element);
    });
    // 这里也用 jQuery 选择器对包含 <img> 标签的 <a> 标签调用 fancybox 方法
    // $("a.has(img)").fancybox({
    //     /* some configure */
    //     'autoScale' : true,
    // });
});
// 一切加载完成后初始化 FancyBox
$(document).ready(function() {
    $("[data-fancybox]").fancybox()
});
</script>

已在另外一个主题上适配成功(毕竟人家的主题只要引用上 js css script 就完事了),但是本站的 Material 主题仍然有“加载后图片消失”的问题,折腾不来折腾不来,说不定跟 Ajax 有关系吧?但是这主题有 Ajax 吗?好像没有吧……

所以,鉴于 FancyBox 装不上去,打算换个主题呢!Handsome 主题在另外一个小站吃灰已久,是不是该转正了呢


如你所见,本站换上了 熊猫小A 的 VOID 主题,主题链接可以看本站底部。

其实很早就看到了这款主题,感觉很别致。熊猫小A 的主页亦是如此。3.0.0 版本的 VOID 已经风格大变,但是我还是不太习惯,所以选择了 2.4.0 版本的安装上了。关于主题特性不在赘述,基本如你所见。刚才打开主题介绍页面,我觉得开发者很用心,这是从主题发布博文中摘取的几段话:

“既然是挂上了 MIT 许可的开源项目,自然就没有立场干涉别人怎么用。但多少是自己的作品,心底里对别人如何使用它还是有所期待的。”
“若要我说出最诚实的想法:我希望使用这些主题的博主,能认真地多写几篇正经文章,这才是独立博客的精髓。一两句话的牢骚,大可以去微博与 Twit­ter 上说;花花绿绿的代刷广告与盗版采集还是免了吧。”
“VOID 的排版很规整,可以用来修改的空间并不大,甚至连个广告都很难找到合适的地方放。再加上图片占了很大比重,若是不认真对待,恐怕用这个主题的结果就很难看了。这是自损八百的做法:我丢失了一部分潜在的使用者。但并非不值得。去除了繁杂的功能、版式,最终还是回归到文本上来。”
“作为一个写主题的人,能做的只有为博主带来无障碍的写作环境、为读者带来无障碍的阅读环境。不要去打击博主可能的创作欲,也不要给想获取信息的读者平添难度。”
...

说实话,我时常觉得自己键盘下的博文简直是糟蹋主题,但又经常抱着“自己的博客嘛反正又没人看”的心态将文发布出来,给自己带来一点快乐。现在亦是如此,本来想尝试为 Material 适配 FancyBox 的,结果最后水了一篇文章后选择更换主题。实属无能。但是,我做博客的初衷原本就是写我所想,记我所思,超脱诸如 QZone Wechat 的圈子,不是家长师长监督自己的地方、也不是同学朋友扯犊子的地方。你看,在这里写什么无所谓,不想看的人可以在网页仍未加载出来之前关闭网页,不想理你的人甚至不想摸键盘输入任何信息。但是正是如此才可以交到很多志同道合的朋友,互相看看博文多么快乐~

咳咳,说一点正事吧,参考 权那他 的《让博客评论起来更方便》文章为本主题添加了自动填写名字和邮箱的功能,支持 GitHub + QQ 账号。但是缺点就是评论表格看起来非常拥挤,尤其是手机上。。。
VOID 主题修改 2 个文件即可

  • </usr/themes/VOID/includes/comments.php 39 行
// 在后面加上这个
<div class="comment-info-input">
    <input aria-label="GH账号快速评论" type="text" id="githubNum" for="githubNum" placeholder="GH账号快速评论" value="<?php $this->remember('githubNum'); ?>" />
    <input aria-label="QQ账号快速评论" type="text" id="qqNum" for="qqNum" placeholder="QQ账号快速评论" value="<?php $this->remember('qqNum'); ?>" />
</div>
  • </usr/themes/VOID/includes/comments.php 适当位置
<script>
    function isEmpty(obj) {
        return typeof obj == "undefined" || obj == null || obj == "";
    }
    $(document).on("input propertychange", "#githubNum", function (event) {
            event.preventDefault();
            let oldVal = $(this).val();
            let github = window.setTimeout(function () {
                let newVal = $("#githubNum").val();
                if (newVal.length > 0 && oldVal === $("#githubNum").val()) {
                    $.ajax({
                        url: 'https://api.github.com/users/' + newVal,
                        dataType: 'jsonp',
                        scriptCharset: "GBK",
                        contentType: "text/html; charset=GBK",
                        success: function (data) {
                            console.log(data);
                            let personal = data["data"];
                            $('#author').val(isEmpty(personal["name"]) ? personal["login"] : personal["name"]);
                            $('#url').val(isEmpty(personal["blog"]) ? personal["html_url"] : personal["blog"]);
                            $('#mail').val(isEmpty(personal["email"]) ? "@" : personal["email"]);
                        }
                    })
                }
            }, 1000);
    });
    $(document).on("input propertychange", "#qqNum", function (event) {
            event.preventDefault();
            let oldVal = $(this).val();
            let qq = window.setTimeout(function () {
                let newVal = $("#qqNum").val();
                if (newVal.length > 0 && oldVal === $("#qqNum").val() && !newVal.isNaN) {
                    $.ajax({
                        url: 'https://api.krait.cn/?interface=personage&target=tencent&object=' + newVal,
                        // 这里可以根据原文改用自己的 API
                        dataType: 'jsonp',
                        jsonpCallback: 'portraitCallBack',
                        scriptCharset: "GBK",
                        contentType: "text/html; charset=GBK",
                        success: function (data) {
                            console.log(data);
                            $('#author').val(data["nickname"]);
                            $('#mail').val(data["email"]);
                        }
                    })
                }
            }, 500);
    });
</script>

在这里顺便安利 权那他 开发的 Typecho Nabo APP ,为 Typecho 玩家在客户端撰写发布修改文章、订阅 RSS 源提供了非常舒适的环境。妈妈再也不用担心我抢不到友链大佬博文评论区的沙发辣!

  • 最后为 VOID 主题“归档”页面添加标签云栏目。初衷是精简单页来着,发现这个归档按年折叠含蛮好玩的,顺手折腾一下,把原来 Material 主题的标签云移植过来。修改 usr/themes/VOID/Archive.php
// 18 行后添加标签云样式:
<style>
.material-tagscloud{padding-left: 1.5rem !important;}
.material-tagscloud a{text-decoration:none; margin: 9px 1px; line-height: 40px; white-space: nowrap; transition: .6s; opacity: .85;}
.material-tagscloud a:hover{transition: .6s; opacity: 1; background: #FAFAFA; box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);}
.material-tagscloud::after{content: attr(data-num) " 个" !important;}
</style>

// 修改后的文件 51 行后添加(请自己注意位置):
<section class="material-tagscloud year shrink" data-year="Tags" data-num="<?php echo Utils::getTagNum(); ?>">
    <?php $this->widget('Widget_Metas_Tag_Cloud','sort=name&ignoreZeroCount=1&desc=0')->to($tag);$max = 0; ?>
    <?php while ($tag->next()) if ($tag->count > $max) $max = $tag->count; ?>
    <?php while ($tag->next()): ?>
        <a href="<?php $tag->permalink(); ?>" style="font-size: <?php echo round($tag->count/$max*15+15,2); ?>px;color: rgb(<?php echo(rand(0, 255)); ?>, <?php echo(rand(0,255)); ?>, <?php echo(rand(0, 255)); ?>"><?php $tag->name(); ?></a>
    <?php endwhile; ?>
    <a role=button aria-label="收起与展开列表" class="toggle-archive" target="_self" href="javascript:void(0);" onclick="VOID.toggleArchive(this);"><?php if($index > 0) echo '+'; else echo '-'; ?></a>
</section>

好啦,就这样,戳 这里 看看本站效果,自己感觉看起来还不错,除了颜色有点花里胡哨之外...

添加新评论

已有 8 条评论

表示一脸懵逼,我太难了

MonsterX MonsterX 回复 @乐心湖

慢慢混呗

:aru30: 转正

MonsterX MonsterX 回复 @c0sMx

我也想入 Hran 大佬的主题,,,好纠结嗷,怎么都这么好看!

来用我的主题呀(逃)

MonsterX MonsterX 回复 @ZigZagK

:aru52: 我要专一!

MonsterX MonsterX 回复 @二吉

:aru16: 又水一篇文章,真对不起各位访客