JSFiddle - React, Tailwind, and code Playground
by Kanatantsin
HTML
<div class="text-editor" id="editor">
<div class="text-editor__title">
Имя файла: <span class="text-editor__filename">(документ)</span>
</div>
<textarea class="text-editor__content"></textarea>
<div class="text-editor__hint">
<div class="text-editor__hint-content">
Перенесите и отпустите .txt файл для загрузки содержимого в редактор
</div>
</div>
</div>
CSS
body, html {
height: 100%;
}
body {
margin: 0;
font-family: Verdana;
}
.text-editor {
display: flex;
flex-direction: column;
height: 100%;
padding: 20px;
box-sizing: border-box;
position: relative;
}
.text-editor__title {
margin-bottom: 10px;
}
.text-editor__hint {
display: none;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba( 255, 255, 255, 0.9 );
justify-content: center;
align-items: stretch;
font-size: 30px;
padding: 20px;
box-sizing: border-box;
}
.text-editor__hint-content {
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
border: 4px dashed gray;
color: gray;
}
.text-editor__hint_visible {
display: flex;
}
.text-editor__content {
flex-grow: 1;
border: 1px solid #CCC;
}
JavaScript
const throttle = ( handler, ms ) => {
let timeout;
return () => {
clearTimeout( timeout );
timeout = setTimeout( handler, ms );
}
};
class TextEditor {
constructor( container, storageKey = '_text-editor__content' ) {
this.container = container;
this.contentContainer = container.querySelector( '.text-editor__content' );
this.hintContainer = container.querySelector( '.text-editor__hint' );
this.filenameContainer = container.querySelector( '.text-editor__filename' );
this.storageKey = storageKey;
this.registerEvents();
this.load( this.getStorageData());
}
registerEvents() {
const save = throttle( this.save.bind( this ), 1000 );
this.contentContainer.addEventListener( 'input', save );
this.container.addEventListener('dragover', (event) => this.showHint.call(this, event));
this.container.addEventListener('drop', (event) => this.loadFile.call(this, event));
}
loadFile(e) {
e.preventDefault();
this.hideHint();
this.readFile(e.dataTransfer.files[0]);
}
readFile(file) {
console.log(file);
if (file.type == 'text/plain') {
const reader = new FileReader();
this.contentContainer.value = '';
this.setFilename(file.name);
reader.addEventListener('load', event => {
this.contentContainer.value = event.currentTarget.result;
});
reader.readAsText(file);
} else {
this.contentContainer.value = 'Сюда можно перетаскивать только файлы в формате .txt';
}
}
setFilename(filename) {
this.filenameContainer.textContent = filename;
}
showHint(e) {
e.preventDefault();
console.log(e);
console.log(document.elementFromPoint(event.clientX, event.clientY));
this.hintContainer.classList.add('text-editor__hint_visible');
}
hideHint() {
this.hintContainer.classList.remove('text-editor__hint_visible');
}
load(value) {
this.contentContainer.value = value || '';
}
...