Instantly share code, notes, and snippets.
Created
February 2, 2025 18:29
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save xpl/3472d5af04e6698f8fbb764047f46f59 to your computer and use it in GitHub Desktop.
Userscript adding a quick Hide button to Zillow thumbnails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Zillow Hide Home Button | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description Adds a hide button to each property thumbnail next to the "save" button on Zillow search pages. | |
// @author Your Name | |
// @match https://www.zillow.com/* | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
/** | |
* Adds a "Hide" button to the given save area element. | |
* @param {Element} saveArea - The DOM element containing the save button. | |
*/ | |
function addHideButton(saveArea) { | |
// Prevent adding duplicate buttons. | |
if (saveArea.querySelector('.zillow-hide-button')) return; | |
// Create the hide button. | |
const hideBtn = document.createElement('button'); | |
hideBtn.textContent = 'Hide'; | |
hideBtn.className = 'zillow-hide-button'; | |
// Optional inline styling – adjust as needed. | |
hideBtn.style.marginTop = '8px'; | |
hideBtn.style.marginRight = '20px'; | |
hideBtn.style.padding = '2px 6px'; | |
hideBtn.style.fontSize = '12px'; | |
hideBtn.style.cursor = 'pointer'; | |
hideBtn.style.opacity = 0.33; | |
hideBtn.addEventListener('click', async function(event) { | |
event.stopPropagation(); | |
event.preventDefault(); | |
// Find the property card. In Zillow’s markup, the property card is an <article> | |
// with an id like "zpid_441734523" or a data-test attribute. | |
const propertyCard = saveArea.closest('article[data-test="property-card"]'); | |
if (!propertyCard) { | |
console.error('Could not locate the property card.'); | |
return; | |
} | |
// Extract the property ID from the card’s id attribute. | |
let propertyId = propertyCard.id; // expected to be like "zpid_441734523" | |
if (propertyId && propertyId.indexOf('zpid_') === 0) { | |
propertyId = propertyId.replace('zpid_', ''); | |
} else { | |
console.error('Property ID not found or unexpected format:', propertyCard.id); | |
return; | |
} | |
if (!confirm("Sure?")) return; | |
// Give feedback to the user. | |
hideBtn.disabled = true; | |
hideBtn.textContent = 'Hiding...'; | |
try { | |
// Send the hide request. | |
const response = await fetch("https://www.zillow.com/zg-graph?operationName=hideHome", { | |
method: "POST", | |
mode: "cors", | |
credentials: "include", | |
headers: { | |
"content-type": "application/json", | |
}, | |
body: JSON.stringify({ | |
operationName: "hideHome", | |
variables: { propertyId: propertyId, propertyIdType: "zpid" }, | |
query: "mutation hideHome($propertyId: ID!, $propertyIdType: PropertyIdType!) {\n hideHome(\n hiddenHomeInput: {propertyId: $propertyId, propertyIdType: $propertyIdType}\n )\n}\n" | |
}) | |
}); | |
const result = await response.json(); | |
console.log('hideHome response:', result); | |
// Optionally remove the card from view. | |
propertyCard.style.display = 'none'; | |
} catch (error) { | |
console.error('Error hiding home:', error); | |
hideBtn.textContent = 'Error'; | |
} | |
}); | |
// Append the hide button to the save area. | |
saveArea.appendChild(hideBtn); | |
} | |
/** | |
* Processes all property cards currently in the DOM. | |
*/ | |
function processPropertyCards() { | |
// Zillow uses dynamic class names but the save area always contains "StyledPropertyCardSaveArea". | |
const saveAreas = document.querySelectorAll('[class*="StyledPropertyCardSaveArea"]'); | |
saveAreas.forEach(saveArea => addHideButton(saveArea)); | |
} | |
// Run on initial page load. | |
processPropertyCards(); | |
// Observe DOM changes to add hide buttons to newly loaded cards. | |
const observer = new MutationObserver(mutations => { | |
mutations.forEach(mutation => { | |
mutation.addedNodes.forEach(node => { | |
if (node.nodeType === Node.ELEMENT_NODE) { | |
// Look for any save areas within newly added nodes. | |
const newSaveAreas = node.querySelectorAll('[class*="StyledPropertyCardSaveArea"]'); | |
newSaveAreas.forEach(saveArea => addHideButton(saveArea)); | |
} | |
}); | |
}); | |
}); | |
observer.observe(document.body, { childList: true, subtree: true }); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment