您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Display news on Google's homepage
// ==UserScript== // @name Google News Display // @description Display news on Google's homepage // @version 1.2 // @match https://www.google.com/ // @match https://www.google.com/webhp* // @grant GM_xmlhttpRequest // @grant GM_addStyle // @author Gen1x/G1nX // @namespace https://gf.qytechs.cn/users/916589 // ==/UserScript== (function () { const userLanguage = (navigator.language || navigator.userLanguage).substr(0, 2).toLowerCase(); const translations = { en: { loading: 'Loading news...', error: 'Error fetching news.', headline: 'News in', originalPlaces: "It's recommended you check these\nin their original places.", }, es: { loading: 'Cargando noticias...', error: 'Error al obtener noticias.', headline: 'Noticias en', originalPlaces: "Se recomienda que verifiques estas\nnoticias en sus lugares originales.", }, fr: { loading: 'Chargement des actualités...', error: 'Erreur lors de la récupération des actualités.', headline: 'Actualités en', originalPlaces: "Il est recommandé de vérifier ces actualités\nà leurs emplacements d'origine.", }, de: { loading: 'Nachrichten werden geladen...', error: 'Fehler beim Abrufen der Nachrichten.', headline: 'Nachrichten in', originalPlaces: "Es wird empfohlen, diese Nachrichten\nan ihren Originalstellen zu überprüfen.", }, zh: { loading: '新闻加载中...', error: '获取新闻时出错。', headline: '新闻在', originalPlaces: "建议您在原始位置检查这些新闻。", }, ru: { loading: 'Загрузка новостей...', error: 'Ошибка при получении новостей.', headline: 'Новости на', originalPlaces: "Рекомендуется проверить эти новости\nв их оригинальных местах.", }, ja: { loading: 'ニュースを読み込んでいます...', error: 'ニュースの取得中にエラーが発生しました。', headline: 'のニュース', originalPlaces: "これらは元の場所で確認することをお勧めします。", } }; // Function to get the translation based on the user's language function getTranslation(key, language) { return translations[language] && translations[language][key] ? translations[language][key] : translations['en'][key]; } // Fetch user's country code using ipapi.co async function getUserCountryCode() { try { const response = await fetch('https://ipapi.co/json'); if (response.ok) { const data = await response.json(); return data.country_code.toLowerCase(); } else { console.error('Error fetching user country code:', response.statusText); // Return a default country code in case of an error return 'us'; } } catch (error) { console.error('Error fetching user country code:', error); // Return a default country code in case of an error return 'us'; } } // Get the user's country code getUserCountryCode().then((userCountryCode) => { // Fetch news data based on the user's country code const apiUrl = `https://personal-toolkit.genarunchisacoa.repl.co/news/alt?country=${userCountryCode}`; // Display loading text displayLoadingText(); GM_xmlhttpRequest({ method: 'GET', url: apiUrl, headers: { 'User-Agent': 'Mozilla/5.0 (compatible; Greasemonkey; UserScript)', Accept: 'application/json', }, onload: function (response) { if (response.status === 200) { const newsData = JSON.parse(response.responseText); // Display news once loaded displayNews(newsData, userCountryCode); } else { console.error('Error fetching news:', response.statusText); // Display error message displayErrorText('Error fetching news.'); } }, onerror: function (error) { console.error('Error fetching news:', error); // Display error message displayErrorText('Error fetching news.'); }, }); }); function displayLoadingText() { const newsContainer = document.createElement('div'); newsContainer.classList.add('news-container'); const loadingText = document.createElement('div'); loadingText.textContent = getTranslation('loading', userLanguage); loadingText.classList.add('loading-text'); newsContainer.appendChild(loadingText); // Find the specified div on the Google homepage const targetDiv = document.querySelector('.FPdoLc.lJ9FBc'); if (targetDiv) { // Insert the news container at the end targetDiv.appendChild(newsContainer); } else { console.error('Target div not found.'); } } // Function to display error text within the news container function displayErrorText(errorMessage) { const newsContainer = document.querySelector('.news-container'); if (newsContainer) { const errorText = document.createElement('div'); errorText.textContent = errorMessage || getTranslation('error', userLanguage); errorText.classList.add('error-text'); newsContainer.innerHTML = ''; // Clear loading text newsContainer.appendChild(errorText); } else { console.error('News container not found.'); } } // Function to get the country name from the country code using Navigator API function getCountryNameFromCode(countryCode) { try { const countryName = new Intl.DisplayNames([userLanguage], { type: 'region' }).of(countryCode.toUpperCase()); return countryName; } catch (error) { console.error('Error getting country name:', error); // Return the country code if an error occurs return countryCode; } } // Function to display news titles with links in grid items and insert them at the end of the specified div function displayNews(newsData, userCountryCode) { const newsContainer = document.querySelector('.news-container'); if (newsContainer) { // Clear loading text newsContainer.innerHTML = ''; // Add heading for the news based on the user's country const userCountryHeading = document.createElement('h3'); userCountryHeading.textContent = `${getTranslation("headline", userLanguage)} ${getCountryNameFromCode(userCountryCode)}\n`; userCountryHeading.style.color = 'white'; userCountryHeading.classList.add('news-header'); newsContainer.appendChild(userCountryHeading); // Add the text recommending checking news in their original places const originalPlacesText = document.createElement('div'); originalPlacesText.textContent = getTranslation('originalPlaces', userLanguage); originalPlacesText.classList.add('original-places-text'); newsContainer.appendChild(originalPlacesText); // Iterate through each news item and create a grid item for the title with a link newsData.results.forEach((item) => { const newsItem = document.createElement('a'); newsItem.classList.add('grid-item'); newsItem.href = item.link; newsItem.target = '_blank'; // Open link in a new tab // Check if the video URL is not null if (item.video_url) { const newsVideo = document.createElement('video'); newsVideo.src = item.video_url; newsVideo.autoplay = true; newsVideo.loop = true; newsVideo.muted = true; newsVideo.classList.add('headline-video'); newsItem.appendChild(newsVideo); } else if (item.image_url) { // If video_url is null, check for image_url const newsImage = document.createElement('img'); newsImage.src = item.image_url; newsImage.alt = item.title; newsImage.classList.add('headline-image'); newsItem.appendChild(newsImage); } const newsTitle = document.createElement('div'); newsTitle.textContent = item.title; newsTitle.classList.add('title-text'); const newsDescription = document.createElement('div'); newsDescription.classList.add('description-text'); newsDescription.style.display = 'none'; // Hide description by default // Extract the first paragraph of the description and cut off at 200 characters const firstParagraph = item.content.split('\n\n')[0].substring(0, 200); // Add three dots if the description was truncated newsDescription.textContent = firstParagraph.length < item.content.length ? `${firstParagraph}...` : firstParagraph; // You might want to add additional styling or processing for each news title newsItem.appendChild(newsTitle); newsItem.appendChild(newsDescription); // Add event listener for hover newsItem.addEventListener('mouseenter', () => { // Display description on hover newsTitle.style.display = 'none'; newsDescription.style.display = 'block'; }); newsItem.addEventListener('mouseleave', () => { // Hide description on leave newsTitle.style.display = 'block'; newsDescription.style.display = 'none'; }); newsContainer.appendChild(newsItem); }); } else { console.error('News container not found.'); } } // Add styles for grid items, news container, loading text, and error text GM_addStyle(` .news-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; max-height: 240%; overflow-y: auto; margin: 20px auto; /* Update this line to center-align the container */ text-align: center; border: 1px solid #ddd; padding: 20px auto; background-color: #2d2c38; border-radius: 10px; } .grid-item { border: 1px solid #ddd; padding: 10px; text-align: center; display: flex; flex-direction: column; /* Display items in a column */ align-items: center; /* Center the text vertically */ justify-content: center; /* Center the text horizontally */ text-decoration: none; /* Remove default link underline */ color: #5489de; /* Set link color */ background-color: #2d2c38; border-radius: 5px; /* Adjust the value to change the level of rounding */ margin: 10px; /* Add margin to the grid items */ } .grid-item:hover { background-color: #494857; /* Add a subtle background color on hover */ transition: background-color 0.3s ease; /* Smooth transition for background color */ } .loading-text, .error-text { font-size: 18px; font-weight: bold; color: white; } .error-text { color: red; } .original-places-text { font-size: 14px; color: #ddd; margin-top: 10px; } /* Add rounded corners to the scrollbar */ .news-container::-webkit-scrollbar { width: 12px; padding: 10px; } .news-container::-webkit-scrollbar-thumb { background-color: #6b6a7d; /* Color of the scrollbar thumb */ border-radius: 6px; /* Rounded corners for the thumb */ } .news-container::-webkit-scrollbar-track { background-color: #2d2c38; /* Color of the scrollbar track */ border-radius: 8px; /* Rounded corners for the track */ } .news-header { text-align: center; display: flex; align-items: center; /* Center the text vertically */ justify-content: center; /* Center the text horizontally */ } .headline-image, .headline-video { max-width: 100%; max-height: 100%; border-radius: 5px; margin-bottom: 10px; /* Adjust margin as needed */ } `); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址