hzhbest
千年狐狸
千年狐狸
  • UID22640
  • 注册日期2008-01-15
  • 最后登录2017-04-06
  • 发帖数1763
  • 经验476枚
  • 威望3点
  • 贡献值414点
  • 好评度89点
  • 社区居民
  • 忠实会员
阅读:1622回复:14

【发布】字数统计脚本

楼主#
更多 发布于:2015-07-02 16:04
selection length | 选中计字数
https://greasyfork.org/zh-CN/scripts/10763-selection-length-选中计字数
只要按住Alt键用鼠标选中一些文字,一个小提示就会弹出显示选中的各类字符数,给你一个非常清晰的字数统计结果。
*注:如果想暂时保留统计结果,可在其弹出后将鼠标移到其上。
**高级用户:如果需要恢复旧版的不需按住Alt键就可显示选中字数,可将代码14行的_use_alt变量设为false。

20150730 更新 v1.2版,要按住Alt键才计数等。
20150723 更新 v1.1版,基本上把大家想要的功能都加进去,局限性都消除了,
本来还想设计个鼠标不动提示就不消失,鼠标移动远了就自动消失的设计,但是mousemove事件会不断干扰mouseup的响应,最后还是放弃了;不过现在的消失机制还是满不错的哦
其实我在想,为什么就没人设计个这么普通的脚本出来呢?

↓↓↓↓↓↓↓↓↓↓↓↓↓↓以下为旧内容,完全可跳过不看↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
脚本的作用是,用鼠标选中一段文本之后,直接显示一个小提示表示当前选中的字数,小提示会在3秒后自动消去。注意,必须是鼠标

首先贴上脚本代码:
// ==UserScript==
// @name        selection length
// @namespace   hzhbest
// @include     https://*
// @include     http://*
// @version     1
// @grant       none
// ==/UserScript==
     
(function() {
     
    document.addEventListener("click", function(event) {
        count(event);
    }, false);
         
    var tooltip =  creaElemIn('div', document.body);
    tooltip.id = "sl_tooltip";  
    var timer;
         
    // 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; font-size: 16pt; background: white; border: 1px solid #ddecff;} #sl_tooltip.show{display: block;}';
     
     
function count(e) {
    var selCount = String(document.getSelection()).length;
    if (selCount == 0) return;
    tooltip.innerHTML = selCount + "字";
    tooltip.className = 'show';
    clearTimeout(timer);
    timer = setTimeout(function(){tooltip.className = '';},3000);
    tooltip.style.top = e.clientY + 10 + "px";
    tooltip.style.left = e.clientX + 20 + "px";
}
     
     
// Create an element
function creaElemIn(tagname, destin) {
    var theElem = destin.appendChild(document.createElement(tagname));
    return theElem;
}
     
     
})();

然后是示例网址:
https://zh.wikipedia.org/wiki/%E7%B4%85%E5%B7%A8%E6%98%9F

在示例网页中,
选中一个段落中的部分文字,不管选择区是否包含了里面的链接 → 正常显示字数
选中整个段落 → 正常显示字数
选择区跨了两个段落 → 无法显示
选中了标题和段落 → 无法显示
纯鼠标选中链接中部分文字 → 无法显示
纯鼠标选中链接中全部文字 → 有机会显示字数
按住Alt键同时选中链接文字 → 正常显示字数
鼠标拖选起始点都在“目录”框右侧、拖动选中“目录”框中的文字 → 正常显示字数
鼠标拖选起始点其一在“目录”框内、拖动选中“目录”框中的文字 → 无法显示

从上面的情况来看,似乎是在某些情况下(inline?)必须只选中同一容器内的文字才能显示字数,而在另一些情况下,则必须在A容器外选中A容器内的文字才能无视A容器内的容器嵌套情况显示字数……
难道Firefox的 document.getSelection() 有 bug ?

最新喜欢:

tulip17tulip1...
yfdyh000
千年狐狸
千年狐狸
  • UID29079
  • 注册日期2009-06-07
  • 最后登录2019-10-18
  • 发帖数2211
  • 经验1343枚
  • 威望0点
  • 贡献值52点
  • 好评度134点
  • 社区居民
  • 最爱沙发
  • 忠实会员
1楼#
发布于:2015-07-02 16:23
没试这个,但提供一个更好用更简单的字数计算脚本,可做参考:
https://zh.wikipedia.org/wiki/User:Liangent/Gadgets/Toolkit/wordcount.js
hzhbest
千年狐狸
千年狐狸
  • UID22640
  • 注册日期2008-01-15
  • 最后登录2017-04-06
  • 发帖数1763
  • 经验476枚
  • 威望3点
  • 贡献值414点
  • 好评度89点
  • 社区居民
  • 忠实会员
