Merge branch 'gh-pages'

Conflicts:
	index.html
	script/relationship.js
	style/index.css
This commit is contained in:
mumuy 2017-04-21 10:09:36 +08:00
commit d2be61d6f1
19 changed files with 2968 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.project
.settings
node_modules/*

16
.travis.yml Normal file
View File

@ -0,0 +1,16 @@
language: node_js
node_js:
- "6.2.0"
- "5.6.0"
- "4.4.4"
install:
- npm install
script:
- npm run build
branches:
only:
- gh-pages

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Haole Zheng
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

31
app.html Normal file
View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>三姑六婆计算器</title>
<meta name="keywords" content="过年走亲访友,拜年神器,android">
<meta name="description" content="">
<link rel="stylesheet" href="style/app.css">
</head>
<body>
<div class="wrapper">
<div class="container">
<div class="mod-app">
<div class="icon"><img src="image/icon.png" width="72" height="72"/></div>
<div class="info">
<p>三姑六婆计算器</p>
<p><a href="https://pan.baidu.com/s/1sljDB8D" target="_blank">下载</a></p>
</div>
</div>
<div class="mod-view">
<img src="image/1.jpg" height="300">
<img src="image/2.jpg" height="300">
</div>
<div class="mod-qrcode">
<div class="box"><img src="image/qrcode.jpg" width="150"/></div>
<p>微信扫一扫,使用小程序</p>
</div>
</div>
</div>
</body>
</html>

1138
dist/relationship.js vendored Normal file

File diff suppressed because it is too large Load Diff

1
dist/relationship.min.js vendored Normal file

File diff suppressed because one or more lines are too long

12
gulpfile.js Normal file
View File

@ -0,0 +1,12 @@
const fs = require('fs');
const gulp = require('gulp');
const uglify = require('gulp-uglify');
const rename = require("gulp-rename");
gulp.task('mini', () => (
gulp.src('script/relationship.js')
.pipe(gulp.dest('dist/'))
.pipe(uglify()) //uglify
.pipe(rename("relationship.min.js"))
.pipe(gulp.dest('dist/'))
));

BIN
image/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
image/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
image/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
image/qrcode.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

171
index.html Normal file
View File

@ -0,0 +1,171 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>中国家庭称谓计算器</title>
<meta name="keywords" content="过年走亲访友,拜年神器,亲戚关系计算器,称呼计算器,关系算法">
<meta name="description" content="一款最全面的中国亲戚关系计算器,走亲访友,逢年过节必备神器,避免叫错、不会叫亲戚的尴尬,人人必备亲戚关系工具。">
<link rel="stylesheet" href="style/index.css">
</head>
<body>
<div class="wrapper">
<div class="container">
<div class="content">
<div class="mod-panel">
<div class="hd"><h1>中国家庭称谓计算器</h1></div>
<div class="bd">
<p>计算类型:
<label for="default"><input id="default" type="radio" name="type" value="default" checked>找称呼</label>
<label for="chain"><input id="chain" type="radio" name="type" value="chain">找关系</label>
</p>
<div class="group">
<p>我的性别:
<label for="male"><input id="male" type="radio" name="sex" value="1" checked></label>
<label for="female"><input id="female" type="radio" name="sex" value="0"></label>
</p>
<p>称呼方式:
<label for="call"><input id="call" type="radio" name="reverse" value="0" checked>我称呼对方</label>
<label for="called"><input id="called" type="radio" name="reverse" value="1">对方称呼我</label>
</p>
</div>
<p>
<textarea id="input" placeholder="称谓间用'的'字分开…"></textarea>
</p>
<p>
<span>快速选择:</span><br/>
<span>
<button class="btn" data-value="爸爸"></button>
<button class="btn" data-value="妈妈"></button>
</span>
<span>
<button class="btn" data-value="老公"></button>
<button class="btn" data-value="老婆"></button>
</span>
<span>
<button class="btn" data-value="儿子"></button>
<button class="btn" data-value="女儿"></button>
</span>
<span>
<button class="btn" data-value="哥哥"></button>
<button class="btn" data-value="弟弟"></button>
</span>
<span>
<button class="btn" data-value="姐姐"></button>
<button class="btn" data-value="妹妹"></button>
</span>
</p>
<p>
<button class="input-button">回退</button>
<button class="input-button">清空</button>
<button class="input-button">计算</button>
</p>
<p>计算结果:</p>
<p>
<textarea id="reslut" readonly></textarea>
</p>
</div>
<div class="ft">
<div class="copy">
<p><a class="github-button" href="https://github.com/mumuy" data-style="mega" data-count-href="/mumuy/followers" data-count-api="/users/mumuy#followers" data-count-aria-label="# followers on GitHub" aria-label="Follow @mumuy on GitHub">Follow @mumuy</a>
<a class="github-button" href="https://github.com/mumuy/relationship" data-style="mega" data-count-href="/mumuy/relationship/stargazers" data-count-api="/repos/mumuy/relationship#stargazers_count" data-count-aria-label="# stargazers on GitHub" aria-label="Star mumuy/relationship on GitHub">Star</a></p>
<p>android版下载<a href="http://passer-by.com/relationship/app.html" target="_blank">三姑六婆计算器</a></p>
<p>&copy; <a href="http://passer-by.com">passer-by.com</a></p>
</div>
</div>
</div>
<div class="mod-qrcode">
<div class="box"><img src="image/qrcode.jpg" width="150"/></div>
<p>微信扫一扫,使用小程序</p>
</div>
</div>
</div>
</div>
<script src="script/common.js"></script>
<script src="script/relationship.js"></script>
<script>
(function(){
var $type = document.getElementsByName('type');
var $sex = document.getElementsByName('sex');
var $reverse = document.getElementsByName('reverse');
var $radio = document.getElementsByTagName('INPUT');
var $textarea = document.getElementsByTagName('TEXTAREA');
var $group = DOMUtil.getElementsByClassName('group')[0];
var $btns = DOMUtil.getElementsByClassName('btn');
var $buttons = DOMUtil.getElementsByClassName('input-button');
var toggle = function(sex){
if(sex){ //男女判断
$btns[2].disabled=true;
$btns[3].disabled=false;
}else{
$btns[2].disabled=false;
$btns[3].disabled=true;
}
}
var count = function(){
var value = $textarea[0].value.trim();
if(value){
var sex = $sex[0].checked?1:0;
var type = $type[0].checked?'default':'chain';
var reverse = !$reverse[0].checked;
var result = relationship({text:value,sex:sex,reverse:reverse,type:type});
$textarea[1].value = '';
if(result.length){
$textarea[1].value = result.join('\n');
}else{
$textarea[1].value = '貌似他/她跟你不是很熟哦!';
}
}else{
$textarea[1].value = '';
}
}
for(var i=0;i<$btns.length;i++){
$btns[i].onclick = function(){
var value = $textarea[0].value.trim();
var name = this.getAttribute('data-value');
if(value){
$textarea[0].value= value+'的'+name;
}else{
$textarea[0].value= name;
}
toggle('爸爸,老公,儿子,哥哥,弟弟'.indexOf(name)>-1);
}
}
for(var i=0;i<$radio.length;i++){
$radio[i].onchange=function(){
toggle($sex[0].checked);
$group.style.display = $type[0].checked?'block':'none';
if($textarea[1].value){
count();
}
}
}
$buttons[0].onclick = function(){
var value = $textarea[0].value.trim();
var index = value.lastIndexOf('的');
index = Math.max(0,index);
var search = value.substr(0,index);
$textarea[0].value = search;
$textarea[1].value = '';
var name = search.split('的').pop();
if(!name){
toggle($sex[0].checked);
}else{
toggle('爸爸,老公,儿子,哥哥,弟弟'.indexOf(name)>-1);
}
}
$buttons[1].onclick = function(){
$textarea[1].value = $textarea[0].value = '';
toggle($sex[0].checked);
}
$buttons[2].onclick = count;
toggle($sex[0].checked);
})();
</script>
<script async defer src="https://buttons.github.io/buttons.js"></script>
<div style="display: none;">
<script src="http://s95.cnzz.com/z_stat.php?id=1258310068&web_id=1258310068"></script>
</div>
</body>
</html>

42
package.json Normal file
View File

@ -0,0 +1,42 @@
{
"name": "relationship.js",
"officialName": "relationship.js",
"version": "1.0.0",
"summary": "relationship.js is a javascript library for chinese family relationship. 中国家庭亲戚称谓计算器,家庭关系、亲戚关系算法。",
"description": "relationship.js is a javascript library for chinese family relationship.",
"author": {
"name": "mumuy",
"url": "http://passer-by.com/"
},
"license": "MIT",
"keywords": [
"relationship",
"relationship.js",
"chinese",
"family",
"relationship",
"家庭亲戚称谓",
"亲戚关系算法"
],
"main": "dist/relationship.min.js",
"repository": {
"type": "git",
"url": "https://github.com/mumuy/relationship"
},
"bugs": {
"url": "https://github.com/mumuy/relationship/issues"
},
"devDependencies": {
"gulp": "^3.9.0",
"gulp-uglify": "^1.5.3",
"gulp-rename": "^1.2.2",
"tape": "^3.6.1",
"pys": "^1.0.2"
},
"scripts": {
"test": "node tests/test.js",
"build": "gulp mini && npm run test"
},
"dependencies": {
}
}

96
readme.md Normal file
View File

@ -0,0 +1,96 @@
[![Build Status](https://travis-ci.org/mumuy/relationship.svg?branch=gh-pages)](https://travis-ci.org/mumuy/relationship/)
由于工作生活节奏不同,如今很多关系稍疏远的亲戚之间来往并不多。因此放假回家过年时,往往会搞不清楚哪位亲戚应该喊什么称呼,很是尴尬。然而搞不清亲戚关系和亲戚称谓的不仅是小孩,就连年轻一代的大人也都常常模糊混乱。
“中国家庭称谓计算器”为你避免了这种尴尬,只需简单的输入即可算出称谓。输入框兼容了不同的叫法,你可以称呼父亲为:“老爸”、“爹地”、“老爷子”等等,方面不同地域的习惯叫法。快捷输入按键,只需简单的点击即可完成关系输入,算法还支持逆向查找称呼哦~!
演示地址:[http://passer-by.com/relationship/](http://passer-by.com/relationship/ )
借助这套算法结合react native开发的APP: [http://passer-by.com/relationship/app.html](http://passer-by.com/relationship/app.html)
在微信中搜索“亲戚关系”,还可以体验小程序版本
![亲戚关系计算器](http://passer-by.com/relationship/image/qrcode.jpg)
## 一、下载 & 安装
该 Javascript 库 / 模块可以用于前端也可以用于后端 Nodejs 中。
1. 直接下载dist/relationship.min.js然后使用 `<script>`标签引入,可以得到全局的方法 `relationship`.
2. 使用 npm 进行包管理,具体为:
> **npm install relationship.js**
然后使用 `require` 引入模块
```js
var relationship = require("relationship.js");
```
## 二、使用
使用很简单,只有一个 API 方法 `relationship(options)`.
```js
var options = {text:'儿子的爸爸的妈妈',sex:1};
relationship(options);
```
另外,参数`options`结构为:
```js
var options = {
text:'', //输入的文本
sex:-1, //自己的性别0女性,1男性
type:'default', //转换类型:'default'算称谓,'chain'算关系(此时reverse无效)
reverse:false //称呼方式true对方称呼我,false我称呼对方
};
```
## 三、开发 & 贡献
```sh
# 安装开发依赖
npm install
# build 模块: 将 relationship 打包压缩
npm run build
# 执行测试用例可以在tests/test.js中完善测试用例
npm test
```
当然也可以直接浏览器打开 `index.html` 来在查看网页demo。
## 四、关于分歧
一些称呼存在南北方或地区差异,容易引起歧义,并不保证和你所处地区的称谓习惯一致。本程序主要以现代生活常见的理解为主。
* 媳妇:在古代或者当今北方地区指儿子的妻子,这里指自己的妻子。
* 大爷:北方指父亲的哥哥,这里指爷爷的哥哥
* 太太:一些地方指年长的妇人,这里指自己的妻子
## 五、其他
他们都在用:
查询网
http://ip138.com/
在线查询网
http://qinshu.supfree.net/
在线工具
http://atool.org/
有道语文达人
http://dict.youdao.com/k12yuwen/html/relation.html
小米MIUI系统计算器
http://www.miui.com/
小米MIUI网页版本
http://www.miui.com/zt/calculator2016/dist.php

95
script/common.js Normal file
View File

@ -0,0 +1,95 @@
if (typeof Array.prototype.indexOf != "function") {
Array.prototype.indexOf = function (searchElement, fromIndex) {
var index = -1;
fromIndex = fromIndex * 1 || 0;
for (var k = 0, length = this.length; k < length; k++) {
if (k >= fromIndex && this[k] === searchElement) {
index = k;
break;
}
}
return index;
};
}
if(!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g,'');
};
}
//跨浏览器DOM对象
var DOMUtil = {
getStyle:function(node,attr){
return node.currentStyle ? node.currentStyle[attr] : getComputedStyle(node,0)[attr];
},
getScroll:function(){ //获取滚动条的滚动距离
var scrollPos={};
if (window.pageYOffset||window.pageXOffset) {
scrollPos['top'] = window.pageYOffset;
scrollPos['left'] = window.pageXOffset;
}else if (document.compatMode && document.compatMode != 'BackCompat'){
scrollPos['top'] = document.documentElement.scrollTop;
scrollPos['left'] = document.documentElement.scrollLeft;
}else if(document.body){
scrollPos['top'] = document.body.scrollTop;
scrollPos['left'] = document.body.scrollLeft;
}
return scrollPos;
},
getClient:function(){ //获取浏览器的可视区域位置
var l,t,w,h;
l = document.documentElement.scrollLeft || document.body.scrollLeft;
t = document.documentElement.scrollTop || document.body.scrollTop;
w = document.documentElement.clientWidth;
h = document.documentElement.clientHeight;
return {'left':l,'top':t,'width':w,'height':h} ;
},
getNextElement:function(node){ //获取下一个节点
if(node.nextElementSibling){
return node.nextElementSibling;
}else{
var NextElementNode = node.nextSibling;
while(NextElementNode.nodeValue != null){
NextElementNode = NextElementNode.nextSibling
}
return NextElementNode;
}
},
getElementById:function(idName){
return document.getElementById(idName);
},
getElementsByClassName:function(className,context,tagName){ //根据class获取节点
if(typeof context == 'string'){
tagName = context;
context = document;
}else{
context = context || document;
tagName = tagName || '*';
}
if(context.getElementsByClassName){
return context.getElementsByClassName(className);
}
var nodes = context.getElementsByTagName(tagName);
var results= [];
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
var classNames = node.className.split(' ');
for (var j = 0; j < classNames.length; j++) {
if (classNames[j] == className) {
results.push(node);
break;
}
}
}
return results;
},
addClass:function(node,classname){ //对节点增加class
if(!new RegExp("(^|\s+)"+classname).test(node.className)){
node.className = (node.className+" "+classname).replace(/^\s+|\s+$/g,'');
}
},
removeClass:function(node,classname){ //对节点删除class
node.className = (node.className.replace(classname,"")).replace(/^\s+|\s+$/g,'');
}
};

1138
script/relationship.js Normal file

File diff suppressed because it is too large Load Diff

60
style/app.css Normal file
View File

@ -0,0 +1,60 @@
html{color:#000;background:#FFF}body,div,dl,dt,dd,ul,ol,li,h1,h3,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h3,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;*font-size:100%}legend{color:#000}
html{
height:100%;
}
body{
height: 100%;
font-size: 14px;
font-family: Arial,Helvetica,"Microsoft Yahei";
background: #fdfdfd;
color:#757575;
}
a{
color:#333;
text-decoration: none;
}
a:hover{
text-decoration: underline;
}
.container{
width:640px;
margin:0 auto;
}
.mod-app{
height: 72px;
padding-top: 100px;
margin-bottom: 25px;
}
.mod-app .icon{
float:left;
width: 72px;
height: 72px;
}
.mod-app .info{
margin-left: 90px;
line-height: 28px;
}
.mod-view{
padding:20px 15px;
background: #f8f8f8;
}
.mod-view img{
height: 300px;
margin-right: 10px;
}
.mod-qrcode{
position: fixed;
right: 25px;
bottom: 25px;
text-align: center;
}
.mod-qrcode .box{
width: 150px;
height: 148px;
overflow: hidden;
}
.mod-qrcode p{
line-height: 30px;
}

121
style/index.css Normal file
View File

@ -0,0 +1,121 @@
html{color:#000;background:#FFF}body,div,dl,dt,dd,ul,ol,li,h1,h3,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}ol,ul{list-style:none}caption,th{text-align:left}h1,h3,h3,h4,h5,h6{font-size:100%;font-weight:normal}q:before,q:after{content:''}abbr,acronym{border:0;font-variant:normal}sup{vertical-align:text-top}sub{vertical-align:text-bottom}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;*font-size:100%}legend{color:#000}
html{
height:100%;
}
body{
height: 100%;
font-size: 14px;
font-family: Arial,Helvetica,"Microsoft Yahei";
background: #fdfdfd;
color:#757575;
}
button, input {
font-family: Arial,Helvetica,"Microsoft Yahei";
}
img{
vertical-align: middle;
}
a{
text-decoration: none;
color: #757575;
}
a:hover{
text-decoration: underline;
}
.mod-panel {
width: 100%;
max-width: 740px;
margin: 0 auto 30px;
_width: 740px;
}
.mod-panel .hd{
padding-top: 25px;
margin-bottom: 30px;
line-height: 30px;
text-align: center;
}
.mod-panel .hd h1{
font-size: 24px;
color:#212121;
}
.mod-panel .bd{
width: 500px;
margin:0 auto 20px;
}
.mod-panel .bd p{
line-height: 30px;
}
.mod-panel .input-text{
width: 60px;
height: 20px;
margin-right:20px;
border: 1px solid #ebebeb;
padding: 4px 8px;
line-height: 20px;
outline: none;
}
.mod-panel .input-button {
height: 30px;
width: 80px;
margin: 15px 10px 0 0;
background: #4bae4f;
border: medium none;
line-height: 30px;
vertical-align: middle;
font-size: 16px;
color: #fff;
cursor: pointer;
outline: none;
}
.mod-panel label,.mod-panel p span{
margin-right:10px;
}
.mod-panel .btn{
width: 36px;
cursor: pointer;
}
.mod-panel textarea{
display: block;
width: 90%;
height: 150px;
padding:5px 10px;
border: 1px solid #ebebeb;
resize: none;
outline: none;
}
.mod-panel .ft{
padding-top: 20px;
border-top:1px dotted #e0e0e0;
}
.mod-panel .about{
padding: 0 20px;
margin-bottom: 20px;
}
.mod-panel .about p{
line-height: 24px;
text-indent: 2em;
}
.mod-panel .copy{
padding: 0 20px;
margin-bottom: 20px;
text-align: center;
}
.mod-panel .copy p{
line-height: 24px;
}
.mod-qrcode{
position: fixed;
right: 25px;
bottom: 25px;
text-align: center;
}
.mod-qrcode .box{
width: 150px;
height: 148px;
overflow: hidden;
}
.mod-qrcode p{
line-height: 30px;
}

21
tests/test.js Normal file
View File

@ -0,0 +1,21 @@
'use strict';
var test = require('tape');
var relationship = require('..');
test('relationship.js show to be tested', function (t) {
// TODO
t.deepEqual(relationship({text:'儿子的爸爸的妈妈',sex:1}),['妈妈']);
t.deepEqual(relationship({text:'爱人',sex:1}),['老婆']);
t.deepEqual(relationship({text:'爱人的爱人',sex:1}),['自己']);
t.deepEqual(relationship({text:'老婆的爱人',sex:1}),['自己']);
t.deepEqual(relationship({text:'老婆的老公',sex:1}),['自己']);
t.deepEqual(relationship({text:'老婆的外孙的姥爷',sex:1}),['自己']);
t.deepEqual(relationship({text:'表姐的哥哥',sex:1}),['姑表哥','舅表哥','姨表哥']);
t.deepEqual(relationship({text:'表姐的妹妹',sex:1}),['姑表姐','姑表妹','舅表姐','舅表妹','姨表姐','姨表妹']);
t.deepEqual(relationship({text:'老公的老婆的儿子的爸爸',sex:0}),['老公']);
t.deepEqual(relationship({text:'哥哥的弟弟的爸爸的儿子',sex:1}),['兄弟','自己']);
t.deepEqual(relationship({text:'爸爸的舅舅',sex:0,reverse:true}),['外甥孙女']);
t.deepEqual(relationship({text:'舅爷爷',type:'chain'}),['爸爸的妈妈的兄弟']);
t.end();
});