可满足的单线input
对于我们在我工作的公司开发的应用程序,我们需要一个支持在基于JS的Web应用程序中插入表情符号的input。 我们目前正在使用表情符号(即:-))的input,并希望切换到插入实际的graphics图像。
我们原来的计划是使用contenteditable
<div>
。 我们使用监听器进行粘贴事件以及不同的键/鼠标交互,以确保没有不必要的标记进入contenteditable(我们从文档的容器标签中去除文本,只留下我们自己插入的图像标签)。
不过,现在的问题是,如果你input足够的内容(即高度增加),div就会resize。 我们不希望发生这种情况,也不能让文本被隐藏(即简单的overflow: hidden
)。 所以:
有没有办法让contenteditable div行为像一个单行input?
我最好喜欢,如果有一个相对简单的属性/ CSS属性,我已经错过了将做我想做的,但如果有必要的CSS + JS的build议也将不胜感激。
[contenteditable="true"].single-line { white-space: nowrap; width:200px; overflow: hidden; } [contenteditable="true"].single-line br { display:none; } [contenteditable="true"].single-line * { display:inline; white-space:nowrap; }
<div contenteditable="true" class="single-line"> This should work. </div>
我想你正在寻找一个contenteditable
div
只有一行文本,当它溢出div
水平滚动。 这应该做的伎俩: http : //jsfiddle.net/F6C9T/1
div { font-family: Arial; font-size: 18px; min-height: 40px; width: 300px; border: 1px solid red; overflow: hidden; white-space: nowrap; }
<div contenteditable> Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. </div>
这是一个相对简单的解决scheme,它使用contenteditable的input事件来扫描dom,并过滤掉各种新行(所以它应该对复制/粘贴,拖放,敲击键盘等等)有效。 它将多个TextNode压缩为单个TextNode,从TextNodes剥离换行符,杀死BRs,并在触摸的任何其他元素上放置“display:inline”。 在Chrome上testing,在其他地方没有保证。
var editable = $('#editable') editable.on('input', function() { return filter_newlines(editable); }); function filter_newlines(div) { var node, prev, _i, _len, _ref, _results; prev = null; _ref = div.contents(); _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { node = _ref[_i]; if (node.nodeType === 3) { node.nodeValue = node.nodeValue.replace('\n', ''); if (prev) { node.nodeValue = prev.nodeValue + node.nodeValue; $(prev).remove(); } _results.push(prev = node); } else if (node.tagName.toLowerCase() === 'br') { _results.push($(node).remove()); } else { $(node).css('display', 'inline'); filter_newlines($(node)); _results.push(prev = null); } } return _results; }
#editable { width: 200px; height: 20px; border: 1px solid black; }
<div id="editable" contenteditable="true"></div>
所以,对于后代来说:最简单的解决scheme是让你的产品经理改变需求,以便你可以进行多行编辑。 结果发生在我们的案件中。
但是,在这之前,我最终创build了一个手动移动的单行Richtext编辑器。 我最终将其封装在一个jQuery插件中。 我没有时间来完成它(IE中可能存在一些错误,Firefox效果最好,Chrome的工作效果也不错 – 评论很less,有时不太清楚)。 它使用Rangy库的一部分 (提取,因为我不想依靠完整的库)来获取select的屏幕位置,以testing鼠标位置与select(所以你可以拖动select和移动框)。
粗略地说,它使用3个元素。 一个外部div(你称之为插件的东西),它获得溢出:隐藏,然后在其中嵌套2层。 第一个层次是绝对定位的,第二个层次是实际的内容。 这种分离是必要的,因为否则一些浏览器将给予contenteditable绝对定位的元素grippies,让用户移动它…
在任何情况下,都有一大堆代码来移动顶部元素内的绝对定位的元素,从而移动实际的内容。 自给自足有白色空间nowrap等等迫使它保持一条线。
插件中还有一些代码可以从粘贴/拖拽到文本框中的任何文本中去除任何不是图像的东西(比如br
,表格等等)。 你需要一些部分(比如brs,剥离/标准化段落等),但是也许你通常想要保持链接, em
, strong
和/或其他格式。
来源: https : //gist.github.com/1161922
看看我刚刚发布的这个答案。 这应该帮助你:
如何创build一个监听Enter和Esc的HTML5单行contentEditable选项卡
这里是HTML标记:
<span contenteditable="false"></span>
这里是jQuery / javascript:
$(document).ready(function() { $('[contenteditable]').dblclick(function() { $(this).attr('contenteditable', 'true'); clearSelection(); $(this).trigger('focus'); }); $('[contenteditable]').live('focus', function() { before = $(this).text(); if($(this).attr('contenteditable') == "true") { $(this).css('border', '1px solid #ffd646'); } //}).live('paste', function() { }).live('blur', function() { $(this).attr('contenteditable', 'false'); $(this).css('border', '1px solid #fafafa'); $(this).text($(this).text().replace(/(\r\n|\n|\r)/gm,"")); if (before != $(this).text()) { $(this).trigger('change'); } }).live('keyup', function(event) { // ESC=27, Enter=13 if (event.which == 27) { $(this).text(before); $(this).trigger('blur'); } else if (event.which == 13) { $(this).trigger('blur'); } }); $('[contenteditable]').live('change', function() { var $thisText = $(this).text(); //Do something with the new value. }); }); function clearSelection() { if ( document.selection ) { document.selection.empty(); } else if ( window.getSelection ) { window.getSelection().removeAllRanges(); } }
希望这可以帮助别人!
如果你想要一个不同的方式来解决它,而不是改变需求,只需要一点点display:table
是完全可能的=)
.container1 { height:20px; width:273px; overflow:hidden; border:1px solid green; } .container2 { display:table; } .textarea { width:273px; font-size: 18px; font-weight: normal; line-height: 18px; outline: none; display: table-cell; position: relative; -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text; word-wrap: break-word; overflow:hidden; }
<div class="container1"> <div class="container2"> <div contenteditable="true" class="textarea"></div> </div> </div>
你可以用文本inputreplace这个div(在onclick事件被调用之后)。
我使用了类似于这个插件的东西,它工作得很好。
与jQuery我已经设置了一个.keypress事件,然后testinge.keyCode == 13(返回键),如果是从事件返回false和编辑不能够使多行
$('*[contenteditable=yes]').keypress(function(e) { if(e.keyCode == 13 && !$(this).data('multiline')) { return false; } })