简介
最近接触了一个项目需要实现,类似于bing中的画词翻译功能,于是自己手写实现了一个,拿出来和大家分享,有什么问题欢迎各位大牛指导
要点
1.得到画词的内容,我使用的是jQuery
我设置的是Mouseup 触该事件
let closeFanyi = false;
// NOTE 翻译功能
const fanyiFn = function (e) {
const text = window.getSelection().toString();
let $fanyiPanel = $body.find('.fanyi-panel');
};
// NOTE 监听i.fanyi的mouseover mouseout
$body.on('mouseup', '.fanyi', (e) => {
if (closeFanyi) {
return;
}
fanyiFn(e);
});
2.隐藏面板
一下几点需要注意
- 1.如果没有面板就创建一个
- 2.如果有就在上面更改内容
- 3.点击外面就关闭面板
- 4.用完记得把点击事件取消掉
// NOTE 隐藏面板
var hidePanelFun = function (e) {
e.stopPropagation();
// NOTE 如果点击面板内部 则不会消失
if ($fanyiPanel.get(0).contains(e.target)) {
return;
}
$fanyiPanel.hide();
document.removeEventListener('mousedown', hidePanelFun);
};
// NOTE 如果没有就创建
if (!$fanyiPanel.length) {
// NOTE 创建fanyipanel
$fanyiPanel = $('<div class="fanyi-panel"><div class="header"><p class="title"></p><div class="content">翻译无结果</div></div><div class="footer"> <a href="javascript:void(0);" class="close">关闭取词</a></div></div>').appendTo($body);
// NOTE 取消取词功能
$fanyiPanel.find('.close').click((e) => {
e.stopPropagation();
closeFanyi = true;
$body.find('.fanyi-panel').hide();
});
}
// NOTE 如果没有选择则关闭面板
if (!text) {
$fanyiPanel.hide();
document.removeEventListener('mousedown', hidePanelFun);
return;
}
3. 计算位置
- 因为弹出的面板会有被遮挡的情况,所以需要计算位置
// NOTE 计算Position的位置取到底部
const position = {
left: e.pageX,
top: e.pageY + lineHeight / 2,
};
// NOTE 如果文字距离底部的距离小于panel的宽度
if ((position.top + panelHeight) > bodyHeight) {
position.top = position.top - lineHeight - panelHeight;
}
// NOTE 判断右边的距离是否够panel的宽度
if ((position.left + panelWidth) > bodyWidth) {
position.left -= panelWidth;
}
// NOTE 先固定好位置
$fanyiPanel.find('.title').text('');
$fanyiPanel.find('.content').text('翻译中请稍后。。。。');
$fanyiPanel.show();
$fanyiPanel.css({ left: position.left, top: position.top });
// NOTE 这延迟debounce处理
fanyiRequestFnDebounce($fanyiPanel, text);
// NOTE 捕获的时候识别点击
document.addEventListener('mousedown', hidePanelFun, false);
};
4.节流的发动请求
为了避免过于频繁的请求 所以必须我自己写了一个节流函数debounce, 这是一个简单的函数,也可以使用Lodash的
function debounce(fn, wait) {
let timer = null;
return function () {
const context = this;
const args = arguments;
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context, args);
}, wait);
};
}
// 把结果输入到面板上面
const url ///自己定义服务器的地址
var fanyiRequestFnDebounce = debounce(($fanyiPanel, text) => {
httpRequest.start({
url: '',
form: {
q: text,
},
}, (ret) => {
$fanyiPanel.find('.title').text(text);
$fanyiPanel.find('.content').text(ret.Result.translatedText);
}, true, url);
}, 500);
关于翻译的面板样式我就不在这些了 自己随便定义, 技术有限。欢迎大家多多指点