【问题标题】:querySelectorAll() not working in Opera Mobile 11.5?querySelectorAll() 在 Opera Mobile 11.5 中不起作用?
【发布时间】:2012-03-12 22:56:37
【问题描述】:

我正在尝试使用 querySelectorAll 从网页中删除不必要的元素,但这似乎不适用于 Opera Mobile 11.5。在将脚本放到手机上之前,我已经在 PC 上试用了这些脚本。

Mozilla 的文档比较混乱,因为关于这个功能有两页,一页says it's compatible,另一页says it isn't

有解决办法吗?我需要在我制作的这些脚本中实现其他库吗?

我想这样做:

function deleteByCSS(el) {
 elem = document.body.querySelectorAll(el);
 for (i=0; i<elem.length; i++){
  elem[i].parentNode.removeChild(elem[i]);
 }
}
deleteByCSS("here goes every CSS selector pointing to objects I want to remove");

【问题讨论】:

    标签: javascript opera userscripts opera-mobile selectors-api


    【解决方案1】:

    几个问题:

    1. Juan Mendes' answer 关于删除顺序是正确的。如果不反向删除,不仅JS效率低下,而且由于数组值不再有效而导致脚本崩溃的真正机会。如果这种低效的方法似乎能奏效一两次,那只是运气。

    2. 另外,嵌套节点需要考虑在内,注意下面代码中的额外检查。

    3. 代码似乎在Opera, User JavaScript 之外为您工作,这表明您正在使用的节点是由页面 javascript/AJAX 添加的。使用计时器或类似方法进行补偿。

    4. 如果仍然遇到困难,链接到目标页面发布您正在尝试的确切 CSS 选择器

    5. 1234563请注意,document.querySelectorAll(){element}.querySelectorAll() 之间可能存在差异,因此是两个页面。

    把它们放在一起,这样的代码应该可以工作:

    function deleteByCSS (cssSelector, delayLoopMax, delayMilliSecs) {
        //-- Use defaults, if not specified.
        var delayLoopMax    = delayLoopMax   || 0;
        var delayMilliSecs  = delayMilliSecs || 300;
        //console.log ("Args: ", cssSelector, delayLoopMax, delayMilliSecs);
    
        var doomedElements  = document.body.querySelectorAll (cssSelector);
        if (doomedElements  &&  doomedElements.length) {
            //console.log ("Found!");
            //-- Found the node(s); delete it/them.
            for (var J = doomedElements.length - 1;  J >= 0;  --J) {
                var doomedNode  = doomedElements[J];
                if (doomedNode) {
                    doomedNode.parentNode.removeChild (doomedNode);
                }
            }
        }
        else {
            //-- Nodes not found. Wait for JS to add them, if specified.
            if (delayLoopMax > 0) {
                delayLoopMax--;
                setTimeout (
                    deleteByCSS,
                    delayMilliSecs,
                    cssSelector, delayLoopMax, delayMilliSecs
                );
            }
        }
    }
    


    在这种情况下,将其与 20 的初始额外参数一起使用...

    deleteByCSS ("*VALID* CSS selector", 20);
    

    【讨论】:

    • 这确实是一个很好的答案,但是这个功能也不起作用。我尝试用匿名函数包装它和调用,然后用指定了 AfterScript 事件的 window.opera.addEventListener 再次包装它,但仍然不会破坏元素。其中一个网站是endlessvideo.com,CSS 选择器是 'div[style="float: left;"] div[style="margin-left: 5px;"] div[style="float: right;"], div#addthis_button,div#uvTab,a[href*="vdownloader.com"],a[href*="youtubedownloader.com"]',在桌面 Firefox 上完美运行
    • 您上一条评论中的代码“搞砸了”。请编辑问题以添加任何重要的代码。不要在这里使用addEventListenerAfterScript,这就是计时器代码的用途。事实上,这个特定的代码可以在Greasemonkey mode 中正常运行。 ... 最后,我不知道 Opera Mobile 是否像这样一次性支持多个选择器。先尝试一些简单的东西,比如deleteByCSS ("#addthis_button", 20);。我没有看到任何 iFrame,但如果其中一些节点合二为一,请注意。
    • 我现在已经尝试了 UserJS 和 Greasemonkey 模式下答案中提供的功能的每种组合。我现在非常怀疑 Opera Mobile 是否真的支持 querySelectorAll()。作为替代方案,您对此有何看法:v.gd/ovd9UR 正如您在演示中看到的那样,它的功能与所讨论的功能完全相同
    • 如果它有效,那就去吧。很确定querySelectorAll() 可以工作;当我感到活泼时,将启动模拟器并仔细检查。 ... 先试试这个:document.body.querySelectorAll 替换为 document.querySelectorAll 并尝试一个简单的选择器开始。
    • 好的,到目前为止我唯一没有尝试过的是我在 Greasemonkey 模式下的原始 sn-p,它确实有效。但是,当它运行时,很多我想避免下载的东西已经下载了。似乎它是 Opera Mobile 的限制。我什至用 BeforeScript 和 AfterScript 将它包裹在 window.opera.AddEventListener 周围,但 var elem 仅在 Greasemonkey 模式下被填充。只是想知道,如果我注入一个 css 以使用 UserJS 为它们设置显示为无,这些内容会被加载吗?
    【解决方案2】:

    问题很可能是您在迭代它们时从列表中删除了元素。一个安全的选择是向后循环,这样,删除节点不会影响列表的其余部分

    function deleteByCSS(el) {
      var elem = document.body.querySelectorAll(el);
      for (var i=elem.length - 1; i>=0; i--){
        elem[i].parentNode.removeChild(elem[i]);
      }
    }
    

    对了,别忘了在你的局部变量前加上var

    【讨论】:

    • 不,这也不起作用,我认为在这种情况下向后循环是没有意义的,因为 elem 数组只填充一次,所以我可以以任何我希望的方式完成它。
    • @user1263513:elem 是一个 NodeList,这意味着它是实时的。因此,从 DOM 中删除节点也会将它们从列表中删除。如果您希望向前迭代和删除元素,则必须增加循环索引
    • 奇怪,我用复杂的 CSS3 选择器在我的 PC 上的 Firefox 上进行了尝试,结果收集了 10 多个元素,并且所有元素都被删除而没有出现任何错误
    • @JuanMendes NodeList by querySelectorAll 不是实时的,它是静态的。
    • @KernelJames 谢谢,我不知道 NodeList 不存在,但这是真的developer.mozilla.org/En/DOM/Element.querySelectorAll
    【解决方案3】:

    根据caniuse (http://caniuse.com/#search=queryselector) 应该是opera mini 支持的。

    无论如何,如果你想避免这种问题,甚至只是嘶嘶作响,请使用 Zepto 或 jQuery 进行 css dom 选择。 querySelectorAll 和 querySelector 显然并非所有浏览器(桌面或移动设备)都支持。在我看来,Mozilla 的 DOM api 的参考不是很好,也不是最新的。开发者确实需要一个真正完整而深入的 DOM api 文档。

    【讨论】:

    • 我猜你想说的是移动而不是迷你。在我遇到问题的功能之前,我曾尝试使用 Sizzle 进行试验,但我就是不知道如何使用 Sizzle 获得相同的结果。 github 和 zip 包中的文档没有显示我可以学习的示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-15
    • 2011-12-07
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多