今天在某前端群看到一个插件,激动万分啊!我就把插件使用实现的步骤分享一下!

  1. 打开chrome浏览器输入地址:chrome://extensions/
  2. 跳转到其他页面,点击左上角--扩展程序;
  3. 将Tampermonkey_v4.0.25.crx文件拖进去。点击--确认添加脚本;
  4. 点击chrome地址栏最右边五角星旁边灰色按钮鼠标悬停提示tampermonkey这个按钮;
  5. 点击--添加新脚本;
  6. 进入界面后把:GitHub_汉化插件main.js里的代码全部复制粘贴进去Ctrl+s保存;
  7. 大功告成!进入github主页看看效果吧。没效果请清除缓存!
  8. 大神的插件地址:https://github.com/52cik/github-hans

  在插件布置完成后,难免有点小激动!我将chrome插件Tampermonkey_v4.0.25.crx移除后,直接将main.js添加新脚本,也汉化了,感觉没什么差异!

  嫌github下载作者的该插件速度慢的童鞋直接将main.js代码按上面的步骤直接添加到新脚本试试吧!

附上main.js:

// ==UserScript==
// @name GitHub 汉化插件
// @description 汉化 GitHub 界面的部分菜单及内容。
// @copyright 2016, 楼教主 (http://www.52cik.com/)
// @icon https://assets-cdn.github.com/pinned-octocat.svg
// @version 1.6.3
// @author 楼教主
// @license MIT
// @homepageURL https://github.com/52cik/github-hans
// @match http://*.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'; var lang = 'zh'; // 中文 // 2016-04-18 github 将 jquery 以 amd 加载,不暴露到全局了。
var $ = require('github/jquery')['default']; // 要翻译的页面
var 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];
// todo 1. 修复多属性翻译问题; 2. 添加事件翻译, 如论预览信息; if (el.nodeType === Node.ELEMENT_NODE) { // 元素节点处理 // 元素节点属性翻译
if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') { // 输入框 按钮 文本域
if (el.type === 'button' || el.type === 'submit') {
transElement(el, 'value');
} else {
transElement(el, 'placeholder');
}
} else if (el.hasAttribute('aria-label')) { // 带提示的元素,类似 tooltip 效果的
transElement(el, 'aria-label', true); if (el.hasAttribute('data-copied-hint')) { // 复制成功提示
transElement(el.dataset, 'copiedHint');
}
} else if (el.tagName === 'OPTGROUP') { // 翻译 <optgroup> 的 label 属性
transElement(el, 'label');
} if (el.hasAttribute('data-disable-with')) { // 按钮等待提示
transElement(el.dataset, 'disableWith');
} // 跳过 readme, 文件列表, 代码显示
if (el.id !== 'readme' && !I18N.conf.reIgnore.test(el.className)) {
walk(el); // 遍历子节点
}
} else if (el.nodeType === Node.TEXT_NODE) { // 文本节点翻译
transElement(el, 'data');
} }
} /**
* 获取翻译页面
*/
function getPage() {
// 先匹配 body 的 class
var 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'); if (title === false) { // 无翻译则退出
return false;
} document.title = title;
} /**
* 翻译节点对应属性内容
*
* @param {object} el 对象
* @param {string} field 属性字段
* @param {boolean} isAttr 是否是 attr 属性
*
* @returns {boolean}
*/
function transElement(el, field, isAttr) {
var transText = false; // 翻译后的文本 if (isAttr === undefined) { // 非属性翻译
transText = translate(el[field], page);
} else {
transText = translate(el.getAttribute(field), page);
} if (transText === false) { // 无翻译则退出
return false;
} // 替换翻译后的内容
if (isAttr === undefined) {
el[field] = transText;
} else {
el.setAttribute(field, transText);
}
} /**
* 翻译文本
*
* @param {string} text 待翻译字符串
* @param {string} page 页面字段
*
* @returns {string|boolean}
*/
function translate(text, page) { // 翻译
var str;
var _key = text.trim(); // 去除首尾空格的 key
var _key_neat = _key
.replace(/\xa0/g, ' ') // 替换 &nbsp; 空格导致的 bug
.replace(/\s{2,}/g, ' '); // 去除多余换行空格等字符,(试验测试阶段,有问题再恢复) if (_key_neat === '') {
return false;
} // 内容为空不翻译 str = transPage('pubilc', _key_neat); // 公共翻译 if (str !== false && str !== _key_neat) { // 公共翻译完成
str = transPage('pubilc', str) || str; // 二次公共翻译(为了弥补正则部分翻译的情况)
return text.replace(_key, str); // 替换原字符,保留空白部分
} if (page === false) {
return false;
} // 未知页面不翻译 str = transPage(page, _key_neat); // 翻译已知页面
if (str === false || str === '') {
return false;
} // 未知内容不翻译 str = transPage('pubilc', str) || str; // 二次公共翻译(为了弥补正则部分翻译的情况)
return text.replace(_key, str); // 替换原字符,保留空白部分
} /**
* 翻译页面内容
*
* @param {string} page 页面
* @param {string} key 待翻译内容
*
* @returns {string|boolean}
*/
function transPage(page, key) {
var str; // 翻译结果
var 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;
}
}
} return false; // 没有翻译条目
} /**
* 时间节点翻译
*/
function timeElement() {
if (!window.RelativeTimeElement) { // 防止报错
return;
} var RelativeTimeElement$getFormattedDate = RelativeTimeElement.prototype.getFormattedDate;
var TimeAgoElement$getFormattedDate = TimeAgoElement.prototype.getFormattedDate;
// var LocalTimeElement$getFormattedDate = LocalTimeElement.prototype.getFormattedDate; var RelativeTime = function (str, el) { // 相对时间解析
if (/^on ([\w ]+)$/.test(str)) {
return '于 ' + el.title.replace(/ .+$/, '');
} // 使用字典公共翻译的第二个正则翻译相对时间
var 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 元素进行翻译
// 2016-04-16 github 改版,不再用 time 标签了。
$('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'); // 等待 IncludeFragmentElement 元素加载完毕后绑定事件
var observe = require('github/observe').observe;
observe(".js-calendar-graph-svg", function () {
setTimeout(function () { // 延时绑定 mouseover 事件,否则没法翻译
var $calendar = $('.js-calendar-graph');
walk($calendar[0]); // 翻译日历部分 $calendar.on('mouseover', '.day', function () {
if (tip.length === 0) { // 没有 tip 元素时退出防止报错
return true;
} var data = $(this).data(); // 获取节点上的 data
var $tip = $(tip[0]); $tip.html(data.count + ' 次贡献 ' + data.date); var rect = this.getBoundingClientRect(); // 获取元素位置
var left = rect.left + window.pageXOffset - tip[0].offsetWidth / 2 + 5.5; $tip.css('left', left);
});
}, 999);
});
} })(window, document);

  虽然翻译的不是很完全,但是基本使用还是没问题的。

  该插件作者也在不停的更新中,还是关注下,有空就看看更新吧!

