Snap Build Your Own Blocks输入中文解决办法

Snap! (formerly BYOB) is a visual, drag-and-drop programming language. It is an extended reimplementation of Scratch (a project of the Lifelong Kindergarten Group at the MIT Media Lab) that allows you to Build Your Own Blocks. It also features first class[1] lists, first class procedures, and continuations[2]. These added capabilities make it suitable for a serious introduction to computer science for high school or college students.

快照!(以前 BYOB) 是一种可视的拖放编程语言。这是一个扩展的重新实施(一个项目的终身幼儿园小组在麻省理工学院媒体实验室), 让你建立自己的块。它还具有第一类 [1] 列表、第一类过程和延续 [2]。这些新增功能使其适合于对高中或大学生进行计算机科学的认真介绍。

它加州伯克利大学编写的一套开源图形化编程,它的官网在:https://snap.berkeley.edu;在页面有更为详细的介绍,并且在编程界面的左上角(如图  1)的图表点击一下即可以下载该图形化编程的源代码。

图  1

到目前在编程界面中除了能够输入英文之外,其他语言均不能正常输入,曾经在GIT上面找到了一个解决中文输入的方案,根据它的修改之后,确实能够进行中文输入,但是,输入体验,不是很好,简单说就是输入过程不能够像在页面的输入框中输入那样流畅。有时候光标还会乱跳,这个方案的访问地址,忘了,后期没有找到。

我的解决方法也是在那个基础上进行改良的,但是方式不一样。

现在我们先确定一下,为了实现中文的输入,我们应该修改哪一个源文件:morphic.js;这个源文件存放了图形化编程界面的核心:主要包含了,所有的类的基类Morph,然后是一堆继承者:CursorMorph(Snap 自定义的光标)MouseSensorMorph(自定义的鼠标事件)、DialMorph(弹窗)、HandleMorph(事件,转发)、StringMorph等等。

在这里我们只关心CursorMorph这一个类。然后再关注他的几个方法:

  • CursorMorph.prototype.init  这个是CursorMorph的初始化
  • CursorMorph.prototype.initializeClipboardHandler 看源码可分析出这个完成创建一个textarea,可编辑域
  • this.clipboardHandler.addEventListener( 'keydown', …) 为可编辑域添加事件keydown
  • this.clipboardHandler.addEventListener(input, …) 为可编辑域添加事件input
  • CursorMorph.prototype.processKeyPress 响应keypress事件
  • CursorMorph.prototype.processKeyDown 响应keydown事件
  • CursorMorph.prototype.insert(aChar, shiftKey) 在编辑域中添加字符,第二个参数是个bool值,判定当前shift键是否按下过。

下面,再给出我自己修改的思路:我们先想想一下,自己进行全拼音中文输入时,在最后选定要输入的中文,都会按下一个 空格或者阿拉伯数字1至9,来选定汉字;这也就代表了一次中文输入结束。便出现问题1:根据什么东西来判定当前一次中文输入结束了呢?问题2:用户选定的要输入的中文字符内容存放在哪里的?

解决第一个问题:需要分析源代码:

this.clipboardHandler.addEventListener(

'keydown',

function (event) {…},

false);

中回调函数function(event)中参数event存放了哪些内容,通过浏览器页面调试打印,我们可以查看到如下信息:

图  2 Opera浏览器中打印出的信息

图  3搜过浏览器中的输出

我们可以发现:两个浏览器输出的内容并不相同,Opera有一个key成员,少一个keyIdentifier;而搜狗浏览器与之相反;但两者又一个共有的成员which,并且值都为229。通过测试谷歌浏览器也同样有这个值。

然后通过空格或数字1到9选定汉字时,打印的信息是:

因子,我们可以在利用code成员的值,来判断一次中文输入是否结束;

这样,第一个问题也算是得到了解决。

下面,我们来解决第二个问题:用户所选定输入的中文字符存放在哪里的,此时:

this.clipboardHandler.addEventListener(

'input',

function (event) {},

false);

代码中function(event)中参数event中存放的内容;

以及CursorMorph.prototype.initializeClipboardHandler=function(){…}代码中的this.clipboardHandler这个成员,它是HTML对象textarea,获取textarea的值的方法是:

var cval = this.clipboardHandler.value;学习过前端的都知道。

现在通过浏览器终端打印输出信息,来看看内容:

图  4 Opera浏览器的输出

图  5 搜狗浏览器的输出

可以发现,Opera的event的成员含有data成员,而搜狗浏览器没有该成员;但它们共育是this.clipboardHandler.value的值是相同的,并且在Opera浏览中,它的值与event.data的值相同。那么这样用户输入的中文的值,我们也就找到了;

最后一个问题:我们怎么把这个字,插入到相应的文本框中呢。

是否还记得前面提及的CursorMorph.prototype.insert(aChar, shiftKey)这个成员函数;它便可以解决该问题。

