上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

大佬帮我看一下DOM节点被删除的问题

[复制链接]
  • TA的每日心情
    无聊
    2023-10-4 13:26
  • 签到天数: 2 天

    [LV.1]初来乍到

    3

    主题

    14

    回帖

    17

    积分

    助理工程师

    积分
    17
    发表于 2023-6-7 17:45:50 | 显示全部楼层 | 阅读模式
    悬赏2油猫币未解决

    本帖最后由 zoenbo 于 2023-6-7 17:46 编辑

    我想让所有加载出来的DOM元素节点不要因为向下滚动而被删除,
    当翻到8页的时候第一个.page下的.canvasWrapper和.textLayer会被删除,
    .page的行内属性data-loaded="true"也会跟着删除掉,

    这个所代替了~
    下边的脚本只能保持.canvasWrapper和.textLayer不被删除,
    但不是我要的最终效果,
    我想让所有已加载的.page和节点原封不动的保留(不要loadingIcon notVisible出现,也不要让data-loaded="true"消失),

    总之要的结果就是不管下翻多少页,往上翻时不用重新加载~

    大佬帮帮忙,帮我修改下,我实在是解决不了了~
    (改JS的方法会,想用脚本来实现)

    @李恒道

    页面:http://biaozhun.osta.org.cn/pdfview.html?code=597

    // ==UserScript==
    // @name         Block Node Operations
    // @namespace    YOU    
    // @version      1
    // @description  Block operations on specific nodes in a web page
    // @match        http://biaozhun.osta.org.cn/pdfview.html?code=*
    // @grant        none
    // ==/UserScript==
    
    (function() {
        'use strict';
    
        const observer = new MutationObserver(mutations => {
            for (const mutation of mutations) {
                if (mutation.type === 'attributes' && mutation.attributeName === 'data-loaded') {
                    const page = mutation.target.closest('.page');
                    if (page && !page.getAttribute('data-loaded')) {
                        console.log("Setting data-loaded attribute to true for .page element");
                        page.setAttribute('data-loaded', 'true');
                    }
                }
            }
        });
    
        observer.observe(document.body, { childList: true, subtree: true });
    
        const originRemove = HTMLDivElement.prototype.remove;
        const originRemoveChild = HTMLDivElement.prototype.removeChild;
    
        Object.defineProperty(HTMLDivElement.prototype, 'remove', {
            value: function () {
                if ((this.classList.contains("canvasWrapper") || this.classList.contains("textLayer")) && !this.closest('.page')) {
                    console.log("Rejected remove", this);
                    return;
                } else {
                    originRemove.apply(this, arguments);
                }
            },
            configurable: true,
            enumerable: true,
            writable: true,
        });
    
        Object.defineProperty(HTMLDivElement.prototype, 'removeChild', {
            value: function (element) {
                if ((element.classList.contains("canvasWrapper") || element.classList.contains("textLayer")) && !element.closest('.page')) {
                    console.log("Rejected removeChild", element);
                    return;
                } else {
                    originRemoveChild.apply(this, arguments);
                }
            },
            configurable: true,
            enumerable: true,
            writable: true,
        });
    })();

  • TA的每日心情
    无聊
    2023-10-4 13:26
  • 签到天数: 2 天

    [LV.1]初来乍到

    3

    主题

    14

    回帖

    17

    积分

    助理工程师

    积分
    17
    发表于 2023-6-7 18:30:31 | 显示全部楼层
    @李恒道 有请大佬~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    638

    主题

    5234

    回帖

    6105

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6105

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2023-6-7 18:50:22 | 显示全部楼层
    mutationObeserve是监听改变
    在触发事件的时候已经被删除了
    可以考虑用 EventTarget上的remove劫持判断this阻止删除
    const oldRemove=Element.prototype.remove

    Element.prototype.remove=function (...args){
       console.log('this,...args',this,...args)
        if(this.className==='textLayer'||this.className==='canvasWrapper'){
          return;
        }
        return oldRemove.call(this,...args)
    }
    但是如果即使解除了dom,网页中的实例已经销毁,实际二次依然会重新渲染
    这个时候只能尝试去研究销毁的机制
    首先打dom销毁断点,堆栈回溯找到
      _createClass(PDFPageViewBuffer, [{
        key: "push",
        value: function push(view) {
          var buf = _classPrivateFieldGet(this, _buf);

          if (buf.has(view)) {
            buf["delete"](view);
          }

          buf.add(view);

          if (buf.size > _classPrivateFieldGet(this, _size)) {
            _classPrivateMethodGet(this, _destroyFirstView, _destroyFirstView2).call(this);
          }
        }
      }
    这里可以看到每次push循环判断大小,然后触发销毁
    _classPrivateMethodGet(this, _destroyFirstView, _destroyFirstView2).call(this);
    那我们核心思路就变成了劫持push
    是通过_createClass调用的
    看_createClass
    function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

    function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }

    可以看到是原型挂载
    所以直接打印PDFPageViewBuffer.prototype.push即可触发到push
    劫持push再通过函数拿大小/修改size/修改函数等等即可实现操作
    这部分就留给你做课后作业了
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2023-10-4 13:26
  • 签到天数: 2 天

    [LV.1]初来乍到

    3

    主题

    14

    回帖

    17

    积分

    助理工程师

    积分
    17
    发表于 2023-6-7 18:59:11 | 显示全部楼层
    李恒道 发表于 2023-6-7 18:50
    mutationObeserve是监听改变
    在触发事件的时候已经被删除了
    可以考虑用 EventTarget上的remove劫持判断this ...

    大佬威武,让我学到了新思路~超级感谢~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-14 00:00
  • 签到天数: 119 天

    [LV.6]常住居民II

    29

    主题

    599

    回帖

    536

    积分

    专家

    积分
    536

    油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2023-6-7 21:46:13 | 显示全部楼层
    zoenbo 发表于 2023-6-7 18:59
    大佬威武,让我学到了新思路~超级感谢~

    哥哥这是要做啥脚本?我看各种方法都用上了,必定不一般,啥时候能做好给咱们瞧瞧
    入驻爱发电 让这世界充满爱 https://afdian.net/a/vpannice
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2023-10-4 13:26
  • 签到天数: 2 天

    [LV.1]初来乍到

    3

    主题

    14

    回帖

    17

    积分

    助理工程师

    积分
    17
    发表于 2023-6-7 22:26:17 | 显示全部楼层
    脚本体验师001 发表于 2023-6-7 21:46
    哥哥这是要做啥脚本?我看各种方法都用上了,必定不一般,啥时候能做好给咱们瞧瞧 ...

    这个就是网上看书的,一翻页之前的内容就消失重新加载,所以想解决这个问题,个别网站有加密不用调试代码...菜鸟的笨办法
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表