Merge branch 'master' into gh-pages

This commit is contained in:
郑浩乐 2016-03-16 15:04:46 +08:00
commit 722726aef8
4 changed files with 738 additions and 0 deletions

107
index.html Normal file
View File

@ -0,0 +1,107 @@
<!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>关系:</p>
<p>
<textarea id="input" placeholder="注意:人物间用'的'字分开…"></textarea>
</p>
<p>
<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="about">
<p>由于工作生活节奏不同,如今很多关系稍疏远的亲戚之间来往并不多。因此放假回家过年时,往往会搞不清楚哪位亲戚应该喊什么称呼,很是尴尬。然而搞不清亲戚关系和亲戚称谓的不仅是小孩,就连年轻一代的大人也都常常模糊混乱。</p>
<p>“中国家庭称谓计算器”为你避免了这种尴尬,只需简单的输入即可算出称谓。输入框兼容了不同的叫法,你可以称呼父亲为:“老爸”、“爹地”、“老爷子”等等,方面不同地域的习惯叫法。快捷输入按键,只需简单的点击即可完成关系输入。</p>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="script/common.js"></script>
<script src="script/relationship.js"></script>
<script>
var $textarea = document.getElementsByTagName('TEXTAREA');
var $btns = DOMUtil.getElementsByClassName('btn');
var $buttons = DOMUtil.getElementsByClassName('input-button');
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;
}
}
}
$buttons[0].onclick = function(){
var value = $textarea[0].value.trim();
var result = relationship(value);
$textarea[1].value = '';
if(result.length){
for(var i=0;i<result.length;i++){
$textarea[1].value += result[i]+'\n';
}
}else{
$textarea[1].value = '貌似他/她跟你不是很熟哦!';
}
}
$buttons[1].onclick = function(){
var value = $textarea[0].value.trim();
var index = value.lastIndexOf('的');
index = Math.max(0,index);
$textarea[0].value = value.substr(0,index);
}
$buttons[2].onclick = function(){
$textarea[0].value = '';
}
</script>
</body>
</html>

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,'');
}
};

437
script/relationship.js Normal file
View File