下面给出修改后的源码,并标记出修改的地方,源文件morphic.js:

CursorMorph.prototype.init = function (aStringOrTextMorph) {

var ls;

//这一行,是自己需要添加的,判定当前是否正在进行中文输入

this.isInputCH = false ;

//这一行,是自己需要添加的,判定一次中文输入是否结束

this.isInputChED = false ;

// additional properties:

this.keyDownEventUsed = false;

this.target = aStringOrTextMorph;

this.originalContents = this.target.text;

this.originalAlignment = this.target.alignment;

this.slot = this.target.text.length;

CursorMorph.uber.init.call(this);

ls = fontHeight(this.target.fontSize);

this.setExtent(new Point(Math.max(Math.floor(ls / 20), 1), ls));

this.drawNew();

this.image.getContext('2d').font = this.target.font();

if (this.target instanceof TextMorph &&

(this.target.alignment !== 'left')) {

this.target.setAlignmentToLeft();

}

this.gotoSlot(this.slot);

this.initializeClipboardHandler();

};

CursorMorph.prototype.initializeClipboardHandler = function () {

// Add hidden text box for copying and pasting

var myself = this,

wrrld = this.target.world();

this.clipboardHandler = document.createElement('textarea');

this.clipboardHandler.style.position = 'absolute';

this.clipboardHandler.style.top = window.outerHeight;

this.clipboardHandler.style.right = '101%'; // placed just out of view

document.body.appendChild(this.clipboardHandler);

this.clipboardHandler.value = this.target.selection();

this.clipboardHandler.focus();

this.clipboardHandler.select();

this.clipboardHandler.addEventListener(

'keypress',

function (event) {

myself.processKeyPress(event);

this.value = myself.target.selection();

this.select();

},

false

);

this.clipboardHandler.addEventListener(

'keydown',

function (event) {

var kcode = event.code.substring(0,5);

console.log(event);

console.log("kcode="+kcode+";which="+event.which);

console.log("keyIdentifier="+event.keyIdentifier);

// if ( (event.key && event.key === 'Process') ||

//      (event.keyIdentifier && event.which === 229)){

if ( event.which === 229) { //所有浏览器共有的特征和值

// 在中文输入过程时,空格为选中汉字

myself.isInputCH = true; //设为真表示正在进行中文输入

//设为真表示一次中文输入结束

myself.isInputChED = (kcode === 'Space' || kcode === 'Digit')?true:false;

console.log("判定当前正在进行中文输入");

}

myself.processKeyDown(event);

if (event.shiftKey) {

wrrld.currentKey = 16;

}

this.value = myself.target.selection();

this.select();

// Make sure tab prevents default

if (event.key === 'U+0009' ||

event.key === 'Tab') {

myself.processKeyPress(event);

event.preventDefault();

}

},

false

);

this.clipboardHandler.addEventListener(

'keyup',

function (event) {  wrrld.currentKey = null;},

false

);

this.clipboardHandler.addEventListener(

'input',

function (event) {

var ival = myself.clipboardHandler.value ;

console.log("============ input ==========");

console.log(event);

console.log(myself.target);

console.log("[cliph data="+ival+";event data="+event.data+"]");

console.log("[char="+ival+",len="+ival.length+",isch="+myself.isInputCH+",ised="+myself.isInputChED+"]");

//这个条件下,表示输入的是 中文汉字

if ( myself.isInputCH && myself.isInputChED ){

console.log(">>>>QQ输入法和搜狗输入法");

//支持了QQ输入法和搜狗输入法

myself.insert(ival,event.shiftKey);

// myself.isInputChED = myself.isInputCH = event.data !== ' '?false:true ;

myself.isInputChED = myself.isInputCH = false ;

}else if (  (ival.length ===1 || ival.length === 2 ) &&

myself.isInputCH && ival !== ' ' &&

(ival < 'a' || ival > 'z') && (ival < 'A' || ival > 'Z')){

//表示输入的是 中文的字符,如逗号,句号等等

console.log(">>>>other input software...");

myself.insert(ival,event.shiftKey);

myself.isInputCH = false ;

}

// if (this.value === '') {

//     myself.gotoSlot(myself.target.selectionStartSlot());

//     myself.target.deleteSelection();

// }

},

false

);

};

这种修改方案有一个小BUG是这样的,当进行输入中文时,一般情况下,键入完拼音后,在键入shift键,那么输入的便是之前 键入的拼音;但在这个解决办法中,不能够完成该操作。

