3

I'm not really familiar with Javascript, and even less with how Javascript works in Chrome's F12 developer tools. What I'm trying to do is have a favorite which, when clicked on, loads a web page but removes some of the clutter of the page which is loaded (I don't really care if it removes it before the page is loaded, or loads it and then removes it)

For now, I'm trying to figure out how to remove all elements except the one I want to keep (and its' children), namely, one which has the following html:

<div>
   <ul class="c-list-news u-relative" data-load-more-content>...</ul>
</div>

I'm trying the following (from what I could find on SO), but I can't find the right selector (or I'm doing something else wrong, not quite sure):

var elem = document.querySelectorAll('body *:not(div ul.c-list-news, div ul.c-list-news *)');

for(var i=0;i<elem.length;i++) {
    elem[i].parentElement.removeChild(elem[i]); 
}

(PS : I haven't yet looked into how to put it into a favorite/extension, it will come later)

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
François M.
  • 4,027
  • 11
  • 30
  • 81

2 Answers2

4

It's probably easier than you realize. :-) You can get the first element matching .c-list-news like this:

const cListNews = document.querySelector(".c-list-news");

If you want to keep its parent, just add .parentNode to that:

const divContainer = document.querySelector(".c-list-news").parentNode;

Then, wipe out body entirely:

document.body.innerHTML = "";

...and put the element back:

document.body.appendChild(cListNews); // Or `divContainer`

I'm not sure I'd expect the page to continue to be readable, though, since of course this completely changes where the element is in the DOM, which may well make the CSS fail.

You can't make a bookmark (favorite) that both loads the page and does this in one go, because javascript: bookmarks work within the context of the current page. You could use something like TamperMonkey which is an extension that lets you run a script automatically when you go to matching URLs.

But you can make a bookmark that you use when you're already on the page: Just use the javascript: pseudo-protocol and follow it with JavaScript code. For instance:

javascript:var divContainer %3D document.querySelector(".c-list-news").parentNode%3Bdocument.body.innerHTML %3D ""%3Bdocument.body.appendChild(divContainer)%3Bconsole.log("done")%3B

I created that by simply removing line breaks from the code (optional), running the code through encodeURIComponent, and putting javascript: on the front. (Some folks would also convert spaces to %20.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • It actually works exactly like I want, thanks! I'll take a look at TamperMonkey, thanks. – François M. Sep 13 '19 at 15:25
  • @FrançoisM. Looks like you've deleted your second comment, but yes, once you're on the webpage already, you can use a bookmark for this. (This is usually called a "bookmarklet", a portmanteau of "bookmark" and "applet".) I've added one to the answer. :-) – T.J. Crowder Sep 13 '19 at 15:41
  • Thanks! Yes, I removed my comment because I tried it by adding `javascript:` in front of your 4 original lines of code and it worked well. What's the interest of `encodedURIComponent`? – François M. Sep 13 '19 at 15:51
  • 1
    @FrançoisM. - Technically what follows is supposed to be URI-encoded, so it would be possible for the code not to work without URI-encoding. With the code above it doesn't really matter. (BTW, you don't need all four, the first two are alternatives for each other.) – T.J. Crowder Sep 13 '19 at 16:00
0

Save the element to keep to a variable. Remove all nodes from the body, or the element that you want, and add the element to keep. Example:

let elementToKeep = document.getElementById('side');
const myNode = document.getElementsByTagName("body")[0];
while (myNode.firstChild) {
  myNode.removeChild(myNode.firstChild);
}
myNode.appendChild(elementToKeep);

Using the removeChild method is faster that setting the innerHtml as empty string. Check here: Remove all child elements of a DOM node in JavaScript

Diogo Peres
  • 1,302
  • 1
  • 11
  • 20