Verwijderen van AngularJS elements uit de DOM

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Mr Alfabet
  • Registratie: Juli 2005
  • Laatst online: 01-08 03:07
Als hobby maak ik wel eens chrome extensies om kleine dingen op websites te wijzigen. Normaal gaat dat prima, maar nu loop ik tegen een probleem aan.

Het probleem:
Op de website lolesports.com kun je tournament games bekijken van de game League of Legends. Als je doorklikt naar schedule, en dan de oudere matches bekijkt (http://euw.lolesports.com/schedule/2015-08-17) staan er meteen spoilers bij (de score, die wil je natuurlijk niet zien voor je de match gezien hebt).

Voorheen was er een 'hide spoilers' knop te vinden op de pagina, maar die is om een of andere reden verwijderd. Als ik de elements inspect van de scores, dan blijkt dat het span elements zijn met een ng-if tag en de classes ng-scope en vs-text. In de ng-if tag staat ook de voorwaarde !hideSpoilers, ik denk dus dat alleen de knop is weggehaald van de pagina, maar niet de functionaliteit. Ik kan de declaratie van die variabele echter nergens vinden.

Oplossingen:
Ik heb 2 mogelijke oplossingen kunnen vinden:
  1. De (AngularJS?) variabele wijzigen. Ik weet niet of de paginacontent nog wijzigt als de variabele gewijzigd wordt nadat de pagina geladen is. Het zou in dat geval moeten gebeuren voordat de DOM geladen wordt denk ik.
  2. De elementen verwijderen nadat de pagina geladen is. Hiermee heb ik enig succes kunnen boeken, maar om 1 of andere reden moet ik meerdere malen achter elkaar alle elementen zoeken en verwijderen, omdat er steeds maar de helft verwijderd wordt (waarom weet ik ook niet).
Zou iemand me in de goede richting kunnen duwen hoe ik dit het beste aan kan pakken? Mijn Google-Fu laat me in de steek.

Huidig script:
code:
1
2
3
4
5
6
7
8
for (var j = 0; j<5; j++) {
    var matches = document.getElementsByClassName('ng-scope vs-text');
    console.log("Matches found: " + matches.length);
    console.log(matches);
    for (var i = 0; i<matches.length; i++) {
        matches[i].parentNode.removeChild(matches[i]);
    }
}


De console output is dan dit:
code:
1
2
3
4
5
6
7
8
9
10
Matches found: 8
[span.vs-text.ng-scope, span.vs-text.ng-scope, span.vs-text.ng-scope, span.vs-text.ng-scope, span.vs-text.ng-scope, span.vs-text.ng-scope, span.vs-text.ng-scope, span.vs-text.ng-scope]
Matches found: 4
[span.vs-text.ng-scope, span.vs-text.ng-scope, span.vs-text.ng-scope, span.vs-text.ng-scope]
Matches found: 2
[span.vs-text.ng-scope, span.vs-text.ng-scope]
Matches found: 1
[span.vs-text.ng-scope]
Matches found: 0
[]


Daar komt nog bij dat het navigeren tussen game weeks de functie niet opnieuw triggert, al zou ik daar zelf wel achter kunnen komen hoe dat moet. Ik zou liever iets hebben wat niet zo 'hacky' voelt.

[ Voor 178% gewijzigd door Mr Alfabet op 26-08-2015 17:01 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:19

crisp

Devver

Pixelated

getElementsByClassName geeft een 'live nodeList' terug; kortom: het resultaat wordt dynamisch aangepast zodra je elementen verwijderd. Als je daar met een dergelijke for-loop doorheen loopt skip je daardoor continue elementen. Dat kan je op een aantal manieren voorkomen:

1) van achteraf doorheen loopen:
JavaScript:
1
2
3
4
5
var matches = document.getElementsByClassName('ng-scope vs-text'), i = matches.length;
while (i--)
{
       matches[i].parentNode.removeChild(matches[i]);
}


2) elke keer het eerste element weghalen totdat matches leeg is:
JavaScript:
1
2
3
4
5
var matches = document.getElementsByClassName('ng-scope vs-text'), match;
while ((match = matches[0]))
{
       match.parentNode.removeChild(match);
}


3) eerst converteren naar een statische array, hier met wat voodoo:
JavaScript:
1
2
3
4
5
var matches = Array.prototype.slice.call(document.getElementsByClassName('ng-scope vs-text'));
for (var i = 0; i < matches.length; i++)
{
       matches[i].parentNode.removeChild(matches[i]);
}

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Casturan
  • Registratie: Oktober 2009
  • Laatst online: 01-09 21:17
Je zou het ook kunnen oplossen door wat CSS te injecteren in de pagina.

JavaScript:
1
2
3
var hidespoilers = document.createElement('style');
hidespoilers.innerHTML = "span.ng-scope.vs-text{display:none;}";
document.body.appendChild(hidespoilers);


Wanneer je het weer wilt tonen, dan moet je de geinjecteerde style weer aanpassen. ;)

Acties:
  • 0 Henk 'm!

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 07-10 10:46
Als je op de een of andere manier de ng-if kan wijzigen van "!hideSpoilers" naar "false" dan ben je er ook denk ik.

En verder https://docs.angularjs.org/guide/scope

Acties:
  • 0 Henk 'm!

  • Casturan
  • Registratie: Oktober 2009
  • Laatst online: 01-09 21:17
epic007 schreef op vrijdag 28 augustus 2015 @ 15:15:
Als je op de een of andere manier de ng-if kan wijzigen van "!hideSpoilers" naar "false" dan ben je er ook denk ik.

En verder https://docs.angularjs.org/guide/scope
Dat had ik ook heel even geprobeerd, maar kon niet zo snel vinden in welke controller/directive de variable zit.

Acties:
  • 0 Henk 'm!

  • Tsjilp
  • Registratie: November 2002
  • Niet online

Tsjilp

RS[I]ds

Zo te zien is de `hideSpoilers` ook uit de sourcecode gehaald en staat hij alleen maar in de HTML.
In dat geval maakt angular de variabele op de huidige scope aan met waarde `undefined`. Het makkelijkste is met css alles met `.vs-text` te hiden

Raar... Is zo gek nog niet

Pagina: 1