gpt4 book ai didi

javascript - 防止在Tumblr仪表板上删除DOM元素

转载 作者:行者123 更新时间:2023-12-04 01:46:55 28 4
gpt4 key购买 nike

注意:这是对my previous one的后续问题。

我决定通过#posts元素内的扩展程序将帖子显示在仪表板上。现在我的问题是 Tumblr在滚动时会自动删除帖子的内容。

这是删除之前的普通帖子的示例:

<li class="post_container" data-pageable="post_110141415125">
<div class="post post_full ..." [...]>
<!-- ... -->
</div>
</li>

和相同的帖子在删除其内容的之后:
<li class="post_container" data-pageable="post_110141415125" style="border-radius: 3px; height: 207px; width: 540px; background-color: rgb(255, 255, 255);">
</li>

由于我的扩展程序将帖子重新定位为类似pinterest的布局,因此删除了帖子内容,使整个布局变得困惑。是否可以阻止Tumblr仪表板删除每个.post中的DOM元素?

编辑:

我在内容脚本中为removeChild方法添加了此注入(inject)代码:
function addScript(){
var script = document.createElement('script');
script.id = 'newRemoveChildScript'; ///just to find is faster in the code
script.src = chrome.extension.getURL("injectedCode.js");
$($('script')[0]).before(script); ///Script is indeed present, I checked that
}

window.onload = addScript;

我接下来要做的是使用第二个版本创建injectedCode.js文件,如下所示:
(function (obj, method) {
function isPost(el) {
return (/^post_\d+$/.test(el.id) && ~el.className.indexOf('post'));
}
obj[method] = (function (obj_method) {
return function (child) {
if (isPost(child)) return child;
return obj_method.apply(this, arguments);
}
}(obj[method]));
}(Element.prototype, 'removeChild'));

当我加载Tumblr-Dashboard时,我可以确认Script元素存在于head元素中。该文件也已正确链接,因为“removeChild”功能仅被调用一次。似乎在那里删除了脚本元素。

从那时起,该函数就不再被调用,我可以再次看到那些“空”的帖子。

最佳答案

