你的位置:首页 > 网页设计

[网页设计]ENGLISH抠脚童鞋的福利


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

  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);

View Code

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

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