2楼#
发布于:2015-07-02 17:09
yfdyh000:没试这个,但提供一个更好用更简单的字数计算脚本,可做参考:
https://zh.wikipedia.org/wiki/User:Liangent/Gadgets/Toolkit/wordcount.js
回到原帖
参考后,把核心的那句改成了
var selCount = getSelection().toString().length;
然后基本表现一样,除了纯鼠标选中链接中部分文字能正常显示字数了。

我猜测,当鼠标在某元素开始选择的时候,结束点要在同一个元素中且不在其下层元素中,否则 getSelection().toString() 不会返回任何东西自然没法计字数。
例如,从元素B开始选择的话,结束点必须在B内而不能到其上层A内,或者在其下层元素C、D等内,但划过的话不影响。
文科
千年狐狸
千年狐狸
  • UID39959
  • 注册日期2013-10-17
  • 最后登录2019-07-27
  • 发帖数2069
  • 经验1328枚
  • 威望4点
  • 贡献值340点
  • 好评度255点
  • 最爱沙发
  • 社区居民
  • 忠实会员
3楼#
发布于:2015-07-02 17:28
calculation of selection length
https://greasyfork.org/zh-CN/scripts/9647-calculation-of-selection-length
之前看到过一个类似的脚本,可惜没有效果。
试试楼主的
aaaa007cn
千年狐狸
千年狐狸
  • UID23968
  • 注册日期2008-05-03
  • 最后登录2019-10-19
  • 发帖数1916
  • 经验1130枚
  • 威望1点
  • 贡献值232点
  • 好评度161点
4楼#
发布于:2015-07-02 17:42
问题不在 document.getSelection
而在 document.addEventListener('click');
https://developer.mozilla.org/en-US/docs/Web/Events/click
The click event is fired when a pointing device button (usually a mouse button) is pressed and released on a single element.
taoww
狐狸大王
狐狸大王
  • UID39284
  • 注册日期2013-03-18
  • 最后登录2019-10-13
  • 发帖数456
  • 经验413枚
  • 威望0点
  • 贡献值98点
  • 好评度71点
5楼#
发布于:2015-07-03 00:04
如4楼所言,click事件只有当按下和放开鼠标都在同一元素上时才会触发,你该绑定在mouseup事件上
另外,当obj不为null或undefined时,String(obj)实际上就是在调用obj.toString(),所以在你的代码中,两者是没区别的。你觉得的区别本质上是由放开鼠标时是否在链接上导致的

虽然现在firebug没办法直接调试gm的脚本了,你还是可以在代码中用console.log或alert来输出调试信息,可以避免很多瞎猜
hzhbest
千年狐狸
千年狐狸
  • UID22640
  • 注册日期2008-01-15
  • 最后登录2017-04-06
  • 发帖数1763
  • 经验476枚
  • 威望3点
  • 贡献值414点
  • 好评度89点
  • 社区居民
  • 忠实会员
6楼#
发布于:2015-07-03 08:51
多谢 @aaaa007cn@taoww 的确是我之前一直只将问题集中在 getSelection() 上面,只是认为 click 事件只是触发后续与它无关,没去了解 click 事件触发本身还有限制
不过我没瞎猜,只是没把调试语句放到 click 事件那里罢了。
改成 mouseup 之后就非常非常顺畅了,哈哈哈哈
不过现在发现一个小问题,就是选中显示字数了,再点击取消选中的时候,有较高几率仍再显示一次跟之前一样的字数,但选择区是已经消失的。
【更新】上面这个小问题通过增加一点小延时就可以排除掉了(mouseup事件至selection刷新有时差,不符合直觉但是可以理解,因为电脑会等候双击的信号)。

P.S. @文科 我就是找到那个脚本,试了之后没效果(Firefox真不支持 selectionchange 事件),所以才自己写一个的。先是用快捷键调用发现可行,才想怎样去用鼠标触发,试了 select 是受限于文字输入框,才去试 click 。

现在是在文字输入框这些地方不能计字数。
文科
千年狐狸
千年狐狸
  • UID39959
  • 注册日期2013-10-17
  • 最后登录2019-07-27
  • 发帖数2069
  • 经验1328枚
  • 威望4点
  • 贡献值340点
  • 好评度255点
  • 最爱沙发
  • 社区居民
  • 忠实会员
7楼#
发布于:2015-07-03 11:08
aaaa007cn
千年狐狸
千年狐狸
  • UID23968
  • 注册日期2008-05-03
  • 最后登录2019-10-19
  • 发帖数1916
  • 经验1130枚
  • 威望1点
  • 贡献值232点
  • 好评度161点
8楼#
发布于:2015-07-03 13:44
hzhbest
千年狐狸
千年狐狸
  • UID22640
  • 注册日期2008-01-15
  • 最后登录2017-04-06
  • 发帖数1763
  • 经验476枚
  • 威望3点
  • 贡献值414点
  • 好评度89点
  • 社区居民
  • 忠实会员
