Tools 是非官方社区Wiki。社区文档正在编写中,欢迎参与。 Wiki编辑答疑群:717421103
版本250923.2
全站通知:

Widget:Search

来自WIKI实验室WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

MediaWiki 移动端搜索框优化方案

功能介绍

这是一个为 MediaWiki 站点优化移动端搜索体验的解决方案。主要特点包括:

1. 移动端搜索按钮优化

  - 在移动端视图中添加一个独立的搜索按钮
  - 点击按钮时弹出全屏搜索界面

2. 全屏搜索体验

  - 搜索框自动获得焦点
  - 搜索建议列表显示在搜索框下方
  - 半透明遮罩背景
  - 优雅的过渡动画效果

3. 搜索建议优化

  - 保留原有的搜索建议功能
  - 优化了建议列表的显示位置和样式
  - 添加了输入节流处理,提升性能

与原版搜索的主要区别

1. 界面布局

  - 原版:搜索框固定在导航栏,空间受限
  - 优化版:点击后全屏显示,更多操作空间

2. 用户体验

  - 原版:在小屏幕设备上操作不便
  - 优化版:全屏布局,输入更方便,建议列表显示更清晰

3. 视觉效果

  - 原版:简单的下拉建议
  - 优化版:添加了过渡动画和遮罩效果,更现代的视觉体验

如何使用

1、在 https://wiki.biligame.com/你管理的BWIKI/Widget:Search 页面粘贴以下代码
<includeonly><style>
    #navSearch {
        display: none !important;
    }

    #navSearch-button {
        display: inline-block;
        position: absolute;
        right: 50px;
        top: 29px;
        width: 20px;
        height: 20px;
    }

    #simpleSearch1 #searchDelete {
        background-color: unset !important;
    }

    #simpleSearch1 #searchInput {
        padding: 1.5rem 0;
        width: calc(100% - 42px);
    }

    #simpleSearch1 #searchInput:focus {
        box-shadow: none;
    }

    .search-overlay.visible {
        position: fixed;
        display: block;
        width: 100%;
        height: 100%;
        background-color: rgb(0 0 0 / 50%);
        color: #000;
        z-index: 9999;
        top: 0;
        left: 0;
        visibility: visible;
        pointer-events: auto;
        user-select: auto;
        padding: 0 15px;
        opacity: 0;
        transition: opacity 0.5s;
    }

    .search-overlay.visible .overlay-header {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        background-color: #eaecf0;
        box-shadow: inset 0 -1px 3px rgb(0 0 0 / 8%);
        border: 1px solid #fff;
        margin: 10px 0;
    }

    .search-overlay.visible .overlay-close {
        background-image: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"%23000000\"><path d=\"m4.34 2.93 12.73 12.73-1.41 1.41L2.93 4.35z\"/><path d=\"M17.07 4.34 4.34 17.07l-1.41-1.41L15.66 2.93z\"/></svg>");
        width: 40px;
        height: 40px;
        display: inline-block;
        background-repeat: no-repeat;
        background-position: center;
        cursor: pointer;
    }

    .search-overlay.visible .overlay-search {
        display: inline-block;
        width: calc(100% - 40px - 20px);
        height: auto;
        margin: 10px;
        background-color: #fff;
    }

    .search-overlay.visible .suggestions {
        position: unset !important;
        width: 100% !important;
    }
