我需要这样制作所见即所得的编辑器:
这样,我们可以呈现语法突出显示的文本,同时保持文本区域的编辑功能。
我的问题是我缺乏CSS专业知识。因此,无论我尝试进行多少变种,换行,滚动或对齐方式都不同步始终存在问题。
下面提供的是一种变体。编辑器组件具有透明的灰色文本,而基础div是橙色文本,因此我们可以看到它们何时对齐。
面临的挑战是,无论内容,内容或滚动或大小如何,它们始终对齐。
function update(){
document.getElementById("richtext").innerHTML =
document.getElementById("editor").value;
}
.scrollable {
width: 300px;
height: 100px;
overflow: scroll;
border : 1px solid grey;
}
.content {
font-family: monospace;
font-size: 18px;
position: absolute;
top: 0;
left: 0;
border: none;
overflow: hidden;
min-width: 100%;
min-height: 100%;
outline: none;
resize: none;
margin: none;
padding: 0;
box-shadow: none;
box-sizing: border-box;
white-space: pre;
display: block;
overflow: none;
}
#richtext {
z-index: -10;
color: orange;
}
#view {
height: 100%;
position: relative;
display: inline-block;
}
#editor {
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
color: #00000055;
caret-color: black;
}
<div class="scrollable">
<div id="view" class="content">
<textarea id="editor" class="content" onInput="update();" class="content"></textarea>
<div id="richtext" class="content"></div>
</div>
</div>
答案 0 :(得分:4)
您是否需要textarea
和基础div?我最近试图寻找一个好的富文本编辑器,并且注意到许多现代的文本编辑器都在使用,只是一个带有contenteditable="true"
作为HTML5属性的div。这是现实世界中的一些good examples。
如果您确实需要坚持使用这两个元素,那么我将通过重置所有属性将它们分解为裸机:
textarea,
.preview {
all: initial;
}
然后建立文本样式,因此两者完全相同。 font-family
,font-size
,font-weight
,line-height
等。我还要确保对CSS进行了很好的重置或归一化。
问题在于,浏览器在文本区域中对待文本呈现的方式与在其他地方不同,因此目标是通过使用一些笨拙的方式来迫使它们相同。
答案 1 :(得分:1)
将类 .content 从min-height:100%;
更改为min-height:100vh;
,还将white-space: pre;
更改为white-space: pre-wrap;
这是更新的小提琴:
function update() {
document.getElementById("richtext").innerHTML =
document.getElementById("editor").value;
}
.scrollable {
width: 300px;
height: 100px;
overflow: scroll;
border: 1px solid grey;
}
.content {
font-family: monospace;
font-size: 18px;
position: absolute;
top: 0;
left: 0;
border: none;
overflow: hidden;
min-width: 100%;
min-height: 100vh;
outline: none;
resize: none;
margin: none;
padding: 0;
box-shadow: none;
box-sizing: border-box;
white-space: pre-wrap;
display: block;
overflow: none;
}
#richtext {
z-index: -10;
color: orange;
}
#view {
height: 100%;
position: relative;
display: inline-block;
}
#editor {
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
color: #00000055;
caret-color: black;
}
<div class="scrollable">
<div id="view" class="content">
<textarea id="editor" class="content" onInput="update();" class="content"></textarea>
<div id="richtext" class="content"></div>
</div>
</div>
答案 2 :(得分:1)
对齐方式不同步,因为最终您将超过文本区域的定义高度,并且内部滚动开始。
为避免这种情况,请更新文本区域的高度,使其自动扩展。
function update(){
richtext.innerHTML = editor.value;
editor.style.width = 'auto';
editor.style.width = editor.scrollWidth+'px';
editor.style.height = 'auto';
editor.style.height = editor.scrollHeight+'px';
}
var richtext = document.getElementById("richtext")
var editor = document.getElementById("editor")
function update(){
richtext.innerHTML = editor.value;
editor.style.width = 'auto';
editor.style.width = editor.scrollWidth+'px';
editor.style.height = 'auto';
editor.style.height = editor.scrollHeight+'px';
}
.scrollable {
width: 300px;
height: 100px;
overflow: scroll;
border : 1px solid grey;
}
.content {
font-family: monospace;
font-size: 18px;
position: absolute;
top: 0;
left: 0;
border: none;
overflow: hidden;
min-width: 100%;
min-height: 100%;
outline: none;
resize: none;
margin: none;
padding: 0;
box-shadow: none;
box-sizing: border-box;
white-space: pre;
display: block;
overflow: none;
}
#richtext {
z-index: -10;
color: orange;
}
#view {
height: 100%;
position: relative;
display: inline-block;
}
#editor {
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
color: #00000055;
caret-color: black;
}
<div class="scrollable">
<div id="view" class="content">
<textarea id="editor" class="content" onInput="update();" class="content"></textarea>
<div id="richtext" class="content"></div>
</div>
</div>
编辑:宽度也一样。
答案 3 :(得分:1)
您已经使用了绝对位置。因此,div和textarea彼此放置。删除div和textarea的位置,最小宽度和最大宽度。并将display:flex-inline用于div#view; 您可以更改空白值以获得更好的效果。