Löscht datumslose Anzeigen. Filtert Profis. Button im großen PRO-Badge Design A & D Navigation
目前為
// ==UserScript==
// @name Kleinanzeigen_01_Navigation Upgrade
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Löscht datumslose Anzeigen. Filtert Profis. Button im großen PRO-Badge Design A & D Navigation
// @author moritz & Gemini
// @icon https://www.google.com/s2/favicons?sz=64&domain=kleinanzeigen.de
// @match https://www.kleinanzeigen.de/*
// @run-at document-start
// @license MIT
// @grant none
// ==/UserScript==
(function() {
'use strict';
// =================================================================
// TEIL 0: Gedächtnis
// =================================================================
const storageKey = 'ka_show_pros_state';
const savedState = localStorage.getItem(storageKey) === 'true';
if (savedState) {
(document.body || document.documentElement).classList.add('ka-show-pro');
}
// =================================================================
// TEIL 1: CSS
// =================================================================
const cssStyles = `
/* 1. Globale Banner & Platzhalter weg */
.j-liberty-wrapper, #brws_banner-supersize, #btf-billboard,
#viewad-sidebar-banner, .site-base--left-banner, .site-base--right-banner {
display: none !important;
}
/* 2. PRO-Anzeigen ausblenden (Standard) */
li.ad-listitem.ka-pro-hidden {
display: none !important;
}
/* 3. Ghost-Mode (Wenn Button geklickt) */
/* Äußerer Container (LI): Sichtbar, kein Rahmen */
body.ka-show-pro li.ad-listitem.ka-pro-hidden {
display: list-item !important;
border: none !important;
margin-bottom: 10px !important;
padding: 0 !important;
}
/* Innerer Artikel: Roter Rahmen, leicht transparent */
body.ka-show-pro li.ad-listitem.ka-pro-hidden article.aditem {
opacity: 0.8 !important;
background-color: #fffafb !important;
border: 1px solid #b30c0c !important; /* Dein Rot */
box-shadow: none !important;
}
/* Dashboard Container */
#ka-dashboard-container {
margin: 0 0 15px 0;
background: #fff;
border: 1px solid #d5d5d5;
padding: 12px 20px;
display: flex;
align-items: center;
justify-content: space-between;
font-family: "Martel Sans", sans-serif;
border-radius: 4px;
}
#ka-dashboard-text { font-size: 14px; color: #333; font-weight: bold; }
/* DER BUTTON - Großer PRO-Badge Style
Farbe: #7b5cbf
Radius: 5px (Proportional größer als das Original)
*/
#ka-dashboard-btn {
background-color: #7b5cbf !important; /* Dein Lila */
color: #ffffff !important;
border: none;
/* Größe anpassen */
height: 36px;
padding: 0 20px;
font-size: 14px;
font-weight: bold;
/* Radius leicht abgerundet, nicht eckig, nicht Pille */
border-radius: 5px !important;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
min-width: 160px;
transition: background-color 0.2s;
}
#ka-dashboard-btn:hover {
background-color: #644aa3 !important; /* Etwas dunkler beim Hover */
}
/* Beide Zustände haben jetzt die GLEICHE Farbe.
Keine Farbänderung mehr bei .filter-active
*/
`;
const styleElement = document.createElement('style');
styleElement.type = 'text/css';
styleElement.appendChild(document.createTextNode(cssStyles));
(document.head || document.documentElement).appendChild(styleElement);
// =================================================================
// TEIL 2: Logik
// =================================================================
let validAdsCount = 0;
let proAdsCount = 0;
function cleanUp() {
const listItems = document.querySelectorAll('li.ad-listitem');
let currentValid = 0;
let currentPro = 0;
listItems.forEach(li => {
// Platzhalter weg
if (li.querySelector('div[id^="srpb-result-list"]') || li.querySelector('.liberty-hide-unfilled')) {
li.remove();
return;
}
const ad = li.querySelector('article.aditem');
if (!ad) return;
// HARD DELETE (Kein Datum oder TOP)
const dateBox = ad.querySelector('.aditem-main--top--right');
const hasDate = dateBox && dateBox.innerText.trim().length > 0;
const isTopBadge = ad.querySelector('.aditem-image--badges--badge-topad') !== null;
const isTopClass = ad.classList.contains('is-topad');
if (!hasDate || isTopBadge || isTopClass) {
li.remove();
return;
}
// SOFT FILTER (Profis)
const isProBadge = ad.querySelector('.badge-hint-pro-small-srp') !== null;
const isProLink = ad.querySelector('a[href^="/pro/"]') !== null;
if (isProBadge || isProLink) {
li.classList.add('ka-pro-hidden');
currentPro++;
} else {
li.classList.remove('ka-pro-hidden');
}
currentValid++;
});
if (currentValid !== validAdsCount || currentPro !== proAdsCount) {
validAdsCount = currentValid;
proAdsCount = currentPro;
updateDashboard();
}
}
// =================================================================
// TEIL 3: Dashboard
// =================================================================
function initDashboard() {
const targetHeader = document.querySelector('.srp-header');
if (!targetHeader) return;
if (!document.getElementById('ka-dashboard-container')) {
const dashboard = document.createElement('div');
dashboard.id = 'ka-dashboard-container';
dashboard.innerHTML = `
<span id="ka-dashboard-text">...</span>
<button id="ka-dashboard-btn">Filter umschalten</button>
`;
targetHeader.parentNode.insertBefore(dashboard, targetHeader.nextSibling);
document.getElementById('ka-dashboard-btn').addEventListener('click', () => {
const isActive = document.body.classList.toggle('ka-show-pro');
localStorage.setItem(storageKey, isActive);
updateDashboard();
});
}
updateDashboard();
}
function updateDashboard() {
const textSpan = document.getElementById('ka-dashboard-text');
const btn = document.getElementById('ka-dashboard-btn');
if (!textSpan) return;
const isShowingPro = document.body.classList.contains('ka-show-pro');
if (isShowingPro) {
textSpan.textContent = `${validAdsCount} Anzeigen davon ${proAdsCount} Profi`;
btn.textContent = "Profis ausblenden";
} else {
if (proAdsCount > 0) {
textSpan.textContent = `${validAdsCount} Anzeigen davon ${proAdsCount} ausgeblendet`;
btn.textContent = "Profis anzeigen";
btn.style.display = 'flex';
} else {
textSpan.textContent = `${validAdsCount} Anzeigen (Keine Profis)`;
btn.style.display = 'none';
}
}
}
window.addEventListener('DOMContentLoaded', () => {
const observer = new MutationObserver(() => {
requestAnimationFrame(() => {
cleanUp();
initDashboard();
});
});
observer.observe(document.body, { childList: true, subtree: true });
});
// =================================================================
// TEIL 4: Navigation (A/D)
// =================================================================
document.addEventListener('keydown', function(e) {
if (['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) return;
if (e.key === 'ArrowLeft' || e.key === 'a') clickNav('.pagination-prev');
else if (e.key === 'ArrowRight' || e.key === 'd') clickNav('.pagination-next');
});
function clickNav(selector) {
const el = document.querySelector(selector);
if (el) {
if (el.href) el.click();
else if (el.getAttribute('data-url')) window.location.href = el.getAttribute('data-url');
}
}
if (window.location.href === 'https://www.kleinanzeigen.de/') {
const int = setInterval(() => {
const btn = document.querySelector('.button-secondary.j-feed-show-more');
if (btn) btn.click();
}, 1000);
setTimeout(() => clearInterval(int), 5000);
}
})();