9楼#
发布于:2015-07-03 14:43
文科:用了一下  https://greasyfork.org/zh-CN/scripts/10763-selection-length-%E9%80%89%E4%B8%AD%E8%AE%A1%E5%AD%97%E6%95%B0
似乎空格也会算入...
回到原帖
不好意思呢,如你所见,目前还非常简陋,只是单纯地获取字长。
如果要写好点应该要忽略或单独统计非词标点和字符、忽略空格、统计拉丁语系单词等等等等……
----------
@aaaa007cn ,回去研究一下先。
文科
千年狐狸
千年狐狸
  • UID39959
  • 注册日期2013-10-17
  • 最后登录2019-07-27
  • 发帖数2069
  • 经验1328枚
  • 威望4点
  • 贡献值340点
  • 好评度255点
  • 最爱沙发
  • 社区居民
  • 忠实会员
10楼#
发布于:2015-07-03 14:50
hzhbest:不好意思呢,如你所见,目前还非常简陋,只是单纯地获取字长。
如果要写好点应该要忽略或单独统计非词标点和字符、忽略空格、统计拉丁语系单词等等等等……
----------
谢 @aaaa007cn ,回去研究一下先。
回到原帖
嗯,期待完善,以后要统计字数就不用单独打开word了
hzhbest
千年狐狸
千年狐狸
  • UID22640
  • 注册日期2008-01-15
  • 最后登录2017-04-06
  • 发帖数1763
  • 经验476枚
  • 威望3点
  • 贡献值414点
  • 好评度89点
  • 社区居民
  • 忠实会员
11楼#
发布于:2015-07-23 16:14

图片:aaaa.png


在文本框中测试的时候,出现这样的错误信息,第一条无法在网上查到相关资料,点右侧的链接也无法打开任何代码,而且 mousedown 和 mouseup 的动作都产生额外的错误数字;
……
好吧,我白痴了,在上面的语句引用了一个下面才定义的变量……
虽然还是无法明白 【Error: Permission denied to access property "onmouseup"】这样的错误信息是怎么出来的,更不明白为何mousedown也会产生这错误信息……
----------

现在还未能解决的问题是:
1.在文本框中点击,依然在控制台产生【Error: Permission denied to access property "onmouseup"】这样的错误信息,就是不影响脚本功能罢了。
2.本论坛的高级发帖框是使用iframe嵌带contentEditable属性“true”的body元素来实现的,由于嵌在iframe里,脚本不生效,也不显示任何错误信息。
(顺便,通过获取document.activeElement无法获取到body,也就无法得到contentEditable == "true"的结果,对ImageMikirenaizer这个扩展来说,就造成混淆【虽然其原始代码本身就不判断这个,但我加上对contentEditable属性的判断也因此无效】,使得在高级发帖框按空格就会触发这扩展的翻页功能而无法输入空格,而且还插入了如下的横线↓)

aaaa007cn
千年狐狸
千年狐狸
  • UID23968
  • 注册日期2008-05-03
  • 最后登录2019-10-19
  • 发帖数1916
  • 经验1130枚
  • 威望1点
  • 贡献值232点
  • 好评度161点
12楼#
发布于:2015-07-24 00:12
我这里没有 Error: Permission denied to access property "onmouseup"
是不是和 firefox 版本(39.0)、油猴版本(3.2),还有 e10s(关闭) 有关?
aaaa007cn
千年狐狸
千年狐狸
  • UID23968
  • 注册日期2008-05-03
  • 最后登录2019-10-19
  • 发帖数1916
  • 经验1130枚
  • 威望1点
  • 贡献值232点
  • 好评度161点
13楼#
发布于:2015-07-24 00:23
https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement
contentDocument
contentWindow
document.querySelector(".wind_editor_iframe").contentWindow.document.querySelector("body")
hzhbest
千年狐狸
千年狐狸
  • UID22640
  • 注册日期2008-01-15
  • 最后登录2017-04-06
  • 发帖数1763
  • 经验476枚
  • 威望3点
  • 贡献值414点
  • 好评度89点
  • 社区居民
  • 忠实会员
14楼#
发布于:2015-07-24 11:45
aaaa007cn:我这里没有 Error: Permission denied to access property "onmouseup"
是不是和 firefox 版本(39.0)、油猴版本(3.2),还有 e10s(关闭) 有关?
回到原帖
硬件加速没开,油猴是2.3,火狐是tete的39.0。
油猴是据说新版有内存泄漏问题,所以没升。
aaaa007cnhttps://developer.mozilla.org/docs/Web/API/HTMLIFrameElement
contentDocument
contentWindow
document.querySelector(".wind_editor_iframe").contentWindow.document.querySelector("body")
回到原帖

不是很明白怎么用,是要明确指定到iframe才能调用吗?在我这个脚本中应该怎么写啊?
游客

返回顶部