Beispiel:JS-Wysiwyg-Editor-3.html
Aus SELFHTML-Wiki
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" media="screen" href="./Beispiel:SELFHTML-Beispiel-Grundlayout.css">
<title>WYSIWYG-Editor</title>
<style>
#editor {
width: 60vmin;
height: 60vmin;
border: 1px solid;
padding: 0.2rem;
}
#content-area > * {
width: calc(100% - 0.4rem);
height: 55vmin;
}
#content-area > * {
display: none;
}
#content-area > .active {
display: block;
}
#wysiwyg {
border: 1px solid #306f91;
}
#html {
border-color: #dfac20;
background-color: #fdfcf3;;
}
button {
width:2rem;
height: 2rem;
background: white;
border: thin solid black;
border-radius: 0 .3rem .3rem;
margin: 0.2rem;
padding: 0.2rem;
font-size: 1.3rem;
}
button:hover,
button:focus {
background-color: #ccc;
}
[data-action="bold"]{
font-weight: bold;
}
[data-action="cursive"]{
font-style: italic;
}
[data-action="underline"]{
font-style: italic;
text-decoration: underline;
}
[data-action="quote"]{
background-image: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' x='0px' y='0px' viewBox='0 0 70 70' %3E%3Cpath id='quot' d='M10,20 h20 v18 a20,20 1 0,1 -20,20 v-8 a15,15 0 0,0 10,-10 h-10' fill='%23000'/%3E%3Cuse href='%23quot' x='32' /%3E%3C/svg%3E");
color: transparent;
}
[data-action="send"]{
width: 5.5rem;
background-color: #ebf5d7;
}
[data-action="send"]:hover,
[data-action="send"]:focus {
background-color: #8db243;
}
[data-action="view"]{
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 2000 1892' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M703 1399l-50 50q-10 10-23 10t-23-10l-466-466q-10-10-10-23t10-23l466-466q10-10 23-10t23 10l50 50q10 10 10 23t-10 23l-393 393 393 393q10 10 10 23t-10 23zm591-1067l-373 1291q-4 13-15.5 19.5t-23.5 2.5l-62-17q-13-4-19.5-15.5t-2.5-24.5l373-1291q4-13 15.5-19.5t23.5-2.5l62 17q13 4 19.5 15.5t2.5 24.5zm657 651l-466 466q-10 10-23 10t-23-10l-50-50q-10-10-10-23t10-23l393-393-393-393q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l466 466q10 10 10 23t-10 23z'/%3E%3C/svg%3E");
color: transparent;
float: right;
}
::selection {
background-color: gold;
}
</style>
</head>
<body>
<h1>WYSIWYG-Editor</h1>
<p>Wählen Sie Text mit der Maus aus!</p>
<div id="editor">
<div id="toolbar">
<button data-action="bold">F</button>
<button data-action="cursive">k</button>
<button data-action="underline">U</button>
<button data-action="quote">Zitat</button>
<button data-action="send">Senden</button>
<button data-action="view">Ansicht</button>
</div>
<div id="content-area">
<div id="wysiwyg" contenteditable></div>
<textarea id="html" class="active"><p>Dies ist ein <b>Beispiel-Satz</b> innerhalb der textarea.</p></textarea>
</div>
</div>
<script>
'use strict';
document.addEventListener('DOMContentLoaded', function () {
const wysiwygView = document.querySelector('#wysiwyg');
const htmlView = document.querySelector('#html');
const toolbar = document.querySelector('#toolbar');
toolbar.addEventListener('click', handleToolbarAction);
function handleToolbarAction(event) {
const action = event.target.getAttribute('data-action');
if (!action) return;
if (action === 'view') {
toggleView();
} else {
const activeElement = wysiwygView.classList.contains('active') ? wysiwygView : htmlView;
formatSelectedText(action, activeElement);
}
}
function toggleView() {
if (wysiwygView.classList.contains('active')) {
htmlView.value = wysiwygView.innerHTML.trim();
} else {
wysiwygView.innerHTML = htmlView.value.trim();
}
wysiwygView.classList.toggle('active');
htmlView.classList.toggle('active');
}
function formatSelectedText(action, activeElement) {
if (activeElement === wysiwygView) {
formatInWysiwyg(action);
} else if (activeElement === htmlView) {
formatInTextarea(action);
}
}
function formatInWysiwyg(action) {
const selection = window.getSelection();
if (!selection.rangeCount) return;
const range = selection.getRangeAt(0);
const selectedText = range.toString();
if (!selectedText) return;
const tagMap = {
bold: 'b',
cursive: 'i',
underline: 'u',
quote: 'blockquote',
};
const wrapperTag = tagMap[action];
if (!wrapperTag) return;
// Wrap the selected text in the specified tag
const wrapper = document.createElement(wrapperTag);
wrapper.textContent = selectedText;
range.deleteContents();
range.insertNode(wrapper);
ensureValidHTMLStructure(wysiwygView);
}
function formatInTextarea(action) {
const start = htmlView.selectionStart;
const end = htmlView.selectionEnd;
const selectedText = htmlView.value.substring(start, end);
if (!selectedText) return;
const tagMap = {
bold: ['<b>', '</b>'],
cursive: ['<i>', '</i>'],
underline: ['<u>', '</u>'],
quote: ['<blockquote>', '</blockquote>'],
};
const tags = tagMap[action];
if (!tags) return;
const before = htmlView.value.substring(0, start);
const after = htmlView.value.substring(end);
htmlView.value = `${before}${tags[0]}${selectedText}${tags[1]}${after}`;
htmlView.setSelectionRange(start + tags[0].length, start + tags[0].length + selectedText.length);
}
function ensureValidHTMLStructure(container) {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = container.innerHTML;
container.innerHTML = tempDiv.innerHTML;
}
});
</script>
</body>
</html>