劫持Tumblr仪表板行为
免责声明:此处完全合法,请不要惊慌!
您要问的是并不是一件容易的事,但是实际上您可以阻止Tumblr在离开视口(viewport)时在滚动时隐藏帖子。更准确地说,高级程序员实际上可以操纵任何Tumblr方法,使其表现出所需的状态,但是,现在,让我们集中讨论您的问题。
为什么Tumblr在滚动时会删除帖子?
Tumblr删除了帖子的内容,使页面变淡,并且由于包含大量元素,您可以继续浏览而不会出现任何滞后和/或滚动。想象一下,连续向下滚动一个小时:您的破折号将包含数千个帖子,并且由于每次滚动都必须移动过多的内容,因此浏览器可能会冻结。
Tumblr如何做到这一点?
我没有检查和理解Tumblr代码的每一行,因为它们都是打包的/最小化的,而且实际上不可能理解任何方法的一行(除非您在Tumblr工作,在这种情况下,恭喜您),但是,基本上,我放了一些DOM breakpoints,并且检查了将帖子移出视口(viewport)时删除帖子的部分代码。
简而言之,这就是它的作用:

  • Tumblr为帖子创建一些自定义且巧妙的“滚动”事件。每当帖子离开视口(viewport)超过一定距离时,这些事件就会触发
  • 现在,Tumblr将一些侦听器附加到这些自定义事件,并且使用li.post_container元素上的 DOM断点,您将能够看到这些侦听器位于dashboard.js JavaScript文件中。

    更确切地说,删除帖子内容的代码的确切部分如下所示:
    function j(t,v) { try{ t.removeChild(v) } catch(u){} }
    其中tli.post_containerv是其子代:div#post_[id]
    这部分代码做什么?没什么特别的:它从字面上从其父div#post_[id] 中删除了li.post_container元素。
  • 现在Tumblr必须使用样式设置已删除帖子的容器,以保持#posts元素的高度,该元素保存所有帖子,否则删除帖子的内容会使页面向下滚动H像素,其中H是高度被删除的职位。
    此更改发生在另一个脚本index.js中,并且我什至没有仔细研究它,因为它根本无法阅读:

    顺便说一句,这个脚本并不重要,因为我们可以使用简单CSS来防止样式更改
  • 现在,帖子的内容已被“删除”,看起来像这样:

    *为清楚起见:我添加了文字和墓碑,您实际上并没有看到它们

  • 因此,最后,当帖子离开视口(viewport)时,将发生以下变化:
    <li class="post_container" [...]>
    <div id="post_[id]" class="post post_full ..." [...]>
    <!-- post body... -->
    </div>
    </li>
    对此:
    <li class="post_container" [...] style="border-radius: 3px; height: Hpx; width: Wpx; background-color: rgb(255, 255, 255);">
    </li>
    防止Tumblr代码删除帖子(确实有些小技巧)
    既然我们知道了Tumblr在仪表板上滚动时的行为,我们就可以阻止它删除帖子并将其样式设置为以使其看起来像是带有圆角边框的空白死块。
    风格第一
    在注意防止将其移除时,我们应该将其样式设置为不具有固定的高度和宽度,以覆盖Tumblr在其离开视口(viewport)时应用于它们的样式。
    我们可以在页面中注入(inject)一些简单的CSS,使规则!important防止内联样式覆盖它们。这是我们要添加的CSS:
    li.post_container {
    height: auto !important;
    width: 540px !important;
    /* 540px is the default width
    * change it to any amount that applies to your layout
    */
    }
    或者,使用JavaScript,我们可以执行以下操作:
    var s = document.createElement('style');
    s.textContent = 'li.post_container{height:auto!important;width:540px!important;}';
    document.head.appendChild(s);
    防止删除帖子:简便(愚蠢)方式
    如果我们不想浪费时间思考一个好的解决方案,我们可以实现最简单的解决方案,并且,在几行代码中,我们可以:
  • 复制removeChildElement.prototype方法,并将其命名为_removeChild
  • 用一种“过滤”对它的调用的功能替换原来的,从而决定除去帖子以外的任何内容。

  • 这是解决问题的简单但愚蠢的代码:
    Element.prototype._removeChild = Element.prototype.removeChild
    Element.prototype.removeChild = function(child) {
    // Check if the element is a post (e.g. the id looks like "post_123456...")
    if (/^post_\d+$/.test(child.id)) {
    // If so, stop here by returning the post
    // This will make Tumblr believe the post has been removed
    return child;
    }

    // Otherwise the element isn't a post, so we can remove it
    return Element.prototype._removeChild.apply(this, arguments);
    }
    代码长度,无注释:5行
    您显然可以检查多个条件:例如,您可以检查帖子是否包含postpost_full类,或者它的parentElement是否具有post_container类,依此类推……由您决定。
    防止删除帖子:聪明(更困难)的方式
    完成此操作的一种更优雅但又巧妙的方法是使用一些闭包和更复杂的逻辑来“编辑”原始Element.prototype.removeChild方法。这是我们要做的:
  • 创建一个闭包,在其中我们将重新定义Element.prototype.removeChild方法,为其添加一个“过滤器”。
  • 在此闭合中,我们将定义我们的自定义过滤器函数(可以称为isPost()),以过滤将要删除的元素
  • 使用第二个闭包,我们将重新定义Element.prototype.removeChild方法,使其表现如下:
  • 使用我们先前创建的过滤器函数isPost()检查元素以删除
  • 如果要删除的元素是帖子,则在此处停止,不要删除它。
  • 否则,继续并使用Element.prototype.removeChild方法调用原始.apply方法。


  • 它看起来似乎很困难,但是代码并不难理解,为了使它更易于理解,我在其中添加了注释,它是:
    (function (obj, method) {
    // This is all wrapped inside a closure
    // to make the new removeChild method remember the isPost function
    // and maintain all the work invisible to the rest of the code in the page

    function isPost(el) {
    // Check if the element is a post
    // This will return true if el is a post, otherwise false
    return (/^post_\d+$/.test(el.id) && ~el.className.indexOf('post'));
    }

    // Edit the Element.prototype.removeChild assigning to it our own function
    obj[method] = (function (obj_method) {
    return function (child) {
    // This is the function that will be assigned to removeChild
    // It is wrapped in a closure to make the check before removing the element

    // Check if the element that is going to be removed is a post
    if (isPost(child)) return child;
    // If so, stop here by returning the post
    // This will make Tumblr believe the post has been removed

    // Otherwise continue and remove it
    return obj_method.apply(this, arguments);
    }
    }(obj[method]));

    }(Element.prototype, 'removeChild'));
    代码长度,不带注释:11行
    在页面中注入(inject)脚本
    由于该内容脚本在隐藏的不同window对象中工作,因此内容脚本代码无法与页面代码交互,因此您必须将代码直接从内容脚本插入页面中。为此,您需要创建一个<script>元素并将其插入页面的<head>中。您可以将要注入(inject)的代码存储在新脚本中(我们将其称为injectedCode.js),然后使用chrome.runtime.getURL获取要在<script> src中使用的绝对URL。
    重要:您需要将injectedCode.js文件添加到"web_accessible_resources"中的 manifest.json field中,以使其可从Tumblr访问,如下所示:
    "web_accessible_resources": ["/injectedCode.js"]
    然后,您可以创建一个<script>,将.src设置为您的injectedCode.js,如下所示:
    /* In your content script: */

    var s = document.createElement('script');
    s.src = chrome.extension.getURL("/injectedCode.js");
    document.head.appendChild(s);
    尾注
    这只是完成您要执行的操作的两种方法:防止Tumblr在滚动时隐藏帖子。显然,还有许多其他方法可以执行此操作,例如使用 MutationObserver 来检查子树的修改,删除所有帖子并使用新的个人事件和方法创建新的容器来模仿Tumblr的事件,插入Tumblr代码并直接对其进行编辑(几乎不可能,合法性不高),依此类推。
    我也想强调一个事实,那就是这只是对问题的解答,对于因错误使用此类操作而损害扩展程序用户的情况,我概不负责。

    关于javascript - 防止在Tumblr仪表板上删除DOM元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28338450/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com