Javascript [non-]内容可编辑HTML5元素上的键盘事件
我正在编写(自由软件,alpha-stage,与定制GCC的领域特定语言相关)。它被用作一个专门的web服务器,我希望它成为我正在设计的某些DSL的语法导向编辑器。我说的是承诺,如果这很重要的话。您可以将其作为Javascript [non-]内容可编辑HTML5元素上的键盘事件,javascript,jquery,linux,html,contenteditable,Javascript,Jquery,Linux,Html,Contenteditable,我正在编写(自由软件,alpha-stage,与定制GCC的领域特定语言相关)。它被用作一个专门的web服务器,我希望它成为我正在设计的某些DSL的语法导向编辑器。我说的是承诺,如果这很重要的话。您可以将其作为/monimelt-Dweb运行,运行-W localhost.localdomain:8086,然后在浏览器中打开 我正在发射(通过文件webroot/microedit.html) 现在,我希望类的每个对一些键盘(也许还有鼠标)事件敏感。但是,contenteditable元素可以通过
/monimelt-Dweb运行,运行-W localhost.localdomain:8086
,然后在浏览器中打开
我正在发射(通过文件webroot/microedit.html
)
现在,我希望类的每个
对一些键盘(也许还有鼠标)事件敏感。但是,contenteditable
元素可以通过许多用户操作进行编辑(我甚至不知道这类用户操作的完整列表是什么……)并且我只希望这些span元素对定义的和受限的按键集作出响应(字母数字和空格)并且不能被用户更改,否则(例如,没有标点符号、没有“剪切”、没有“粘贴”、没有退格、没有制表符等)
是否有contenteditable='true'
元素可以获取并响应的事件(或用户操作)的完整列表
如何禁用大多数事件或用户操作(在键盘和鼠标上)并仅对某些(定义良好的)键盘事件作出反应?
显然,非可编辑内容的
元素中的
元素无法获得任何键盘用户操作(因为它无法获得焦点)
我只针对最新的HTML5浏览器,如Firefox38或42,或Chrome47等。。。在Debian/Linux/x86-64上,如果这很重要的话(所以我真的不关心IE9)
PS.是一个相关的问题,但不是同一个问题
PS2:找到了博客页面。让我几乎哭了。。。还可以阅读关于(的文章)。另请参见关于和草稿的W3C草稿内部文档。W3C的两项工作都在进行中。W3C TR on(2015年11月)仍然是一份工作草案。另请参见(在Chrome 46和Firefox 42或43 beta中表现不同)
PS3:也许contenteditable
毕竟是个坏主意。我(遗憾地)正在考虑使用画布(a la)并用手写javascript进行所有编辑和绘图
增编:
(2015年11月26日)
通过与一些Mozilla人士私下讨论,我了解到:
- 杂乱无章(因此我宁愿避免),在Firefox中也不再有效(例如,即使是最近的测试版Firefox也不知道
contenteditable='events',
,请参阅)
- 非常重要
- 一个普通的
(或
)可以通过给它一个tabindex
属性来设置焦点
- API可能很有用(但有一些最新的)
所以我可能不需要内容可编辑
您可以这样做:
function validateInput(usrAct){
swich(usrAct){
case "paste":
// do something when pasted
break;
case "keydown":
// dosomething on keydown
break;
default:
//do something on default
break;
}
}
document.querySelectorAll('.momitemref_cl').addEventListener('input', function(e){
validateInput(e.type)
}, false);
首先,HTMLElements
在您将其contentEditableElements
属性设置为true
时变为contentEditableElements
现在,执行IMO解析的最佳方法是侦听并检查元素的textContent
:
s.addEventListener('input',validate,false);
功能验证(evt){
var badValues=['bad','content'];
var span=这个;
badValues.forEach(函数(v){
if(span.textContent.indexOf(v)>-1){
//那太糟糕了,钥匙
span.textContent=span.textContent.split(v).join(“”);
}
});
};代码>
Hello
编辑:
(仅处理所述类的跨距。还处理这样的情况,即可以从另一个跨距返回到上一个跨距并删除它。合并了@AWolff的思想,用于切换焦点上的contenteditable属性)
总体思路与前一版本相同
小提琴:
片段:
var div=document.getElementById('microedit_id'),
span=document.querySelectorAll('#microedit_id.momtItemRef_cl'),
命令=[“粘贴”、“剪切”],
//白名单是按键事件的按键代码
白名单=[{'range':true,'start':'97','end':'122},//小写
{'range':true,'start':'65','end':'90'},//大写
{'range':true,'start':'48','end':'57'}//数字
],
//specialkeys是按键关闭事件的按键代码
specialKeys=[8,9,13,46]//退格、制表符、输入、删除
;
div.addEventListener('keydown',把手外,假);
[].forEach.call(跨度,函数(跨度){
span.setAttribute('contenteditable',true);
setAttribute('tabindex','-1');
span.添加的事件监听器('focus',handleFocus,false);
span.增补列表(“模糊”,把手模糊,错误);
commands.forEach(函数(cmd){
span.addEventListener(cmd,函数(e){
e、 preventDefault();返回false;
});
});
span.添加的监听器('keypress',handlePress,false);
span.addEventListener('keydown',handleDown,false);
});
函数handleFocus(e){div.setAttribute('contenteditable',false);}
函数handleBlur(e){div.setAttribute('contenteditable',true);}
功能手柄(e){
允许的var=false,key=e.keyCode;
白名单.forEach(函数(范围){
如果(键&&(键!='')和(range.start这段代码可能就是你想要的,使span.momtItemRef\u cl
元素可聚焦但不可选项卡化,并且设置为contenteditable
。但是当我在chrome上测试它时,contenteditable
在任何属性contenteditable
设置为true
的容器中,不要触发任何键盘事件。所以技巧可能是聚焦,将任何容器设置为不可编辑(并切换回模糊)
参见示例:(keypress和keydown事件都是绑定的,用于处理keypress或keydown无法处理的特定情况
<dd class='statval_cl' data-forattr='notice'> ▵
<span class='momnode_cl'>*<span class='momconn_cl'>
<span class='momitemref_cl'>comment</span></span>
(“<span class='momstring_cl'>some simple notice</span>”
<span class='momnode_cl'>*<span class='momconn_cl'>
<span class='momitemref_cl'>web_state</span></span>
(<span class='momnumber_cl'>2</span>)</span>
<span class='momitemval_cl'>hashset</span>
<span class='momset_cl'>{<span class='momitemref_cl'>microedit</span>
<span class='momitemref_cl'>the_agenda</span>}</span>
<span class='momtuple_cl'>[<span class='momitemref_cl'>web_session</span>
<span class='momitemref_cl empty_cl'>~</span>
<span class='momitemref_cl'>the_system</span>]</span>)</span> ;</dd>
function validateInput(usrAct){
swich(usrAct){
case "paste":
// do something when pasted
break;
case "keydown":
// dosomething on keydown
break;
default:
//do something on default
break;
}
}
document.querySelectorAll('.momitemref_cl').addEventListener('input', function(e){
validateInput(e.type)
}, false);
<div class="momitemref_cl" contenteditable="true">Foo Bar</div>
<input class="not-momitemref_cl"/>
<input class="momitemref_cl"/>
document.querySelectorAll('.momitemref_cl').forEach((el) => {
el.addEventListener('keydown', validateInput);
el.addEventListener('cut', e => e.preventDefault());
el.addEventListener('copy', e => e.preventDefault());
el.addEventListener('paste', e => e.preventDefault());
});
function validateInput(userAction) {
console.log(userAction);
if (userAction.ctrlKey) {
userAction.preventDefault();
return false;
}
let code = (userAction.keyCode ? userAction.keyCode : userAction.which);
if ((48 <= code && code <= 57 && !userAction.shiftKey) || (65 <= code && code <= 90) || (97 <= code && code <= 122) || code === 32) {
console.log(`Allowing keypress with code: ${code}`);
return true;
}
console.log(`Preventing keypress with code: ${code}`);
userAction.preventDefault();
return false;
}