NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @id better-indeed // @name Better Indeed // @version 1.1.1 // @namespace https://github.com/luigia // @author Luigi Agcaoili // @license MIT // @description Removes bloat on Indeed by giving users the option to remove sponsored and/or Job Spotter postings // @include https://indeed.com/jobs?* // @include *indeed.com/* // @updateURL https://github.com/luigia/better-indeed/raw/master/better-indeed.user.js // @run-at document-end // @grant none // ==/UserScript== // select & edit the side bar const filters = document.querySelector('#refineresults'), bar = document.createElement('div'); bar.innerHTML = ` <h4 class="toggle-title">Toggle ads</h4> <input type="checkbox" id="job-spotter-checkbox"> <label for="job-spotter-checkbox">Hide Job Spotter ads</label> <input type="checkbox" id="sponsored-checkbox"> <label for="sponsored-checkbox">Hide sponsored ads</label> `; // add consistent styling to div bar.style.marginBottom = '24px'; bar.style.marginLeft = '0'; bar.style.paddingLeft = '24px'; bar.style.color = '#2d2d2d'; bar.style.fontSize = '12px'; bar.style.maxWidth = '70%'; // add consistent styling to title bar.firstElementChild.style.fontSize = '14px'; bar.firstElementChild.style.fontWeight = '500'; bar.firstElementChild.style.color = '#000'; // insert the div before the first child filters.insertBefore(bar, filters.firstChild); // checkbox variables const jobSpotCb = document.querySelector('#job-spotter-checkbox'), sponsoredCb = document.querySelector('#sponsored-checkbox'); // addEventListeners & check localStorage window.onload = () => { jobSpotCb.addEventListener('change', hideJobSpot); sponsoredCb.addEventListener('change', hideSponsored); // call the function based on localStorage definitions let jobSpotLS = JSON.parse(localStorage.getItem(jobSpotCb.id)), sponsoredLS = JSON.parse(localStorage.getItem(sponsoredCb.id)); if (jobSpotLS) { jobSpotCb.checked = true; hideJobSpot(); } if (sponsoredLS) { sponsoredCb.checked = true; hideSponsored(); } // re-insert pagination to the side or job posting after the pagination is moved // check if there is only 1 page // there won't be a pagination if there is only 1 page if (document.querySelector('.pagination')) { const pagination = document.querySelector('.pagination'), results = document.querySelector('#resultsCol'); // add a delay as job postings aren't instantly loaded setTimeout(() => { let side = document.querySelector('#jobalerts') || document.querySelector('#vjs-header'); side.insertBefore(pagination, side.firstChild); }, 200); // move pagination when a result card is clicked results.addEventListener('click', (e) => { setTimeout(() => { // currently viewing a job listing if (document.querySelector('#vjs-header')) { let vjsHeader = document.querySelector('#vjs-header'); // add pagination as the last child in the job posting header vjsHeader.appendChild(pagination); } // add event listener to close button if (document.querySelector('#vjs-x')) { let close = document.querySelector('#vjs-x'); close.addEventListener('click', (e) => { // move pagination back to the side if it's removed if (document.querySelector('#jobalerts')) { side = document.querySelector('#jobalerts'); side.insertBefore(pagination, side.firstChild); } }); } }, 200); }) } } // functions // hide job spotter postings const hideJobSpot = (e) => { const linkSource = Array.from(document.querySelectorAll('.result-link-source')), jobSpot = []; // sources that include Job Spotter text are recorded linkSource.forEach((source) => (source.textContent == 'Job Spotter ') && jobSpot.push(source)); // set variable in localStorage & show/hide Job Spotter postings if (jobSpotCb.checked) { localStorage.setItem(jobSpotCb.id, jobSpotCb.checked); (jobSpot.length > 0) && jobSpot.forEach((posting) => posting.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.style.display = 'none'); } else { localStorage.removeItem(jobSpotCb.id); jobSpot.forEach((posting) => posting.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.style.display = 'block'); } } // hide sponsored postings const hideSponsored = (e) => { const lastSponsored = Array.from(document.querySelectorAll('.sjlast')); // set variable in localStorage & show/hide sponsored postings if (sponsoredCb.checked) { localStorage.setItem(sponsoredCb.id, sponsoredCb.checked); // use a loop only if there is more than one element for performance (lastSponsored.length === 1) ? lastSponsored[0].parentElement.style.display = 'none' : lastSponsored.forEach((section) => section.parentElement.style.display = 'none'); // sometimes there will be a sponsored posting that is separate from other sponsored listings if (document.querySelector('.sjita')) { const singleAd = document.querySelector('.sjita'); singleAd.style.display = 'none'; } } else { localStorage.removeItem(sponsoredCb.id); (lastSponsored.length === 1) ? lastSponsored[0].parentElement.style.display = 'block' : lastSponsored.forEach((section) => section.parentElement.style.display = 'block'); if (document.querySelector('.sjita')) { const singleAd = document.querySelector('.sjita'); singleAd.style.display = 'none'; } } } // keyboard navigation const keyboardNav = (e) => { // check if there is only 1 page // there won't be a pagination if there is only 1 page if (document.querySelector('.pagination')) { const activePage = document.querySelector('.pagination b'); switch (e.keyCode) { // left arrow key case 37: // this is not the first page (activePage.previousElementSibling !== null) && activePage.previousElementSibling.click(); break; // right arrow key case 39: // this is not the last page (activePage.nextElementSibling !== null) && activePage.nextElementSibling.click(); break; } } } document.onkeydown = keyboardNav;