[搁置] PandaBangumi.js 笔记

这两天在调试 PandaBangumi 插件,尝试将三次元的剧集也都展示出来,毕竟好看的电视剧、电影还是蛮多呢。放假前有天没事干我特意在 Bangumi 三次元片单里从第一页翻到最后一页把看过的剧全加到“看过”里了。但是 bgm.tv 毕竟还是二次元为主吧跟豆瓣不能比...关键是插件 API 获取有 25 部的限制,网页获取又出了问题(作者博客还是可以展示全部的,我这里可能是自己改了什么代码出错了)。所以我打开本地缓存的 watched.json 文件尝试自行写入,并修改了插件规则跳过已看缓存的刷新。结果打发时间的我一下子添加了两百多部剧集,还把豆瓣上的也拉了过来,.json 写了 57k 。然后就啥也显示不出来了。再看一眼插件代码发现可能是 json 解码占用内存超限了。

昨天正一筹莫展之时发现友情链接页面的排版和追剧展示的排版几乎一样,想了想友情链接的输出...哦!是 Links 插件!是数据库!兴奋的我连夜把 Links 插件改了改,Iveseen 插件 beta 诞生了!我尝试将剧集像友链一样全部存入数据库,这两百多部剧集又花了我今天半下午。但是有一个问题就是虽然展示确实可以,但一次性加载 200 多张电影海报还是十分难看的。我想让追剧展示的效果和 PandaBangumi 一样实现点击加载。

可惜,本来应该就是这么一个挺简单的需求,不了解 JavaScript 的我搜索了半天也没找到一个合适的模板。我又回过头来看 PandaBangumi 的插件,希望从大佬的代码学到点什么!于是我开始寻找他的实现方式。在 PandaBangumi.js 中我发现了奥秘。开工!

反复读这个 js 发现 Json 文件在这段 JavaScript 中经过 $.getJSON(url, function(data){}) 解码输出,那我要做的工作就是 将 Links 的输出作为这段 JavaScript 的输入

没有学 Javascript 所以需要把常用的函数/这段代码中反复用的函数弄弄清楚,是干嘛的?返回了啥?忘记了的和新学的都记一下笔记:

  • (function(){})(); 创建后立即执行的匿名函数
    它是立即调用的函数表达式,简称 IIFE 。它在创建后立即执行,与任何事件(例如 document.onload )的事件处理程序无关,内部使用的所有变量在其范围之外都不可见。(学习:What is the (function() { } )() construct in JavaScript? - Stack Overflow
  • String() 将不同的对象转换为字符串
  • typeof 运算返回一个变量、对象、函数或表达式的类型
  • jQuery 选择器 $("") :上次折腾友链随机输出的时候看过了

  • jQuery 属性操作 attr() 方法:设置或返回被选元素的属性值

    • $(selector).attr(attribute) 返回被选元素的属性值
    • $(selector).attr(attribute,value) 设置被选元素的属性和值
  • jQuery 文档操作 html() 方法:返回或设置被选元素的内容 (inner HTML)

    • $(selector).html() 返回第一个匹配元素的内容
    • $(selector).html(content) 覆盖所有匹配元素的内容
    • $(selector).html(function(index,oldcontent)) 使用函数来设置所有匹配元素的内容
  • jQuery 文档操作 append() 方法:在被选元素的结尾(仍然在内部)插入指定内容

    • $(selector).append(content) 在被选元素的结尾插入指定内容
    • $(selector).append(function(index,html)) 使用函数在指定元素的结尾插入内容
  • jQuery 遍历 each() 方法:为每个匹配元素规定运行的函数

下面是 PandaBangumi.js 源文件,看懂之后开始着手修改。

function loadMoreBgm(loader){
    if (loader === 'all') {
        // 加载页面上的全部面板
        $.each($('.loader'), function(i, item){
            loadMoreBgm(item);
        })
        return;
    }

    $(loader).html('<div class="dot"></div><div class="dot"></div><div class="dot"></div>');
    
    // 拼接 URL
    var listEl = $($(loader).attr('data-ref'));
    var bgmCur = listEl.attr('bgmCur');
    bgmCur = typeof bgmCur === 'string' ? parseInt(bgmCur) : 0;
    var type = listEl.attr('data-type');
    var cate = listEl.attr('data-cate');

    var url = bgmBase+'?from=' + String(bgmCur) + '&type=' + type + '&cate=' + cate;
    $.getJSON(url, function(data){
        $(loader).html('加载更多');
        if(data.length<1) $(loader).html('没有了');
        
        $.each(data, function (i, item) {
            var name_cn = item.name_cn ? item.name_cn : item.name;
            var status;
            var total;
            if(!item.count || item.count==null) {
                status=100;
                total='未知';
            }
            else {
                status=item.status/item.count*100;
                total=String(item.count);
            };
            var html=`<a class="bgm-item" data-id="`+item.id+`" href="`+item.url+`" target="_blank">
                        <div class="bgm-item-thumb" style="background-image:url(`+item.img+`)"></div>
                        <div class="bgm-item-info">
                            <span class="bgm-item-title main">`+item.name+`</span>
                            <span class="bgm-item-title">`+name_cn+`</span>
                            status-bar}}
                        </div>
                    </a>`;
            if (type === 'watching') {
                html = html.replace('{{status-bar}}', `
                            <div class="bgm-item-statusBar-container">
                                <div class="bgm-item-statusBar" style="width(`+String(status)+`%"></div>
                                进度:`+String(item.status)+` / `+total+`
                            </div>`);
            } else {
                html = html.replace('{{status-bar)', '');
            }
            listEl.append(html);

            bgmCur++;
        })

        // 记录当前数量
        listEl.attr('bgmCur', String(bgmCur));
    })
}

function initCollection(){
    var bgmIndex = 0;
    $.each($('.bgm-collection'), function(i, item) {
        bgmIndex++;
        $(item).attr('id', 'bgm-collection-' + String(bgmIndex));
        $(item).after(
                '<div class="loader" data-ref="' + '#bgm-collection-' + String(bgmIndex) + '" onclick="loadMoreBgm(this);"></div>');
    });

    loadMoreBgm('all');
}

$(document).ready(function(){
    initCollection();
})

$(document).on('pjax:complete', function () {
    initCollection();
})

19 行的 bgmBase 变量是插件在头部输出的,由插件 php 添加的路由,算是获取已看缓存的接口

var bgmBase="https://monsterx.cn/PandaBangumi"

一开始我没注意这个地方,以为这个拼接的 url 返回的是全部 json ,后来发现这个只返回了要加载的 item 的 json ,我直接把这个改成我的全部剧集 json 地址时效果就变成了所有 item 全部输出,点击加载后又将所有 item 再加载一遍永无止境。

我的思路是将数组依旧全部输出,然后用类似 C 语言 for 的结构输出;或者将数组分次输出。

先尝试将数组全部输出。

边写边发…待更咕咕

添加新评论

本站现启用评论投票,被踩的太多就会自动折叠 QwQ ,快来试试吧 ~
评论提交失败请点Artalk备用评论


这里还没有评论哦