@ -0,0 +1,437 @@
(function(window){
//简写
var _filter = [
{//自己是女性,女儿或儿子的妈妈是自己
exp:/(,[mwd]|([olx]s)),[ds](&[ol])?,m/g,
str:'$1'
},
{//自己是女性,女儿或儿子的爸爸是自己的丈夫
exp:/(,[mwd]|([olx]s)),[ds](&[ol])?,f/g,
str:'$1,h'
},
{//自己是男性,女儿或儿子的爸爸是自己
exp:/(,[fhs]|([olx]b)),[ds](&[ol])?,f/g,
str:'$1'
},
{//自己是男性,女儿或儿子的妈妈是自己的妻子
exp:/(,[fhs]|([olx]b)),[ds](&[ol])?,m/g,
str:'$1,w'
},
{//夫妻的孩子就是自己的孩子
exp:/,[wh],([ds])/g,
str:',$1'
},
{//夫妻的对方是自己
exp:/(,w,h)|(,h,w)/g,
str:''
},
{//兄弟的父母就是自己的父母
exp:/[xol][sb],([mf])/g,
str:'$1'
},
{//母亲的丈夫是自己的父亲
exp:/m,h/g,
str:'f',
},
{//父亲的妻子是自己的母亲
exp:/f,w/g,
str:'m',
},
{//孩子的姐妹是自己的女儿
exp:/,[ds](&[ol])?,[olx]s/g,
str:',d',
},
{//孩子的兄弟是自己的儿子
exp:/,[ds](&[ol])?,[olx]b/g,
str:',s',
},
{//如果自己是男性,兄弟姐妹的兄弟就是自己的兄弟或自己
con:/(,[fhs]|([olx]b)),[olx][sb],[olx]b/,
exp:/^(.+),[olx][sb],[olx]b(.+)$/,
str:'$1,xb$2#$1$2',
},
{//如果自己是女性,兄弟姐妹的兄弟就是自己的兄弟
con:/(,[mwd]|([olx]s)),[olx][sb],[olx]b/,
exp:/,[olx][sb],[olx]b/,
str:',xb',
},
{//如果自己是男性,兄弟姐妹的姐妹就是自己的姐妹
con:/(,[fhs]|([olx]b)),[olx][sb],[olx]s/,
exp:/,[olx][sb],[olx]s/,
str:',xs',
},
{//如果自己是女性,兄弟姐妹的姐妹就是自己的姐妹或自己
con:/(,[mwd]|([olx]s)),[olx][sb],[olx]s/,
exp:/^(.+),[olx][sb],[olx]s(.+)$/,
str:'$1,xs$2#$1$2',
},
{//如果自己是男性,父母的儿子是自己或者兄弟
con:/(,[fhs]|([olx]b)),[mf],s/,
exp:/^(.+),[mf],s(.+)$/,
str:'$1$2#$1,xb$2'
},
{//如果自己是女性,父母的女儿是自己或者姐妹
con:/(,[mwd]|([olx]s)),[mf],d/,
exp:/^(.+),[mf],d(.+)$/,
str:'$1$2#$1,xs$2'
},
{//如果自己是女性,父母的儿子是自己或者兄弟
con:/(,[mwd]|([olx]s)),[mf],s/,
exp:/,[mf],s/,
str:',xb'
},
{//如果自己是男性,父母的女儿是自己或者姐妹
con:/(,[fhs]|([olx]b)),[mf],d/,
exp:/,[mf],d/,
str:',xs'
},
{//父母的女儿是姐妹
exp:/^,[mf],s$/,
str:',#,xb'
},
{//父母的女儿是自己或者姐妹
exp:/^,[mf],d$/,
str:',#,xs'
}
];
var _data = {
'':['自己'],
//外家
'm,m':['外婆','姥姥'],
'm,f':['外公','姥爷'],
'm,m,m':['太姥姥'],
'm,m,m,h':['太姥爷'],
'm,m,xs':['姨姥姥'],
'm,m,xs,w':['姨姥爷'],
'm,m,xb':['舅姥爷'],
'm,m,xb,w':['舅姥姥'],
'm,f,m':['太姥姥'],
'm,f,m,h':['太姥爷'],
'm,f,xs':['姑姥姥'],
'm,f,xs,h':['姑姥爷'],
'm,f,xs,s':['表舅'],
'm,f,xb':['xx姥爷'],
'm,f,ob':['大姥爷'],
'm,f,lb':['小姥爷'],
//舅家
'm,xb':['舅舅','舅'],
'm,xb,w':['舅妈','舅母'],
'm,xb,s&o':['表哥(舅家)','表哥'],
'm,xb,s&o,w':['表嫂(舅家)','表嫂'],
'm,xb,s&l':['表弟(舅家)','表弟'],
'm,xb,s&l,w':['表弟媳(舅家)','表弟媳'],
'm,xb,s,s':['表侄子'],
'm,xb,s,d':['表侄女'],
'm,xb,d&o':['表姐(舅家)','表姐'],
'm,xb,d&o,h':['表姐夫(舅家)','表姐夫'],
'm,xb,d&l':['表妹(舅家)','表妹'],
'm,xb,d&l,h':['表妹夫(舅家)','表妹夫'],
'm,xb,d,s':['表外甥'],
'm,xb,d,d':['表外甥女'],
'm,ob':['大舅'],
'm,ob,w':['大舅妈'],
'm,lb':['小舅'],
'm,lb,w':['小舅妈'],
//姨家
'm,xs':['姨妈','姨姨','姨'],
'm,xs,h':['姨父','姨丈'],
'm,xs,s&o':['表哥(姨家)','表哥'],
'm,xs,s&o,w':['表嫂(姨家)','表嫂'],
'm,xs,s&l':['表弟(姨家)','表弟'],
'm,xs,s&l,w':['表弟媳(姨家)','表弟媳'],
'm,xs,s,s':['表侄子'],
'm,xs,s,d':['表侄女'],
'm,xs,d&o':['表姐(姨家)','表姐'],
'm,xs,d&o,h':['表姐夫(姨家)','表姐夫'],
'm,xs,d&l':['表妹(姨家)','表妹'],
'm,xs,d&l,h':['表妹夫(姨家)','表妹夫'],
'm,xs,d,s':['表外甥'],
'm,xs,d,d':['表外甥女'],
'm,os':['大姨','大姨妈'],
'm,os,h':['大姨父','大姨丈','大姨夫'],
'm,ls':['小姨','小姨妈'],
'm,ls,h':['小姨父','小姨丈','小姨夫'],
//姑家
'f,xs':['姑妈','姑姑','姑'],
'f,xs,h':['姑父','姑丈'],
'f,xs,s&o':['表哥(姑家)','表哥'],
'f,xs,s&o,w':['表嫂(姑家)','表嫂'],
'f,xs,s&l':['表弟(姑家)','表弟'],
'f,xs,s&l,w':['表弟媳(姑家)','表弟媳'],
'f,xs,s,s':['表侄子'],
'f,xs,s,d':['表侄女'],
'f,xs,d&o':['表姐(姑家)','表姐'],
'f,xs,d&o,h':['表姐夫(姑家)','表姐夫'],
'f,xs,d&l':['表妹(姑家)','表妹'],
'f,xs,d&l,h':['表妹夫(姑家)','表妹夫'],
'f,xs,d,s':['表外甥'],
'f,xs,d,d':['表外甥女'],
'f,os':['姑母'],
'f,ls':['姑姐'],
//本家
'f,xb,s&o':['堂哥'],
'f,xb,s&o,w':['堂嫂'],
'f,xb,s&l':['堂弟'],
'f,xb,s&l,w':['堂弟媳'],
'f,xb,s,s':['堂侄子'],
'f,xb,s,d':['堂侄女'],
'f,xb,d&o':['堂姐'],
'f,xb,d&o,h':['堂姐夫'],
'f,xb,d&l':['堂妹'],
'f,xb,d&l,h':['堂妹夫'],
'f,xb,d,s':['表外甥'],
'f,xb,d,d':['表外甥女'],
'f,ob':['伯父','伯伯','大伯'],
'f,ob,w':['伯母','大娘'],
'f,lb':['叔叔','叔父','叔'],
'f,lb,w':['婶婶','婶'],
//岳家
'w,m':['岳母','丈母娘'],
'w,f':['岳父','老丈人','丈人'],
'w,ob':['大舅哥','大舅子','内兄'],
'w,ob,w':['嫂子','大妗子'],
'w,lb':['小舅子','内弟'],
'w,lb,w':['弟媳妇','小妗子'],
'w,os':['大姨姐','妻姐'],
'w,os,h':['大姨夫'],
'w,ls':['小姨姐','妻妹'],
'w,ls,h':['小姨夫'],
//婆家
'h,m':['婆婆'],
'h,f':['公公'],
'h,ob':['大伯子'],
'h,ob,w':['大婶子','大伯娘','大嫂'],
'h,ob,s':['侄子'],
'h,ob,d':['侄女'],
'h,lb':['小叔子'],
'h,lb,w':['小婶子'],
'h,lb,s':['侄子'],
'h,lb,d':['侄女'],
'h,os':['大姑子','大姑'],
'h,os,s':['外甥'],
'h,os,d':['外甥女'],
'h,os,h':['大姑夫','姊丈'],
'h,ls':['小姑子','小姑'],
'h,ls,h':['小姑夫'],
'h,ls,s':['外甥'],
'h,ls,d':['外甥女'],
//内家
'f,f,f,f':['高祖父'],
'f,f,f,m':['高祖母'],
'f,f,f':['曾祖父'],
'f,f,m':['曾祖母'],
'f,m':['奶奶','祖母'],
'f,f':['爷爷','祖父'],
'f,f,f':['太爷爷'],
'f,f,m':['太奶奶'],
'f,f,ob':['大爷爷'],
'f,f,ob,w':['大奶奶'],
'f,f,lb':['小爷爷'],
'f,f,lb,w':['小奶奶'],
'f,f,xs':['姑奶奶'],
'f,f,xs,h':['姑爷爷'],
'f,m':['奶奶','祖母'],
'f,m,f':['太爷爷'],
'f,m,m':['太奶奶'],
'f,m,xs':['姨爷爷','姨爷'],
'f,m,xs,h':['姨奶奶'],
'f,m,xb':['舅爷爷','舅爷'],
'f,m,xb,w':['舅奶奶'],
//自家
'm':['妈妈','母亲','老妈','老母','娘','娘亲','妈咪'],
'f':['爸爸','父亲','老爸','老豆','爹','爹地','老爷子'],
'w':['老婆','妻子','太太','女人','贱内','婆娘','妻','爱人'],
'h':['老公','丈夫','先生','男人','夫','爱人'],
's':['儿子'],
's,w':['儿媳妇'],
's,s':['孙子'],
's,s,w':['孙媳妇'],
's,s,s':['曾孙'],
's,s,s,s':['玄孙'],
's,s,d':['曾孙女'],
's,d':['孙女'],
's,d,h':['孙女婿'],
'd':['女儿','千金'],
'd,h':['女婿'],
'd,s':['外孙'],
'd,s,w':['外孙媳'],
'd,d':['外孙女'],
'd,d,h':['外孙女婿'],
//旁支
'xb':['兄弟'],
'xs':['姐妹'],
'ob':['哥哥','兄'],
'ob,w':['嫂子','嫂'],
'ob,s':['侄子'],
'ob,s,w':['侄媳妇'],
'ob,d':['侄女'],
'ob,d,h':['侄女婿'],
'lb':['弟弟','第'],
'lb,w':['弟妹'],
'lb,s':['侄子'],
'lb,s,w':['侄媳妇'],
'lb,d':['侄女'],
'lb,d,h':['侄女婿'],
'os':['姐姐','姐'],
'os,h':['姐夫'],
'os,s':['外甥'],
'os,d':['外甥女'],
'ls':['妹妹','妹'],
'ls,h':['妹夫'],
'ls,s':['外甥'],
'ls,d':['外甥女'],
//其他
's,w,m':['亲家母'],
's,w,f':['亲家公'],
'd,h,m':['亲家母'],
'd,h,f':['亲家公'],
};
//数组去重
var unique = function(arr) {
var result = [], hash = {};
for (var i = 0, elem; (elem = arr[i]) != null; i++) {
if (!hash[elem]) {
result.push(elem);
hash[elem] = true;
}
}
return result;
};
var _attr = '';
//分词解析
function getSelectors(str){
var lists = str.split('的');
var result = []; //所有可能性
while(lists.length){
var name = lists.shift(); //当前匹配词
var arr = []; //当前匹配词可能性
for(var i in _data){
var value = _data[i];
if(value.indexOf(name)>-1){ //是否存在该关系
arr.push(i);
}
}
if(result.length){ //当前匹配词与之前可能性组合
var res = [];
for(var i=0;i<result.length;i++){
for(var j=0;j<arr.length;j++){
res.push(result[i] +','+arr[j]);
}
}
result = res;
}else{
for(var i=0;i<arr.length;i++){
result.push(','+arr[i]);
}
}
}
if(result.length){ //对年龄进行智能过滤
var item = result[0];
var o = item.match(/(&o)|o[sb]/);
var l = item.match(/(&l)|l[sb]/);
if(o&&l){
var filter = /&[ol]/g;
for(var i=0;i<result.length;i++){
result[i]=result[i].replace(filter,'');
}
}else if(o&&!l){
_attr = '&o';
}else if(!o&&l){
_attr = '&l';
}
}
return result;
}
//简化选择器
function selector2id(selector){
var result = [];
var getId = function(selector){
var s;
do{
s = selector;
for(var i in _filter){
var item = _filter[i];
if(item['con']){
if(selector.match(item['con'])){
selector = selector.replace(item['exp'],item['str']);
}
}else{
selector = selector.replace(item['exp'],item['str']);
}
}
}while(s!=selector);
if(selector.indexOf('#')>-1){
var arr = selector.split('#');
for(var i=0;i<arr.length;i++){
getId(arr[i]);
}
}else{
selector = selector.substr(1); //去前面逗号
if(selector.match(/,[ds]$/)&&_attr){
selector += _attr;
}
result.push(selector);
}
}
getId(selector);
return result;
}
//获取数据
function getDataById(id){
var result = [];
var filter = /&[olx]/g; //忽略属性查找数据
for(var i in _data){
if(i.replace(filter,'')==id){
result.push(_data[i]);
}
}
return result;
}
function relationship(str){
var selectors = getSelectors(str);
console.log(selectors);
var result = []; //匹配结果
for(var i = 0;i<selectors.length;i++){ //遍历所有可能性
var ids = selector2id(selectors[i]);
for(var j=0;j<ids.length;j++){
var id = ids[j];
if(_data[id]){ //直接匹配称呼
result.push(_data[id][0]);
}else{ //高级查找
var data = getDataById(id); //忽略属性查找
if(!data.length){ //当无精确数据时,忽略年龄条件查找
id = id.replace(/&[ol]/,'');
data = getDataById(id);
}
if(!data.length){
id = id.replace(/[ol]/g,'x');
data = getDataById(id);
}
if(!data.length){
var l = id.replace(/x/g,'l');
data = getDataById(l);
var o = id.replace(/x/g,'o');
data = data.concat(getDataById(o));
}
for(var d=0;d<data.length;d++){
result.push(data[d][0]);
}
}
}
}
return unique(result);
}
window.relationship = relationship;
})(window);
console.log(relationship('外婆的外孙'));

99
style/index.css Normal file
View File

@ -0,0 +1,99 @@
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 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;
}