You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

原生JS实现同一页面重复点击同名锚点时触发输入框聚焦的最简方案

原生JS实现同一页面重复点击同名锚点时触发输入框聚焦的最简方案

嘿,我完全懂你的困扰——重复点同一个锚点时,因为URL的hash没变化,hashchange事件不触发,导致输入框失去焦点后没法自动回去。其实解决起来超简单,不用任何库,只需要给锚点链接加个点击监听就行,我一步步给你说清楚:

问题核心回顾

你的现有代码只监听了hashchangeload事件,但点击同一个锚点时hash不会变,所以聚焦函数不会重新执行。我们需要给每个锚点链接单独加点击监听,不管hash变不变,点击后都强制跑一遍聚焦逻辑。

修改后的完整代码

我保留了你原来的核心逻辑,只新增了必要的监听代码,还加了点鲁棒性判断避免报错:

<!DOCTYPE html>
<html>
<head>
    <style>
        /* 隐藏所有搜索表单默认状态 */
        .Startpage, .DuckDuckGo, .Wayback, .Bing, .Google, .YouTube, .Google_Images, .OpenGameArt, .FreeSound, .Amazon { 
            display : none; 
        }
        /* 锚点激活时显示对应表单 */
        #Startpage:target.Startpage, #DuckDuckGo:target.DuckDuckGo, #Wayback:target.Wayback, #Bing:target.Bing, #Google:target.Google, #YouTube:target.YouTube, #Google_Images:target.Google_Images, #OpenGameArt:target.OpenGameArt, #FreeSound:target.FreeSound, #Amazon:target.Amazon { 
            display : block; 
        }
    </style>
</head>
<body>
    <!-- 你的所有搜索表单保持不变 -->
    <form method="get" action="https://eu.startpage.com/do/search" id="Startpage" class="Startpage">
        <input type="text" name="query" value="" placeholder=" Startpage">
    </form>
    <form method="get" action="https://duckduckgo.com/" id="DuckDuckGo" class="DuckDuckGo">
        <input type="text" name="q" value="" placeholder=" DuckDuckGo" required="" minlength="1">
    </form>
    <form method="post" action="https://web.archive.org/" id="Wayback" class="Wayback">
        <input type="text" name="url" placeholder=" Wayback">
    </form>
    <!-- 省略其他重复表单... -->

    <h2>Web Search</h2>
    <ul>
        <li><a href="#Startpage">Startpage</a></li>
        <li><a href="#DuckDuckGo">DuckDuckGo</a></li>
        <li><a href="#Bing">Bing</a></li>
        <li><a href="#Google">Google</a></li>
    </ul>

    <script>
        function focusOnSearch() {
            var urlAnchorId = window.location.hash.substring(1);
            // 新增判断:避免hash为空或目标元素不存在时报错
            if (urlAnchorId) {
                const targetForm = document.getElementById(urlAnchorId);
                if (targetForm) {
                    const inputField = targetForm.getElementsByTagName("input")[0];
                    if (inputField) inputField.focus();
                }
            }
        }

        // 保留你原来的两个事件监听
        window.addEventListener("hashchange", focusOnSearch);
        window.addEventListener("load", focusOnSearch);

        // 新增:给所有锚点链接绑定点击监听
        function setupAnchorClicks() {
            // 只选中指向当前页面锚点的a标签(href以#开头)
            const anchorLinks = document.querySelectorAll('a[href^="#"]');
            anchorLinks.forEach(link => {
                link.addEventListener('click', function() {
                    const targetId = this.href.split('#')[1];
                    // 确认目标表单存在再执行
                    if (document.getElementById(targetId)) {
                        // 用setTimeout让浏览器先处理锚点默认行为(比如显示表单),再聚焦
                        setTimeout(focusOnSearch, 0);
                    }
                });
            });
        }

        // 页面加载完成后初始化锚点监听
        window.addEventListener("load", setupAnchorClicks);
    </script>
</body>
</html>

关键修改点说明

  1. 增强focusOnSearch的鲁棒性
    加了多层判断,避免页面hash为空、目标表单不存在或找不到输入框时,控制台报红影响其他功能。

  2. 新增锚点点击监听逻辑

    • document.querySelectorAll('a[href^="#"]'):精准选中所有指向当前页面锚点的链接,不会监听外部跳转的链接
    • setTimeout(focusOnSearch, 0):给浏览器留一点时间处理锚点的默认行为(比如通过:target CSS显示对应表单),再执行聚焦,确保输入框已经显示出来,不会因为元素还隐藏着导致聚焦失败
    • 绑定在load事件上:确保所有锚点链接都加载完成后再绑定监听,不会漏绑

为什么这个方案最适合你?

  • 完全原生JS,没有任何库依赖,符合你的需求
  • 代码逻辑简单,作为新手也能轻松看懂和维护
  • 兼顾了「第一次点击锚点」和「重复点击同一锚点」的场景,同时处理了可能的报错情况

试一下这个修改,不管你点多少次同一个锚点,输入框都会自动聚焦啦!要是还有问题随时喊我~ 😊

火山引擎 最新活动