KoriIku / luxirty-search

一个搜索引擎,基于 Google,屏蔽内容农场,无广告,无跟踪,干净,简洁,快。
https://search.luxirty.com
GNU Affero General Public License v3.0
1.32k stars 129 forks source link

关于自动翻页 #4

Open chenxuuu opened 1 month ago

chenxuuu commented 1 month ago

我写了一个看起来很丑陋的实现,不过放到油猴里面运行也还过得去吧

let lastPage = 0;
let searchResults = [];
function loadNextPage() {
    //记录当前的滚动条位置
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    //备份class="gsc-expansionArea"内的数据
    let expansionArea = document.querySelector(".gsc-expansionArea").cloneNode(true);
    expansionArea.className = "gsc-expansionArea-backup";
    searchResults.push(expansionArea);
    //模拟点击下一页
    document.querySelectorAll(".gsc-cursor-page")[lastPage+1].dispatchEvent(new Event('click'));

    let timer = setInterval(() => {
        if(document.querySelector(".gsc-loading-resultsRoot") == null)
        {
            clearInterval(timer);
            //将备份的数据插入到class="gsc-results"最开头,反着插入
            for(let i = searchResults.length-1; i >= 0; i--)
            {
                document.querySelector(".gsc-results").insertBefore(searchResults[i].cloneNode(true), document.querySelector(".gsc-results").firstChild);
            }
            //滚动到之前的位置
            window.scrollTo(0, scrollTop);
            lastPage++;
            observer.observe(document.querySelector('.gsc-cursor-page'));
        }
    },50);
}

// 创建IntersectionObserver实例
const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            console.log('Element is in view!');
            //停止观察
            observer.unobserve(entry.target);
            //加载下一页
            loadNextPage();
        }
    });
});

// 开始观察目标元素
observer.observe(document.querySelector('.gsc-cursor-page'));
KoriIku commented 1 month ago

感谢!目前我简单地测试了一下,似乎有两个问题:1. 加载的时候滚动条跳动还是有点影响体验 2. 模拟点击的时候整个页面会变暗。不知道是不是我的使用方式不对。 非常感谢你的代码提供的思路,我会继续进行一些改进的尝试,直到它足够好用。 这个issue请保持开启,用于专门讨论此功能的实现。

chenxuuu commented 1 month ago

真要完全自己控制的话,我看还是需要把event调用的接口自己找出来,手动去调用获取下一页的哪个api,最后自己把新的搜索结果画出来放进html 这个接口返回的是一段js,会去调用你用get参数传入的回调函数名,传入参数是一大段json数据

chenxuuu commented 1 month ago

具体的获取接口,我测试下来需要的参数有这些:

https://cse.google.com/cse/element/v1?rsz=filtered_cse&num=100&start=0&cx=d0753b9ad66c34097&q=搜索参数&cse_tok=字符串&filter=1&callback=google.search.cse.api3221&safe=off

chenxuuu commented 1 month ago

改了个新脚本,滚动条倒是不会跳了,实现方式依旧很让人难绷😂

let lastPage = 0;
let searchResults = [];
function loadNextPage() {
    //记录当前的滚动条位置
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    //备份class="gsc-expansionArea"内的数据
    let expansionArea = document.querySelector(".gsc-expansionArea").cloneNode(true);
    expansionArea.className = "gsc-expansionArea-backup";
    searchResults.push(expansionArea);
    //禁用滚动
    let oldScrollIntoView = Element.prototype.scrollIntoView;
    Element.prototype.scrollIntoView = function () { };
    //模拟点击下一页
    document.querySelectorAll(".gsc-cursor-page")[lastPage + 1].dispatchEvent(new Event('click'));

    let timer = setInterval(() => {
        if (document.querySelector(".gsc-loading-resultsRoot") == null) {
            clearInterval(timer);
            //恢复滚动
            Element.prototype.scrollIntoView = oldScrollIntoView;
            //将备份的数据插入到class="gsc-results"最开头,反着插入
            for (let i = searchResults.length - 1; i >= 0; i--) {
                document.querySelector(".gsc-results").insertBefore(searchResults[i].cloneNode(true), document.querySelector(".gsc-results").firstChild);
            }
            //滚动到之前的位置
            window.scrollTo(0, scrollTop);
            lastPage++;
            observer.observe(document.querySelector('.gsc-cursor-page'));
        }
    }, 50);
}

// 创建IntersectionObserver实例
const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            console.log('Element is in view!');
            //停止观察
            observer.unobserve(entry.target);
            //加载下一页
            setTimeout(loadNextPage, 200);
        }
    });
});

// 开始观察目标元素
observer.observe(document.querySelector('.gsc-cursor-page'));