Runoneall

Runoneall's Blog

首页
关于
链接
搜索
RSS
Sitemap
Email

查看博客友链最新更新了什么?

  • 作者: Tom Brown
  • 时间: 2025-03-18
  • 分类: 默认  

这是对 https://dev.oneall.eu.org/archives/32/ 的补充
在原有友链基础上增加可选的 rss 选项

支持自动分析 rss 和 atom

// 本人js不好大体是这么个意思
// 使用 https://dev.oneall.eu.org/archives/49/ 跨域请求
function xhrGet(url) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", "https://dev.oneall.eu.org/netdrive.php/" + url, true);
        xhr.onload = function () {
            if (xhr.status >= 200 && xhr.status < 300) {
                resolve(xhr.responseText);
            } else {
                reject(new Error(`HTTP Error: ${xhr.status}`));
            }
        };
        xhr.onerror = function () {
            reject(new Error("Network Error"));
        };
        xhr.send();
    });
}

async function putRss(linkItemsArea, rssLinkItems) {
    if (rssLinkItems.length === 0) {
        return;
    }
    linkItemsArea.innerHTML += `<div id="links-rss"><h2>近期更新</h2><ul></ul></div>`;
    const rssItemsArea = linkItemsArea.querySelector("#links-rss ul");
    for (const rssLinkItem of rssLinkItems) {
        xhrGet(rssLinkItem)
            .then((xmlString) => {
                const xmlStringParser = new DOMParser();
                const xmlDoc = xmlStringParser.parseFromString(
                    xmlString,
                    "text/xml",
                );
                atomFeed = xmlDoc.getElementsByTagName("feed");
                rssFeed = xmlDoc.getElementsByTagName("rss");
                if (atomFeed.length > 0) {
                    const blogName =
                        atomFeed[0].getElementsByTagName("title")[0]
                            .textContent;
                    rssItemsArea.innerHTML += `<h3>${blogName}:</h3>`;
                    const first10Items = [
                        ...atomFeed[0].getElementsByTagName("entry"),
                    ].slice(0, 10);
                    first10Items.forEach((item) => {
                        const blog_title =
                            item.getElementsByTagName("title")[0].textContent;
                        const blog_link = item
                            .getElementsByTagName("link")[0]
                            .getAttribute("href");
                        rssItemsArea.innerHTML += `<li><a href="${blog_link}" target="_blank">${blog_title}</a></li>`;
                    });
                } else if (rssFeed.length > 0) {
                    const blogName =
                        rssFeed[0].getElementsByTagName("title")[0].textContent;
                    rssItemsArea.innerHTML += `<h3>${blogName}:</h3>`;
                    const first10Items = [
                        ...rssFeed[0].getElementsByTagName("item"),
                    ].slice(0, 10);
                    first10Items.forEach((item) => {
                        const blog_title =
                            item.getElementsByTagName("title")[0].textContent;
                        const blog_link =
                            item.getElementsByTagName("link")[0].textContent;
                        rssItemsArea.innerHTML += `<li><a href="${blog_link}" target="_blank">${blog_title}</a></li>`;
                    });
                } else {
                    console.log("Unknown feed type " + rssLinkItem);
                }
            })
            .catch(() => {});
    }
}

function putLinks(link_json) {
    const linkJson = JSON.parse(link_json);
    const linkItemsArea = document.getElementById("linkItemsArea");
    let linkItemsHTML = "";
    let rssLinkItems = [];
    for (const linkItem of linkJson) {
        linkItemsHTML += `<div class="link-item"><img class="link-item-avatar" src="${linkItem.avatar}"><div class="link-item-content"><a href="${linkItem.url}" target="_blank"><h2>${linkItem.title}</h2></a><p>${linkItem.description}</p></div></div>`;
        if (linkItem.rss) {
            rssLinkItems.push(linkItem.rss);
        }
    }
    linkItemsArea.innerHTML = linkItemsHTML;
    setTimeout(() => putRss(linkItemsArea, rssLinkItems), 0);
}
#linkItemsArea {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
}

@media screen and (max-width: 700px) {
    #linkItemsArea {
        grid-template-columns: repeat(1, 1fr);
    }
}

.link-item {
    height: 100px;
    overflow: hidden;
    border: 1px solid gray;
}

.link-item a {
    color: inherit !important;
}

.link-item-avatar {
    float: left;
    width: auto;
    height: auto;
    max-height: 100%;
    margin-right: 10px;
    border-right: 1px solid gray;
}

.link-item-content {
    height: 100%;
}

#linkItemsArea #links-rss {
    grid-column: 1 / -1;
}

效果:异步加载最新 10 篇文章

具体可看:https://dev.oneall.eu.org/links.html(若发现错位就是缓存未失效)

© 2025 Runoneall. Old Fasion Theme. Powered by Hexo.