ENGLISH抠脚童鞋的福利--GitHub汉化插件的更多相关文章

  1. 三步操作gitHub汉化插件安装--谷歌浏览器

    如果本文对你有用,请爱心点个赞,提高排名,帮助更多的人.谢谢大家!❤ 如果解决不了,可以在文末进群交流. 一个好用基于chrome的插件,用来汉化gitHub,大致效果图如下: 步骤一: 首先下载谷歌 ...

  2. 【转】GitHub汉化脚本(谷歌浏览器)

    // ==UserScript== // @name GitHub 汉化插件 // @description 汉化 GitHub 界面的部分菜单及内容. // @copyright 2016, 楼教主 ...

  3. 【APP设计利器】Sketch 41 Mac中文破解版(含汉化插件)

    Sketch是一款拥有美观界面和强大功能适用于所有设计师的专业矢量绘图工具.它旨在为美术设计师创造出一款更优秀的作品,不是复制品,而是提升品.Sketch简约的设计是基于无限的规模和层次的绘图空间,免 ...

  4. 最详细eclipse汉化插件安装教程

    最详细eclipse汉化插件安装教程(转) 转自:http://blog.csdn.net/dai_zhenliang/article/details/8588576#t4 教程作者:戴振良 本文与& ...

  5. psp开发------汉化插件

    近期略微研究了下psp汉化,写了个汉化插件,在这记录下.聊以慰藉. 传统的汉化流程找码表,字库,破解什么这里不多讲,网上有教程.以下说下一种另类汉化方法.特别对于难以破解字库的游戏,当然这样的方法也有 ...

  6. 安装Sublime Text 3汉化插件

    一.Sublime Text工具介绍: Sublime Text 是一个代码编辑器(Sublime Text 2是收费软件,但可以无限期试用),也是HTML和散文先进的文本编辑器.Sublime Te ...

  7. Sublime Text 3下载-汉化-插件配置

    Sublime Text 3下载 不用说是上官方下载地址:http://www.sublimetext.com/3 Sublime Text 3 免费使用方法 Sublime Text 2的时候还有一 ...

  8. Java开发环境配置(3)--eclipse汉化插件安装、卸载 中遇到的问题

    eclipse汉化中遇到的问题 网上汉化的帖子很多 如: Eclipse超级完美汉化教程_百度经验http://jingyan.baidu.com/article/e75057f28401a8ebc9 ...

  9. sublime text3:下载代码格式化插件和汉化插件

    1.从官网下载sublime text3 2.下载插件工具 A.使用Ctrl+`(Esc键下方)快捷键或者通过View->Show Console菜单打开命令行 将以下代码复制后粘贴,然后按En ...

随机推荐

  1. 拨开迷雾,找回自我:DDD 应对具体业务场景,Domain Model 到底如何设计?

    写在前面 除了博文内容之外,和 netfocus 兄的讨论,也可以让你学到很多(至少我是这样),不要错过哦. 阅读目录: 迷雾森林 找回自我 开源地址 后记 毫无疑问,领域驱动设计的核心是领域模型,领 ...

  2. C# 利用性能计数器监控网络状态

    本例是利用C#中的性能计数器(PerformanceCounter)监控网络的状态.并能够直观的展现出来 涉及到的知识点: PerformanceCounter,表示 Windows NT 性能计数器 ...

  3. static,你还敢用吗?(二)

    为了压系统,昨天小组在测试环境模拟了一大批订单数据.今天上午查看记录的账单计息日志,发现了一大堆的MySqlException MySql.Data.MySqlClient.MySqlExceptio ...

  4. 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查。。。

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Ser ...

  5. AFNetworking 3.0 源码解读 总结(干货)(下)

    承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...

  6. C# BackgroundWorker 详解

    在C#程序中,经常会有一些耗时较长的CPU密集型运算,如果直接在 UI 线程执行这样的运算就会出现UI不响应的问题.解决这类问题的主要途径是使用多线程,启动一个后台线程,把运算操作放在这个后台线程中完 ...

  7. Spring配置文件标签报错:The prefix "XXX" for element "XXX:XXX" is not bound. .

    例如:The prefix "context" for element "context:annotation-config" is not bound. 这种 ...

  8. BPM公文管理解决方案分享

    一.方案概述 公文作为一种规范性文书,具有法律性.指导性.政令性强的特点,是企事业单位政令上通下达的重要方式.及时.准确.安全地处理.控制和管理公文,方能保障企事业单位正常运转,确保组织权威和政令畅通 ...

  9. React Native环境配置之Windows版本搭建

    接近年底了,回想这一年都做了啥,学习了啥,然后突然发现,这一年买了不少书,看是看了,就没有完整看完的.悲催. 然后,最近项目也不是很紧了,所以抽空学习了H5.自学啃书还是很无趣的,虽然Head Fir ...

  10. Mysql - 查询之关联查询

    查询这块是重中之重, 关系到系统反应时间. 项目做到后期, 都是要做性能测试和性能优化的, 优化的时候, 数据库这块是一个大头. sql格式: select 列名/* from 表名 where 条件 ...