</style><script>
    // 作者:怒怒 https://space.bilibili.com/141211391
    // 补充和修改:时舟(sizau) https://space.bilibili.com/3546754953775813
    (function () {
        var overlaysContainer = document.createElement("div");
        overlaysContainer.className = "mw-overlays-container";
        overlaysContainer.innerHTML = `<div class="search-overlay" style="opacity:0"><div class="overlay-header"><div class="overlay-search"></div><div class="overlay-close"></div></div><div class="overlay-content"></div></div>`;
        document.body.appendChild(overlaysContainer);
        var originalParent = null;
        var originalIndex = null;
        var suggestions = null;
        var navSearch = document.querySelector("#navSearch");
        var navSearchButton = document.createElement("span");
        navSearchButton.id = "navSearch-button";
        navSearchButton.className = "visible-xs";
        navSearchButton.innerHTML = navSearch.innerHTML;
        navSearch.insertAdjacentElement("afterend", navSearchButton);
        navSearch.remove();
        var searchForm = document.querySelector("#searchform");
        var searchOverlay = document.querySelector(".search-overlay");
        var overlayContent = document.querySelector(".overlay-content");
        navSearchButton.addEventListener("click", function () {
            searchOverlay.classList.add("visible");
            searchOverlay.style.opacity = '1';
            // 保存原始位置
            if (originalParent === null) {
                originalParent = searchForm.parentElement;
                originalIndex = Array.from(originalParent.children).indexOf(searchForm);
            }
            // 移动搜索框
            document.querySelector(".overlay-search").appendChild(searchForm);
            document.body.style.overflow = "hidden";
            document.querySelector("#searchInput").focus();
            if (suggestions) {
                overlayContent.appendChild(suggestions);
            } else {
                setTimeout(function () {
                    suggestions = document.querySelector(".suggestions");
                    if (suggestions) {
                        overlayContent.appendChild(suggestions);
                    }
                }, 500);
            }
        });
        var overlayClose = document.querySelector(".overlay-close");
        overlayClose.addEventListener("click", function () {
            searchOverlay.style.opacity = '0';
            setTimeout(function () {
                searchOverlay.classList.remove("visible");
            }, 500);
            // 将搜索框移回原始位置
            if (originalParent !== null) {
                if (originalIndex >= originalParent.children.length) {
                    originalParent.appendChild(searchForm);
                } else {
                    originalParent.insertBefore(searchForm, originalParent.children[originalIndex]);
                }
            }
            document.body.style.overflow = "";
            if (suggestions) {
                document.body.appendChild(suggestions);
            }
        });
        function UpdateSuggestions() {
            try {
                var $searchInput = $("#searchInput"),
                    previousSearchText = $searchInput.val(),
                    throttleTimer,
                    lastTime = 0;
                $searchInput.on("focus", function () {
                    $(this).trigger("keypress");
                });
                $searchInput.on("input", function () {
                    var searchText = $(this).val(),
                        currentTime = Date.now();
                    currentTime - lastTime >= 550
                        ? (searchText &&
                            searchText !== previousSearchText &&
                            $("#searchInput").trigger("keypress"),
                            (previousSearchText = searchText),
                            (lastTime = currentTime))
                        : (clearTimeout(throttleTimer),
                            (throttleTimer = setTimeout(function () {
                                searchText &&
                                    searchText !== previousSearchText &&
                                    $("#searchInput").trigger("keypress"),
                                    (previousSearchText = searchText),
                                    (lastTime = Date.now());
                            }, 550)));
                });
            } catch (error) { }
        }
        (window.RLQ = window.RLQ || []).push([["jquery"], function () {
            $(document).ready(function () {
                UpdateSuggestions();
            });
        }]);
    })();
</script></includeonly>
2、在 https://wiki.biligame.com/你管理的BWIKI/MediaWiki:Sitenotice 页面添加调用
{{#widget:Search}}
确保你的站点页面中有以下元素:
  - ID 为 navSearch 的搜索按钮容器
  - ID 为 searchform 的搜索表单
  - ID 为 searchInput 的搜索输入框'


注意事项

  1. 代码依赖 jQuery,确保你的 MediaWiki 站点已启用 jQuery
  2. 如果你的站点使用了自定义的搜索框样式,可能需要调整 CSS 中的样式值
  3. 代码中的 visible-xs 类用于控制移动端显示,请确保你的站点支持这个类名,或根据需要修改

兼容性

  - 支持主流移动端浏览器
  - 兼容 MediaWiki 1.31 及以上版本
  - 响应式设计,同时支持移动端和桌面端

自定义修改

如果需要修改样式,可以调整 <style> 标签中的 CSS:

  - 修改 #navSearch-button 的位置和大小
  - 调整 .search-overlay 的背景色和透明度
  - 更改 .overlay-header 的样式和布局

技术支持

原作者:怒怒 (https://space.bilibili.com/141211391)

修改版本:时舟 (https://space.bilibili.com/3546754953775813)

更新日志

  • v1.1(2025-10-01):修改css加载顺序,修正css进来过慢导致异常显示过大的搜索图标。
  • v1.0(2025-02-12):测试版发布。