今天在某前端群看到一个插件,激动万分啊!我就把插件使用实现的步骤分享一下!
在插件布置完成后,难免有点小激动!我将chrome插件Tampermonkey_v4.0.25.crx移除后,直接将main.js添加新脚本,也汉化了,感觉没什么差异!
嫌github下载作者的该插件速度慢的童鞋直接将main.js代码按上面的步骤直接添加到新脚本试试吧!
附上main.js:
// ==UserScript== // @name GitHub 汉化插件 // @description 汉化 GitHub 界面的部分菜单及内容。 // @copyright 2016, 楼教主 () // @icon https://assets-cdn.github.com/pinned-octocat.svg // @version 1.6.3 // @author 楼教主 // @license MIT // @homepageURL https://github.com/52cik/github-hans // @match *.github.com/* // @match https://*.github.com/* // @require https://52cik.github.io/github-hans/locals.js?v1.6.3 // @run-at document-end // @grant none // ==/UserScript== (function (window, document, undefined) { 'use strict'; $ = require('github/jquery')['default']; page = getPage(); transTitle(); // 页面标题翻译 timeElement(); // 时间节点翻译 contributions(); // 贡献日历翻译 (日历是内嵌或ajax的, 所以基于回调事件处理) walk(document.body); // 立即翻译页面 $(document).ajaxComplete(function () { transTitle(); walk(document.body); // ajax 请求后再次翻译页面 }); /** * 遍历节点 * * @param {Element} node 节点 */ function walk(node) { var nodes = node.childNodes; for (var i = 0, len = nodes.length; i < len; i++) { var el = nodes[i]; (el.nodeType === Node.ELEMENT_NODE) { (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') { (el.type === 'button' || el.type === 'submit') { transElement(el, 'value'); } else { transElement(el, 'placeholder'); } } transElement(el, 'aria-label', true); if (el.hasAttribute('data-copied-hint')) { // 复制成功提示 transElement(el.dataset, 'copiedHint'); } } transElement(el, 'label'); } if (el.hasAttribute('data-disable-with')) { // 按钮等待提示 transElement(el.dataset, 'disableWith'); } (el.id !== 'readme' && !I18N.conf.reIgnore.test(el.className)) { walk(el); // 遍历子节点 } } transElement(el, 'data'); } } } /** * 获取翻译页面 */ function getPage() { page = document.body.className.match(I18N.conf.rePageClass); if (!page) { // 扩展 url 匹配 page = location.href.match(I18N.conf.rePageUrl); } if (!page) { // 扩展 pathname 匹配 page = location.pathname.match(I18N.conf.rePagePath); } return page ? page[1] || 'homepage' : false; // 取页面 key } /** * 翻译页面标题 */ function transTitle() { var title = translate(document.title, 'title'); ; } document.title = title; } /** * 翻译节点对应属性内容 * * @param {object} el 对象 * @param {string} field 属性字段 * @param {boolean} isAttr 是否是 attr 属性 * * @returns {boolean} */ function transElement(el, field, isAttr) { (isAttr === undefined) { // 非属性翻译 transText = translate(el[field], page); } else { transText = translate(el.getAttribute(field), page); } ; } (isAttr === undefined) { el[field] = transText; } else { el.setAttribute(field, transText); } } /** * 翻译文本 * * @param {string} text 待翻译字符串 * @param {string} page 页面字段 * * @returns {string|boolean} str; _key_neat = _key .replace(/\xa0/g, ' ') // 替换 空格导致的 bug .replace(/\s{2,}/g, ' '); (_key_neat === '') { return false; } // 内容为空不翻译 str = transPage('pubilc', _key_neat); (str !== false && str !== _key_neat) { // 公共翻译完成 str = transPage('pubilc', str) || str; text.replace(_key, str); // 替换原字符,保留空白部分 } if (page === false) { return false; } // 未知页面不翻译 str = transPage(page, _key_neat); (str === false || str === '') { return false; } // 未知内容不翻译 str = transPage('pubilc', str) || str; text.replace(_key, str); // 替换原字符,保留空白部分 } /** * 翻译页面内容 * * @param {string} page 页面 * @param {string} key 待翻译内容 * * @returns {string|boolean} */ function transPage(page, key) { res; str = I18N[lang][page]['static'][key]; if (str) { return str; } // 正则翻译 res = I18N[lang][page].regexp; if (res) { for (var i = 0, len = res.length; i < len; i++) { str = key.replace(res[i][0], res[i][1]); if (str !== key) { return str; } } } } /** * 时间节点翻译 */ function timeElement() { ; } var RelativeTimeElement$getFormattedDate = RelativeTimeElement.prototype.getFormattedDate; var TimeAgoElement$getFormattedDate = TimeAgoElement.prototype.getFormattedDate; RelativeTime = (/^on ([\w ]+)$/.test(str)) { return '于 ' + el.title.replace(/ .+$/, ''); } time_ago = I18N[lang].pubilc.regexp[1]; return str.replace(time_ago[0], time_ago[1]); }; RelativeTimeElement.prototype.getFormattedDate = function () { var str = RelativeTimeElement$getFormattedDate.call(this); return RelativeTime(str, this); }; TimeAgoElement.prototype.getFormattedDate = function () { var str = TimeAgoElement$getFormattedDate.call(this); return RelativeTime(str, this); }; LocalTimeElement.prototype.getFormattedDate = function () { return this.title.replace(/ .+$/, ''); }; $('time, relative-time, time-ago, local-time').each(function (i, el) { if (el.getFormattedDate) { // 跳过未注册的 time 元素 el.textContent = el.getFormattedDate(); } }); } /** * 贡献日历 基于事件翻译 */ function contributions() { var tip = document.getElementsByClassName('svg-tip-one-line'); observe = require('github/observe').observe; observe(".js-calendar-graph-svg", function () { setTimeout($calendar = $('.js-calendar-graph'); walk($calendar[0]); // 翻译日历部分 $calendar.on('mouseover', '.day', function () { ; } $tip = $(tip[0]); $tip.html(data.count + ' 次贡献 ' + data.date); left = rect.left + window.pageXOffset - tip[0].offsetWidth / 2 + 5.5; $tip.css('left', left); }); }, 999); }); } })(window, document);
View Code虽然翻译的不是很完全,但是基本使用还是没问题的。
该插件作者也在不停的更新中,还是关注下,有空就看看更新吧!