selection length | 选中计字数

鼠标拖选显示选中字数

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        selection length | 选中计字数
// @namespace   hzhbest
// @description    鼠标拖选显示选中字数
// @include     https://*
// @include     http://*
// @version     1.3
// @grant       none
// ==/UserScript==

(function() {
	
	// CONFIG
	var _use_alt = true; // true-必须按住Alt才显示;false-直接显示。
	// CONFIG
	
	document.addEventListener('mouseup', function(e) {
		if (!_use_alt || e.altKey) setTimeout(function(){count(e);},150);
	}, false);

	var tooltip = creaElemIn('div', document.body);
	tooltip.id = "sl_tooltip";	
	var timer, content, overed = false;
	var timeout = 1000;
	
	// Insert CSS
	var headID = document.getElementsByTagName('head')[0];         
	var cssNode = creaElemIn('style', headID);
	cssNode.type = 'text/css';
	cssNode.innerHTML = `
	#sl_tooltip {
		display: none;
		position: fixed;
		z-index: 999999;
		font-size: 12pt;
		background: white;
		border: 1px solid #eee;
		box-shadow: 0 1px 12px #3332;
	}

	#sl_tooltip.show {
		display: block;
	  padding: 0.2em 0.3em;
	  border-radius:0.3em;
	}

	#sl_tooltip table {
		line-height: 15 pt;
		border-collapse: collapse;
		border-spacing: 0;
		font-size: 10pt;
	}

	#sl_tooltip .subT{
		border-top: 0.4em solid white;
	}`;


function count(e) {
	if (overed) return;
	var ae = document.activeElement; //console.log(ae.value + "|" + ae.selectionStart + "|" + ae.selectionEnd);
	if (ae.tagName.toLowerCase() == "input" || ae.tagName.toLowerCase() == "textarea") {
		content = ae.value.substring(ae.selectionStart, ae.selectionEnd);
	} else {
		content = getSelection().toString();
	}
	var selCount = content.length;
	if (selCount == 0) return;
		//借用一字数统计脚本代码
			var cvalue=content.replace(/\r\n/g,"\n");
			var sarr=cvalue.split("");
			var len_total=sarr.length;
			var r={
				"wd":0,  //中英文字数
				"nwd":0, //英数词数
				"kwd":0, //日文假名
				"krd":0, //韩文字
				"nb":0,  //数字词数
				"c":0,   //字符数
				"cb":0,  //非空格字符
				"r":0,   //回车
				"en":0,  //英文字母数
				"cn":0,  //中文字数
				"bl":0   //非回车空格
			};
			var words=cvalue.match(/\w+([’\']\w+)?/g)||[];    //含撇号(如I'm)的单词视为一个词
			var numbers=cvalue.match(/\b\d+(\.\d+)?\b/g)||[];  //含小数点的数字视为一个词
			var cnwords=cvalue.match(/[\u4e00-\u9fa5]/g)||[];  //统一中文字范围
			var kanawds=cvalue.match(/[\u3040-\u30ff]/g)||[];  //日文假名范围
			var krwords=cvalue.match(/[\uac00-\ud7af]/g)||[];  //韩文字范围
			r.nwd=words.length;
			r.nb=numbers.length;
			r.cn=cnwords.length;
			r.kwd=kanawds.length;
			r.krd=krwords.length;
			for(var i=0;i<len_total;i++){
				r.c++;
				switch(true){
					case /[a-zA-Z]/.test(sarr[i]):
						r.en++;
						break;
					case /\S/.test(sarr[i]):
						r.cb++;
						break;
					case /\s/.test(sarr[i]):
						if(sarr[i]=="\n"||sarr[i]=="\r"){
							r.r++;
						}else{
							r.bl++;
						}
				}
			}
			r.wd=r.nwd+r.cn+r.kwd+r.krd;
			var str="字符统计<br/>";
			str+="<table border='0' cellpadding='0' cellspacing='0' width='100%'>";
			str+="<tr class='subT'><td algin='left'>总字符数:</td><td align='right'> "+(r.c-r.r)+"</td></tr>";
			// str+="<tr><td algin='left'>非空白总字符数:</td><td align='right'>"+(r.c-r.bl-r.r)+"</td></tr>";
			str+="<tr><td algin='left'> 空白字符:</td><td align='right'> "+r.bl+"</td></tr>";
			str+="<tr><td algin='left'> 英文字符:</td><td align='right'> "+r.en+"</td></tr>";
			str+="<tr><td algin='left'> 其它字符:</td><td align='right'> "+(r.c-r.en-r.bl-r.cn-r.r)+"</td></tr>";
			// str+="<tr><td algin='left'>&nbsp;</td><td align='right'>&nbsp;</td></tr>";
			str+="<tr class='subT'><td algin='left'>总字词数:</td><td align='right'> "+r.wd+"</td></tr>";
			if(r.cn > 0)	str+="<tr><td algin='left'> 中文字:</td><td align='right'> "+r.cn+"</td></tr>";
			if(r.kwd > 0)	str+="<tr><td algin='left'> 日文假名:</td><td align='right'> "+r.kwd+"</td></tr>";
			if(r.krd > 0)	str+="<tr><td algin='left'> 韩文字:</td><td align='right'> "+r.krd+"</td></tr>";
			if(r.nwd-r.nb > 0)str+="<tr><td algin='left'> 英文单词:</td><td align='right'> "+(r.nwd-r.nb)+"</td></tr>";
			if(r.nb > 0)	str+="<tr><td algin='left'> 阿拉伯数字:</td><td align='right'> "+r.nb+"</td></tr>";
			// str+="<tr><td algin='left'>&nbsp;</td><td align='right'>&nbsp;</td></tr>";
			str+="<tr class='subT'><td algin='left'>回行数:</td><td align='right'> "+(r.r+1)+"</td></tr>";
			str+="</table>";
	tooltip.innerHTML = str;
	// tooltip.innerHTML = getSelection().toString();  //for debug
	tooltip.className = "show";
	tooltip.style.top = Math.min(e.clientY + 10, window.innerHeight - tooltip.offsetHeight - 10) + "px";
	tooltip.style.left = Math.min(e.clientX + 20, window.innerWidth - 150) + "px";
	
	function hide(){
		tooltip.className = '';
		tooltip.removeEventListener('mouseover', over, false);
		tooltip.removeEventListener('mouseout', out, false);
	}
	function over() {
		overed = true;
		clearTimeout(timer);
	}
	function out() {
		overed = false;
		timer = setTimeout(hide, timeout);
	}
	tooltip.addEventListener('mouseover', over, false);
	tooltip.addEventListener('mouseout', out, false);
	timer = setTimeout(hide, timeout * 3);
}


// Create an element
function creaElemIn(tagname, destin) {
	var theElem = destin.appendChild(document.createElement(tagname));
	return theElem;
}


})();