2012-03-12 126 views
0

我试图从querySelectorAll以外的网页中删除元素,但这似乎不适用于Opera Mobile 11.5。在我将它们放在手机上之前,我已经在PC上试过了这些脚本。querySelectorAll()在Opera Mobile 11.5中不起作用?

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"); 

回答

1

几个问题之前添加var

  1. Juan Mendes' answer是正确的删除命令。如果不反向删除,JS不但效率低下,而且由于数组值不再有效,脚本崩溃的真正机会。如果效率低下的方式似乎只运行一次或两次,那只是运气。

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

  3. 代码在Opera, User JavaScript之外似乎对您有用的事实表明您正在使用的节点已通过javascript/AJAX页面添加。用计时器或类似方法补偿。

  4. 如果仍然遇到困难,链接到目标页面后您正试图确切的CSS选择器。

  5. 请注意,querySelectorAll() is compatible with Opera Mobile 11.5,这两个页面要么这样说,要么显示一个问号 - 这并不意味着它不兼容,只是Mozilla没有测试它(其他人有)。请注意,有潜在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); 
+0

这真的是一个很好的答案,但是这个函数doesn也不行。我尝试用一​​个匿名函数来包装它,然后用window.opera.addEventListener再次用指定的AfterScript事件包装它,但仍然不销毁元素。其中一个网站是http://endlessvideo.com/,CSS选择器是'div [style =“float:left;”] div [style =“margin-left:5px;”] div [style =“float:右键;“],div#addthis_button,div#uvTab,a [href * =”vdownloader.com“],[href * =”youtubedownloader.com“]',可在桌面上完美工作Firefox – user1263513 2012-03-13 07:17:38

+0

您最后的代码评论是“搞砸了”。请编辑该问题以添加任何重要的代码。不要在这里使用'addEventListener'或'AfterScript',这就是计时器代码的用途。事实上,这个特定的代码可以在[Greasemonkey模式](http://www.opera.com/docs/userjs/examples/#greasemonkey)中正常运行。 ...最后,我不知道Opera Mobile是否支持多个选择器。首先尝试一下简单的东西,比如'deleteByCSS(“#addthis_button”,20);'。我没有看到任何iFrames,但是如果这些节点中的一些在一个中,请注意。 – 2012-03-13 07:35:27

+0

我已经尝试了在UserJS和Greasemonkey模式下的答案中提供的每个函数组合。我非常怀疑Opera Mobile真的支持querySelectorAll()。作为一种替代方法,您如何看待这个问题:http://v.gd/ovd9UR正如您在演示中看到的那样,它确实正在讨论这个功能 – user1263513 2012-03-13 07:58:19

0

根据caniuse(http://caniuse.com/#search=queryselector)应该通过Opera Mini的支持。

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

+0

我猜你想说移动而不是迷你。 我试图用Sizzle进行试验,然后才结束了我遇到的问题,但我无法弄清楚如何才能用Sizzle实现相同的结果。 github和zip包中的文档告诉我没有任何例子,我可以学习它的方式。 – user1263513 2012-03-12 23:31:51

1

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

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

顺便说的休息,不要忘记你的局部变量

+0

不是,这也行不通,我认为在这种情况下向后循环是没有意义的,因为elem数组只填充一次,所以我可以通过任何我想要的方式来完成它。 – user1263513 2012-03-12 23:35:14

+1

@ user1263513:elem是一个NodeList,这意味着它是活的。因此,从DOM中删除节点也将从列表中删除它们。如果你想迭代前进和删除元素,你必须增加你的循环索引 – 2012-03-12 23:44:27

+0

奇怪的是,我在我的PC上使用复杂的CSS3选择器在Firefox上试了一下,结果收集了10个以上的元素,并且所有这些元素都被删除了,没有发生任何错误 – user1263513 2012-03-12 23:54:32