您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
便捷返回顶部/跨引擎一键搜
当前为
- // ==UserScript==
- // @name DuckDuckGo Optimization
- // @name:zh-CN DuckDuckGo优化
- // @name:zh-TW DuckDuckGo優化
- // @description Double Click To Return The Top / Shortcuts To Other Search Engines
- // @description:zh-CN 便捷返回顶部/跨引擎一键搜
- // @description:zh-TW 便捷返回頂部/跨引擎一鍵搜
- // @version 1.1.1
- // @icon https://raw.githubusercontent.com/MiPoNianYou/UserScripts/refs/heads/main/Icons/DuckDuckGoOptimizationIcon.svg
- // @author 念柚
- // @namespace https://github.com/MiPoNianYou/UserScripts
- // @supportURL https://github.com/MiPoNianYou/UserScripts/issues
- // @license GPL-3.0
- // @match https://duckduckgo.com/*
- // @grant GM_addStyle
- // ==/UserScript==
- (function () {
- "use strict";
- const RightAreaRatio = 0.2;
- const InteractiveElementsSelector =
- 'a, button, input, select, textarea, [role="button"], [tabindex]:not([tabindex="-1"])';
- const SearchFormSelector = "#search_form";
- const SearchInputSelector = "#search_form_input";
- const SearchBtnGroupClass = "SearchBtnGroup";
- const SearchBtnClass = "SearchBtn";
- const DebounceDelay = 250;
- document.addEventListener(
- "dblclick",
- function (Event) {
- const WindowWidth = window.innerWidth;
- const TriggerBoundary = WindowWidth * (1 - RightAreaRatio);
- if (
- Event.clientX > TriggerBoundary &&
- !Event.target.closest(InteractiveElementsSelector)
- ) {
- window.scrollTo({
- top: 0,
- behavior: "smooth",
- });
- }
- },
- { passive: true }
- );
- const SearchButtonStyle = `
- .${SearchBtnGroupClass} {
- display: flex;
- flex-wrap: wrap;
- gap: 10px;
- margin: 12px auto;
- padding: 0 10px;
- max-width: 800px;
- justify-content: center;
- }
- .${SearchBtnClass} {
- padding: 8px 16px;
- border-radius: 8px;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
- font-size: 14px;
- font-weight: 500;
- cursor: pointer;
- transition: background-color 0.2s ease, border-color 0.2s ease;
- min-width: 110px;
- text-align: center;
- flex-grow: 1;
- flex-basis: 110px;
- box-sizing: border-box;
- border: 1px solid transparent;
- background-color: rgba(60, 60, 60, 0.8);
- color: #f5f5f7;
- border-color: rgba(85, 85, 85, 0.9);
- }
- .${SearchBtnClass}:hover {
- background-color: rgba(75, 75, 75, 0.9);
- border-color: rgba(100, 100, 100, 0.9);
- }
- `;
- GM_addStyle(SearchButtonStyle);
- const EngineList = [
- { Name: "Google", Url: "https://www.google.com/search?q=" },
- { Name: "Bing", Url: "https://www.bing.com/search?q=" },
- { Name: "Baidu", Url: "https://www.baidu.com/s?wd=" },
- ];
- function Debounce(Func, Wait) {
- let Timeout;
- return function ExecutedFunction(...Args) {
- const Later = () => {
- clearTimeout(Timeout);
- Func(...Args);
- };
- clearTimeout(Timeout);
- Timeout = setTimeout(Later, Wait);
- };
- }
- function CreateSearchButtons() {
- const SearchForm = document.querySelector(SearchFormSelector);
- const SearchInput = SearchForm?.querySelector(SearchInputSelector);
- if (
- !SearchForm ||
- !SearchInput ||
- document.querySelector(`.${SearchBtnGroupClass}`)
- ) {
- return;
- }
- const BtnGroup = document.createElement("div");
- BtnGroup.className = SearchBtnGroupClass;
- EngineList.forEach((Engine) => {
- const Button = document.createElement("button");
- Button.className = SearchBtnClass;
- Button.textContent = `使用 ${Engine.Name} 搜索`;
- Button.type = "button";
- Button.addEventListener("click", (Event) => {
- Event.preventDefault();
- const Query = SearchInput.value.trim();
- if (Query) {
- const SearchUrl = `${Engine.Url}${encodeURIComponent(Query)}`;
- window.open(SearchUrl, "_blank", "noopener,noreferrer");
- }
- });
- BtnGroup.appendChild(Button);
- });
- SearchForm.parentNode.insertBefore(BtnGroup, SearchForm.nextSibling);
- }
- const DebouncedCreateSearchButtons = Debounce(
- CreateSearchButtons,
- DebounceDelay
- );
- function CheckAndMaybeCreateButtons() {
- const SearchFormExists = document.querySelector(SearchFormSelector);
- const ButtonsExist = document.querySelector(`.${SearchBtnGroupClass}`);
- if (SearchFormExists && !ButtonsExist) {
- DebouncedCreateSearchButtons();
- }
- }
- const Observer = new MutationObserver(CheckAndMaybeCreateButtons);
- Observer.observe(document.body, {
- childList: true,
- subtree: true,
- });
- if (document.readyState === "loading") {
- window.addEventListener("DOMContentLoaded", CheckAndMaybeCreateButtons);
- } else {
- CheckAndMaybeCreateButtons();
- }
- })();