- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一堆垂直排列的多行 contenteditable div,我想允许通过箭头键在它们之间进行自然导航(就好像它是一个文档一样)。为此,在 keydown
事件中我需要:
keydown
事件,而不是 keyup
).focus()
元素,而是在与我们所在位置相同的垂直位置模拟点击之前,这样它会感觉很自然,就像在文本编辑器中一样。我迄今为止发现的所有脚本/库要么没有完成我需要的所有事情,要么存在错误。请在您的建议中包含演示,这样我就可以在不先合并到我的代码中的情况下进行测试。谢谢!
更新: 视觉解释 - 请注意,有超过 2 个 div,并且“最后一行的向下箭头键”只是四个触发器之一
最佳答案
我已经写了一些代码,但它根本没有完成......也许你可以从那里开始,如果你愿意,可以尝试完成我所做的;)我将在本周继续努力,以提供你有一个解决方案......这是我到目前为止所做的:
var ajaxResult = [
"Inter has ruinarum varietates a Nisibi quam tuebatur accitus Vrsicinus, cui nos obsecuturos iunxerat imperiale praeceptum, dispicere litis exitialis certamina cogebatur. Inter has ruinarum varietates a Nisibi quam tuebatur accitus Vrsicinus, cui nos obsecuturos iunxerat imperiale praeceptum, dispicere litis exitialis certamina cogebatur. Inter has ruinarum varietates exitialis certamina cogebatur",
"Inter has ruinarum varietates a Nisibi quam tuebatur accitus",
"Inter has ruinarum varietates a Nisibi quam tuebatur accitus Vrsicinus, cui nos obsecuturos iunxerat imperiale praeceptum, dispicere litis exitialis certamina cogebatur. Inter has ruinarum varietates a Nisibi quamos iunxerat imperiale praeceptum, dispicere litis exitialis certamina cogebatur. Inter has ruinarum varietates exitialis certamina cogebatur",
];
/*************************************************************
*
* LIST OF CONTENT EDITABLE DIVS MANAGEMENT
*
**************************************************************/
// Create the editable divs
window.onload = function(){
var contentEditables = createContentEditables();
document.body.appendChild(contentEditables);
}
// Remember all the content editable elements in the order they appear in the dom
var _currentEdit,
_edits = [];
function createContentEditables(){
var div;
var result = document.createDocumentFragment();
for (var i = 0, n = ajaxResult.length ; i < n ; i++){
div = createContentEditable(ajaxResult[i]);
_edits.push(div);
result.appendChild(div);
}
return result;
}
function getPreviousEdit(edit){
// Search for the edit index
var index = _edits.indexOf(edit);
if(index == 0)
return;
// Return the previous one
return _edits[index - 1];
}
function getNextEdit(edit){
// Search for the edit index
var index = _edits.indexOf(edit);
if(index == _edits.length - 1)
return;
// Return the previous one
return _edits[index + 1];
}
/*************************************************************
*
* CONTENT EDITABLE MANAGEMENT
*
**************************************************************/
// We need to define the line height of the div to be able to retrieve the number of lines
var LINE_HEIGHT = 16;
// variables to keep trace of relevant information about the div
var _lines, _caretPosition;
/*
* Create a div with contenteditable set to true with the text
* received from the server
*/
function createContentEditable(text){
var element = document.createElement('div');
element.className = 'contenteditable';
element.innerHTML = text;
element.style.lineHeight = LINE_HEIGHT + 'px';
element.setAttribute('contenteditable', true);
// Set listeners
element.addEventListener('mouseup', onEdit_mouseup);
element.addEventListener('keydown', onEdit_keydown);
element.addEventListener('focus', onEdit_focus);
return element;
}
function onEdit_keydown(domEvent){
// Update caret position
_caretPosition = getCaretPosition(domEvent.target);
switch(domEvent.keyCode){
case 37: // left arrow
if (_caretPosition.index == 0){
var previousEdit = getPreviousEdit(domEvent.target);
if(previousEdit){
console.log("go to end of previous edit");
console.log(previousEdit);
previousEdit.focus();
}
}
break;
case 38: // up arrow
if (_caretPosition.line == 1){
var previousEdit = getPreviousEdit(domEvent.target);
if(previousEdit){
console.log("go to previous edit keeping the caret offset");
console.log(previousEdit);
previousEdit.focus();
}
}
break;
case 39: // right arrow
if (_caretPosition.index == domEvent.target.innerHTML.length){
var nextEdit = getNextEdit(domEvent.target);
if(nextEdit){
console.log("go to beginning of next edit");
console.log(nextEdit);
nextEdit.focus();
}
}
break;
case 40: // down arrow
if (_caretPosition.line == getLines(domEvent.target)){
var nextEdit = getNextEdit(domEvent.target);
if(nextEdit){
console.log("go to next edit keeping the caret offset");
console.log(nextEdit);
nextEdit.focus();
}
}
break;
}
}
function onEdit_mouseup(domEvent){
// Update caret position
_caretPosition = getCaretPosition(domEvent.target);
}
function onEdit_focus(domEvent){
// Add listeners
_currentEdit = domEvent.target;
_currentEdit.addEventListener('blur', onEdit_blur);
window.addEventListener('resize', onWindow_resize);
}
function onEdit_blur(domEvent){
// Remove listeners
domEvent.target.removeEventListener('blur', onEdit_blur);
window.removeEventListener('resize', onWindow_resize);
}
function onWindow_resize(domEvent){
// Update caret position
_caretPosition = getCaretPosition(_currentEdit);
}
/*************************************************************
*
* HELPERS
*
**************************************************************/
//http://stackoverflow.com/questions/4811822/get-a-ranges-start-and-end-offsets-relative-to-its-parent-container/4812022#4812022
//http://stackoverflow.com/questions/5528004/how-to-get-number-of-rows-in-contenteditable-area-and-current-caret-line-positio
function getCaretPosition(element){
var caretPosition = {index: 0, line: 0};
var doc = element.ownerDocument || element.document;
var win = doc.defaultView || doc.parentWindow;
var elemOffsetTop = element.offsetTop;
var sel;
// Get the x position of the caret
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
// Retrieve the current line
var rects = range.getClientRects();
var caretOffsetTop;
if (typeof rects[1] != "undefined"){
caretOffsetTop = rects[1].top;
}
else if (typeof rects[0] != "undefined"){
caretOffsetTop = rects[0].top;
}
else{
// Create dummy element to get y position of the caret
var dummy = document.createElement('CANVAS');
dummy.id = 'findCaretHelper';
range.insertNode(dummy);
caretOffsetTop = dummy.offsetTop;
element.removeChild(dummy);
}
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(element);
preCaretRange.setEnd(range.endContainer, range.endOffset);
// Remember caret position
caretPosition.index = preCaretRange.toString().length;
caretPosition.line = Math.ceil((caretOffsetTop - elemOffsetTop)/LINE_HEIGHT) + 1;
}
}
// support ie
//else if ( (sel = doc.selection) && sel.type != "Control") {
//var textRange = sel.createRange();
//var preCaretTextRange = doc.body.createTextRange();
//preCaretTextRange.moveToElementText(element);
//preCaretTextRange.setEndPoint("EndToEnd", textRange);
//caretPosition.x = preCaretTextRange.text.length;
//}
return caretPosition;
}
function getLines(element){
return element.clientHeight/LINE_HEIGHT;;
}
.contenteditable{
border: solid 1px #aaa;
margin: 10px 0;
}
我设法获取了有关当前行的信息,内容可编辑 div 中的当前字符索引和其他一些东西......我仍然需要专注于其他内容可编辑的 div,以便将插入符号放在正确的位置...我希望这个解决方案的开头对您有所帮助!
关于javascript - 使多个 contenteditables 表现得像一个文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38412194/
我正在用 C++ 开发一个程序,我必须实现一个 cron。由于不同的原因,这个 cron 应该每小时和每 24 小时执行一次。我的第一个想法是创建一个独立的 pthread 并在每次 1h 内休眠。这
我需要向同一场景几何添加多个体素(立方体等于),但每个体素具有不同的纹理。 我的体素超过 500 个,导致性能出现严重错误。 这是我的代码: texture = crearTextura(voxel.
对于 MySQL 数据库,我有 2 个场景,我不确定该选择哪一个,并且对于一些表我也遇到了同样的困境。 我正在制作一个仅供成员(member)访问的网络应用程序。每个成员都有自己的交易、费用和“列表”
我想知道一个简单的事情: 当设置一个被所有 child 继承的样式时,是否建议最具体? Structure: html > body > parent_content > wrapper > p 我想
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
这些天我正在阅读有关 JPA 的内容。我了解到可以在 JPQL 中使用 explicit 或 implicit JOIN。 显式加入 em.createQuery(“SELECT b.title, p
我有一种情况需要连接几个字符串以形成一个类的 id。基本上,我只是在列表中循环以获取对象的 ToString 值,然后将它们连接起来。 foreach (MyObject o in myList)
我正在检查我的游戏在拖尾效果下的性能会降低多少。但我注意到每秒的操作次数更多了。这怎么可能? 这是怎么回事... context.fillRect(0, 0, 500, 500); // cl
如果我可以选择使用全局变量或传递变量,哪个选项在速度和内存使用方面更好? // global variable function func(){ global $var; echo $var;
我有一个类似这样的表“tbl”:ID bigint(20) - 主键,自增字段1字段2字段3 该表有 60 万多行。 查询:SELECT * from tbl ORDER by ID LIMIT 60
谁能告诉我,我如何比较 TSP 最优和启发式算法?我已经实现了 TSP,但不知道如何比较它们。事实上,我怎样才能找到 TSP 的最优成本?有什么方法或猜测吗? 谢谢 最佳答案 用众所周知的基准实例检查
我有一个 NSTextStorage里面有长文本(比如一本书有 500 页,当前字体在设备上超过 9000 页)。我以这种方式为 textcontainer 分发此文本: let textStorag
我有一个根据邮政编码搜索项目的应用程序。 在搜索邮政编码时,我返回了来自该城市/社区的所有产品(通过解析邮政编码完成)。 我现在需要根据与原始邮政编码的距离对这些产品进行分类。 我将纬度/经度存储在数
我有许多进程(大约100到1000个进程),每个进程都必须向其他进程(例如大约10个)发送一些数据。 (通常,但不一定总是这样,如果A发送给B,B也发送给A。)每个进程都知道必须从哪个进程接收多少数据
我知道无状态组件使用起来更舒服(在特定场景下),但是既然你不能使用shouldComponentUpdate,这是否意味着组件将在每次props更改时重新渲染?我的问题是,使用带有智能 shouldC
我正在研究 Google Pagespeed 的加速页面加载时间指南列表。其中之一是缩小 CSS 和 JS 文件。 由于这些文件经常更改,我正在考虑使用 PHP 脚本根据请求(来自浏览器)即时缩小此脚
我正在尝试从下表构建 SQL 查询(示例): Example of table with name "performances" 这是带有运动表现的表格。我想从这个表中选择每个学科和一组一个或多个类别
假设我们有一个字符串 var "sA",我想检查字符串 "123"是否在 sA 的末尾。 什么更好,为什么: if(sA.length() > 2) sA.substr(sA.length()-3)
关于受这篇文章启发的可参数化查询 LINQ group by property as a parameter我获得了一个很好的参数化查询,但在性能上有一个缺点。 public static void
| 和| 之间有什么主要区别吗?和 + 从长远来看会影响代码的性能吗?或者都是 O(1)?我正在使用的代码是这样的: uint64_t dostuff(uint64_t a,uint64_t b){
我是一名优秀的程序员,十分优秀!