MediaWiki:Gadget-UnihanTooltips.js:修订间差异
外观
	
	
 创建页面,内容为“→本小工具可以將[[Template:僻字]]的提示由原來的title提示改為元素式彈出提示,使觸控式裝置可以觀看有關提示:  (function() {     // 使用MediaWiki的Cookie方法     const dontLoad = mw.util.getParamValue("UTdontload");     if (dontLoad && !isNaN(dontLoad)) {         mw.cookie.set("UTdontload", "1", { path: "/", expires: parseInt(dontLoad) });     }     if (mw.cookie.get("UTdontload") === "1") return;      (function()…”  | 
			
(没有差异) 
 | 
2025年11月2日 (日) 17:43的版本
/*
  本小工具可以將[[Template:僻字]]的提示由原來的title提示改為元素式彈出提示,使觸控式裝置可以觀看有關提示
*/
(function() {
    // 使用MediaWiki的Cookie方法
    const dontLoad = mw.util.getParamValue("UTdontload");
    if (dontLoad && !isNaN(dontLoad)) {
        mw.cookie.set("UTdontload", "1", { path: "/", expires: parseInt(dontLoad) });
    }
    if (mw.cookie.get("UTdontload") === "1") return;
    (function() {
        // 使用MediaWiki提供的content容器
        const bodyContent = mw.util.$content || document.body;
        const canonicalNamespace = mw.config.get('wgCanonicalNamespace');
        
        // 只在这些命名空间运行
        if (!['', 'Project', 'Help'].includes(canonicalNamespace)) return;
        // 更可靠的触摸检测
        const isTouchscreen = mw.config.get('wgDisplayResolution') === 'mobile' || 
                             'ontouchstart' in document.documentElement;
        const timerLength = isTouchscreen ? 0 : 200;
        // 添加CSS样式
        mw.util.addCSS(`
            .unihantooltip {
                position: absolute;
                z-index: 999;
                background: #fff;
                border: 1px solid #ccc;
                padding: 5px;
                border-radius: 3px;
                box-shadow: 0 2px 5px rgba(0,0,0,0.2);
                opacity: 0;
                transition: opacity 0.1s;
            }
            .unihantooltip.UHflipped {
                top: auto !important;
                bottom: 12px;
            }
        `);
        $(".inline-unihan").each(function() {
            let tooltipNode = null;
            let hideTimer = null;
            let showTimer = null;
            function hide(refLink) {
                if (tooltipNode && tooltipNode.parentNode === bodyContent) {
                    hideTimer = setTimeout(() => {
                        $(tooltipNode).animate({
                            opacity: 0
                        }, 100, function() {
                            if (tooltipNode && tooltipNode.parentNode) {
                                tooltipNode.parentNode.removeChild(tooltipNode);
                            }
                        });
                    }, isTouchscreen ? 16 : 100);
                }
            }
            function show() {
                if (!tooltipNode.parentNode || tooltipNode.parentNode.nodeType === 11) {
                    bodyContent.appendChild(tooltipNode);
                }
                $(tooltipNode).stop().animate({
                    opacity: 1
                }, 100);
                clearTimeout(hideTimer);
            }
            // 保存原始title并清空
            const originalTitle = this.title;
            this.title = "";
            // 使用jQuery的on方法代替hover
            $(this).on(isTouchscreen ? 'click' : 'mouseenter mouseleave', function(e) {
                const element = this;
                
                if (isTouchscreen && e.type === 'click') {
                    e.preventDefault();
                    
                    if (!tooltipNode || tooltipNode.parentNode !== bodyContent) {
                        requestAnimationFrame(() => {
                            $(bodyContent).on("click touchstart", function closeHandler(e) {
                                const target = e.target || e.srcElement;
                                let currentElement = target;
                                
                                while (currentElement && !currentElement.classList.contains("unihantooltip")) {
                                    currentElement = currentElement.parentNode;
                                }
                                
                                if (!currentElement) {
                                    clearTimeout(showTimer);
                                    hide(element);
                                    $(bodyContent).off("click touchstart", closeHandler);
                                }
                            });
                        });
                    }
                }
                if (e.type === 'mouseleave') {
                    clearTimeout(showTimer);
                    hide(this);
                    return;
                }
                showTimer && clearTimeout(showTimer);
                showTimer = setTimeout(() => {
                    const tooltipContent = $("<ul class='reflist'></ul>");
                    const lines = originalTitle.split("\n");
                    
                    lines.forEach(line => {
                        if (line.trim()) {
                            tooltipContent.append($("<li></li>").text(line)).append("<br>");
                        }
                    });
                    if (!tooltipNode) {
                        tooltipNode = document.createElement("div");
                        tooltipNode.className = "unihantooltip";
                        $(tooltipNode).append(tooltipContent);
                        
                        if (!isTouchscreen) {
                            $(tooltipNode).on("mouseenter", show)
                                          .on("mouseleave", hide);
                        }
                    }
                    show();
                    
                    const position = $(element).position();
                    const viewport = mw.util.getViewportDimensions();
                    let top = position.top - tooltipNode.offsetHeight;
                    let left = position.left - 7;
                    // 边界检测
                    if (top < 0) {
                        $(tooltipNode).addClass("UHflipped");
                        top = position.top + $(element).outerHeight();
                    } else {
                        $(tooltipNode).removeClass("UHflipped");
                    }
                    if (left + tooltipNode.offsetWidth > viewport.width) {
                        left = viewport.width - tooltipNode.offsetWidth - 10;
                    }
                    $(tooltipNode).css({
                        top: Math.max(0, top),
                        left: Math.max(0, left)
                    });
                }, timerLength);
            });
        });
    })();
})();