Wikipedia multi language view

View a Wikipedia entry with two (or more?) languages side by side for comparison and language learning.

当前为 2025-05-26 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name             Wikipedia multi language view
// @name:zh          Wikipedia 多语言浏览
// @namespace        https://userscript.snomiao.com/
// @author           [email protected]
// @version          0.0.6
// @description      View a Wikipedia entry with two (or more?) languages side by side for comparison and language learning.
// @description:zh   以并列多语言视角浏览维基百科
// @match            https://*.wikipedia.org/wiki/*
// @match            https://zh.wikipedia.org/zh-*/*
// @grant            none
// @run-at           document-start
// @license          GPL-3.0+
// @supportURL       https://github.com/snomiao/userscript.js/issues
// @contributionURL  https://snomiao.com/donate
// ==/UserScript==
// 
// MAINTAINING NOTE: this file have been moved to https://github.com/snomiao/multilang-wiki/tree/main
// please contribute there if you want to improve this script.
// 
// ref:
// [javascript - Resize Cross Domain Iframe Height - Stack Overflow]( https://stackoverflow.com/questions/22086722/resize-cross-domain-iframe-height )
//

// const Langs = ['en', 'ja', 'zh', 'de', 'fr', 'es', 'ru', 'it', 'ko', 'pt', 'ar', 'vi', 'pl', 'uk', 'nl', 'sv', 'id', 'fi', 'no', 'tr', 'cs', 'da', 'he', 'hu', 'ro', 'th']
const langs = ['en', 'ja', 'zh'] // modify this to your preferred languages, will be used to load the 2nd language iframe
// 

if (location.hash.match("#langIfr")) {
    // iframe code send height
    const sendHeight = () =>
        parent.postMessage?.(
            { langIfr: { height: document.body.scrollHeight } },
            "*"
        );
    window.addEventListener("resize", sendHeight, false);
    window.addEventListener("load", sendHeight, false);
    sendHeight();
    document.head.appendChild(createHtmlElement('<base target="_parent" />'))
} else {
    // parent code recv iframe's height
    const msgHandler = (e) => {
        const setHeight = (height) =>
            height &&
            document.querySelector("#langIfr")?.setAttribute("height", height);
        setHeight(e.data?.langIfr?.height);
    };
    window.addEventListener("message", msgHandler, false);
    // load iframe
    const langLnksGet = () =>
        Object.fromEntries(
            [...document.querySelectorAll("a.interlanguage-link-target")]
                .map((e) => ({
                    lang: e.getAttribute("lang"),
                    href: e.href,
                    language: e.textContent,
                }))
                .map((e) => [e.lang, e])
        );
    const exlangFrameLoad = () => {
        const langLnks = langLnksGet();
        const langIframeLoad = (lang = "en") => {
            if (!langLnks[lang]) return false;
            document.body.setAttribute("style", "width: 50vw");
            document.body.querySelector("#langIfr")?.remove();
            document.querySelector("#sidebarCollapse")?.click();
            const langIfr = Object.assign(document.createElement("iframe"), {
                id: "langIfr",
                src: langLnks[lang].href + "#langIfr",
            });
            langIfr.setAttribute(
                "style",
                "border: none; position:absolute; left: 50vw; top: 0vh; width: 50vw"
            );
            document.body.appendChild(langIfr);
            return true;
        };

        // the load 2st language for current page
        langs.find(lang => langIframeLoad(lang))
    };
    window.addEventListener("load", exlangFrameLoad, false);
}

function createHtmlElement(innerHTML= '<span>hello</span>'){
  return Object.assign(document.createElement('div'), {innerHTML}).children[0]
}