Reputation: 9293
Trying to create a simple html editor.
$('#edit').on('input', function(e){
console.log($(this).html());
});
.edit{
background:gold;
min-height:140px;
font-size:1.6em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='edit' id='edit' contenteditable></div>
type this inside the div edit
:
lorem
ipsum
then place the cursor at the end of lorem
- and press spacebar
and del
on keyboard to get this:
lorem ipsum
and you'll see the problem - ipsum
has much larger font size then lorem
.
That's the first question - how to avoid this?
My second try was using textarea
instead of contenteditable div but in that case I cannot use document.execCommand
to change some text to be bold
etc.
So what is the way to set html tags inside textarea
like it's done here on stackoverflow
, or on wordpress
sites and so on?
My final goal is to provide a simple editor with just a a few commands - bold, italic and align
Users should be able to type and style the text, and click on a button should get the html content.
Any help?
Upvotes: 2
Views: 2805
Reputation: 43880
.execCommand()
Try loading the first parameter dynamically by assigning the #id
of each <button>
to match a command.
<button id="bold">B</button> ... ... var ID = this.id; return document.execCommand(ID, false, null)
$('#WYSINWYE').on('submit', function() {
return false;
});
$('#edit').focus();
$('#edit').on('keyup', function() {
$('#view').html($(this).text());
});
$('#ctrl button').on('click', function() {
var ID = this.id;
if (ID === 'HTML') {
$('#view').slideToggle('750')
return;
}
return document.execCommand(ID, false, null);
});
form {
width: 100%;
height: fit-content;
font: 400 16px/1.25 Arial;
}
#view {
background: gold;
min-height: 100px;
font: inherit;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
#ctrl {
height: 20px;
}
#edit {
font: inherit;
font-family: Consolas;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
}
button {
display: inline-block;
font: inherit;
width: 36px;
height: 24px;
line-height: 24px;
margin: 0 -2px;
vertical-align: middle;
cursor: pointer;
border-radius: 1px;
}
b:hover,
button:hover {
color: rgba(205, 121, 0, 0.8);
}
#HTML {
float: right
}
#ctrl button:first-of-type {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
#ctrl button:nth-of-type(6) {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
#ctrl button:last-of-type {
border-radius: 4px;
}
<link href="//use.fontawesome.com/releases/v5.7.2/css/all.css" rel="stylesheet" crossorigin="anonymous">
<form id='WYSINWYE'>
<fieldset id='view' class='text' contenteditable='false' style='display:none'>
</fieldset>
<fieldset id='ctrl'>
<button id='bold' class="fas fa-bold"></button>
<button id='italic' class="fas fa-italic"></button>
<button id='underline' class="fas fa-underline"></button>
<b>|</b>
<button id='justifyLeft' class="fas fa-align-left"></button>
<button id='justifyCenter' class="fas fa-align-center"></button>
<button id='justifyRight' class="fas fa-align-right"></button>
<button id='HTML' class="fas fa-code"></button>
</fieldset>
<fieldset id='edit' class='text' contenteditable='true'>
</fieldset>
</form>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 0
Reputation: 18493
As pointed out by many angry developers, contenteditable
is indeed terrible - don't expect anything great, but let's try to make do anyway.
By wrapping the editable div inside another div and applying the CSS font to this wrapper, the text shall not get bigger when doing the process described in the question. The HTML is still ugly (useless span tags with 1em of font size), but the text content is acceptable.
const editable = document.querySelector('div[contenteditable]');
editable.onkeyup = () => {
document.querySelector('#html-log').innerText = editable.innerHTML;
document.querySelector('#text-log').innerText = JSON.stringify(editable.innerText);
}
#wrapper {
font-size: 1.2em;
}
div[contenteditable] {
width: 100%;
height: 100%;
border: solid;
font-size: 1em;
}
<div id="wrapper">
<div contenteditable></div>
</div>
<h3>HTML content</h3>
<pre id="html-log"></pre>
<h3>Text content</h3>
<pre id="text-log"></pre>
Upvotes: 2