Snap Build Your Own Blocks输入中文解决办法的更多相关文章

  1. powerpoint无法输入中文怎么办|ppt文本框无法输入中文解决办法

    powerpoint文本框无法输入中文的情况不知大家是否遇到过呢?反正小编是遇到过这样的情况的,简直是急煞人也!那么powerpoint无法输入中文时应该怎么办呢?本节内容中小编就为大家带来ppt文本 ...

  2. ubuntu16.04下fcitx无法在QT Creator输入中文解决办法

    我的博客新地址:www.liuquanhao.com ------------------------------------------------------ Qt creator无法用fcitx ...

  3. ubuntu15.10下sublime text3 无法输入中文解决办法

    原文链接:http://geek.csdn.net/news/detail/44464 1.首先保证你的电脑有c++编译环境 如果没有,通过以下指令安装 sudo apt-get install bu ...

  4. mysql列名不能输入中文 解决办法

    以前安装了mysql,今天下午做了个练习,每次列名为中文时总是报错.查资料显示说需要修改配置文件my.ini 我的路径是:C:\Program Files\MySQL\MySQL Server 5.5 ...

  5. 解决Qt程序在Linux下无法输入中文的办法

    解决Qt程序在Linux下无法输入中文的办法 一位网友问我怎样在Linux的Qt的应用程序中输入中文,我一開始认为不是什么问题,可是后面自己尝试了一下还真不行.不仅是Qt制作的应用程序,就连Qt Cr ...

  6. 【Qt开发】解决Qt程序在Linux下无法输入中文的办法

    解决Qt程序在Linux下无法输入中文的办法 一位网友问我如何在Linux的Qt的应用程序中输入中文,我一开始觉得不是什么问题,但是后面自己尝试了一下还真不行.不仅是Qt制作的应用程序,就连Qt Cr ...

  7. vi/vim输入中文乱码,无法输入中文解决方法

    vi/vim输入中文乱码,无法输入中文解决方法 编辑/etc/vimrc或者/etc/virc,加入以下内容即可 set encoding=UTF-8 set langmenu=zh_CN.UTF-8 ...

  8. jmeter中接口测试出现乱码或不识别中文解决办法

    在查看结果是中出现乱码时:jmeter的bin目录下的jmeter.properties下最下面添加sampleresult.default.encoding=UTF-8后重新打开工具就好了 在接口的 ...

  9. Ubuntu 15.04下MySQL 5.6.25不支持中文解决办法

    Ubuntu 15.04下MySQL 5.6.25不支持中文解决办法,apt-get install 安装的,不是源码包安装的mysql. 1 修改mysql的配置文件 /etc/mysql/conf ...

随机推荐

  1. Java安全之安全加密算法

    Java安全之安全加密算法 0x00 前言 本篇文来谈谈关于常见的一些加密算法,其实在此之前,对算法的了解并不是太多.了解的层次只是基于加密算法的一些应用上.也来浅谈一下加密算法在安全领域中的作用.写 ...

  2. python基础二:循环

    python 中循环的方式有两种: 一,for 循环  单向循环 可以用来遍历字符串,列表,元组,字典等 for value in 被遍历对象: print(value) 遍历字典dict的时候稍有不 ...

  3. Luogu P1625 求和

    题意 给定两个整数 \(n,m\),求 \[\sum\limits_{i=1}^{n}\frac{1}{\prod\limits_{j=i}^{i+m-1}j} \] \(\texttt{Data R ...

  4. Redis还可以做哪些事?

    在上一篇文章中,讲到了redis五大基本数据类型的使用场景,除了string,hash,list,set,zset之外,redis还提供了一些其他的数据结构(当然,严格意义上也不算数据结构),一起来看 ...

  5. python栈、队列、文件目录遍历

    一. 栈与队列 关注公众号"轻松学编程"了解更多. 1. 栈 stack 特点:先进先出[可以抽象成竹筒中的豆子,先进去的后出来] 后来者居上 mystack = [] #压栈[向 ...

  6. 【Android Studio】安卓开发初体验2——Activity

    Activity是什么 Activity用于提供可视化用户界面的组件,可以与用户进行交互来完成某项任务,一个应用程序中可以包含零个或多个活动 Activity的创建 首先将左侧的Active Tool ...

  7. [python学习手册-笔记]001.python前言

    001.python前言 ❝ 本系列文章是我个人学习<python学习手册(第五版)>的学习笔记,其中大部分内容为该书的总结和个人理解,小部分内容为相关知识点的扩展. 非商业用途转载请注明 ...

  8. 直播软件开发关于Android、iOS中的视频采集步骤

    很多人对直播软件开发还是抱有想法的,但是在这个资本冷静的市场下,直播平台该怎么玩,在直播软件开发过程中哪些功能是必须具备的,这都是值得关注的话题.今天我们给大家分享一份详细的直播软件开发关于Andro ...

  9. 分布式文档存储数据库之MongoDB访问控制

    上一篇博客主要聊了下mongodb的分片机制以及分片集群的搭建,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13958295.html:今天我们来了解下mon ...

  10. MyBatis 中 @Param 注解的四种使用场景

    https://juejin.im/post/6844903894997270536 第一种:方法有多个参数,需要 @Param 注解 第二种:方法参数要取别名,需要 @Param 注解 第三种:XM ...