Beispiel:JS-Wysiwyg-Editor-3.html

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
<!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>