3.4 KiB
CSS для решения
Как видно из исходного кода, #view
-- это <div>
, который будет содержать результат, а #area
- это редактируемое текстовое поле.
Так как мы преобразуем <div>
в <textarea>
и обратно, нам нужно сделать их практически одинаковыми с виду:
#view,
#area {
height: 150px;
width: 400px;
font-family: arial;
font-size: 14px;
}
Текстовое поле нужно как-то выделить. Можно добавить границу, но тогда изменится блок: он увеличится в размерах и немного съедет текст.
Для того, чтобы сделать размер #area
таким же, как и #view
, добавим поля(padding):
#view {
/* padding + border = 3px */
padding: 2px;
border: 1px solid black;
}
CSS для #area
заменяет поля границами:
#area {
border: 3px groove blue;
padding: 0px;
display: none;
}
По умолчанию, текстовое поле скрыто. Кстати, этот код убирает дополнительную рамку в ряде браузеров, которая появляется вокруг поля, когда на него попадает фокус:
/*+ no-beautify */
#area:focus {
outline: none; /* убирает рамку при фокусе */
}
Горячие клавиши
Чтобы отследить горячие клавиши, нам нужны их скан-коды, а не символы. Это важно, потому что горячие клавиши должны работать независимо от языковой раскладки. Поэтому, мы будем использовать keydown
:
document.onkeydown = function(e) {
if (e.keyCode == 27) { // escape
cancel();
return false;
}
if ((e.ctrlKey && e.keyCode == 'E'.charCodeAt(0)) && !area.offsetHeight) {
edit();
return false;
}
if ((e.ctrlKey && e.keyCode == 'S'.charCodeAt(0)) && area.offsetHeight) {
save();
return false;
}
};
В примере выше, offsetHeight
используется для того, чтобы проверить, отображается элемент или нет. Это очень надежный способ для всех элементов, кроме <tr>
в некоторых старых браузерах.
В отличие от простой проверки display=='none'
, этот способ работает с элементом, спрятанным с помощью стилей, а так же для элементов, у которых скрыты родители.
Редактирование
Следующие функции переключают режимы. HTML-код разрешен, поэтому возможна прямая трансформация в <textarea>
и обратно.
function edit() {
view.style.display = 'none';
area.value = view.innerHTML;
area.style.display = 'block';
area.focus();
}
function save() {
area.style.display = 'none';
view.innerHTML = area.value;
view.style.display = 'block';
}
function cancel() {
area.style.display = 'none';
view.style.display = 'block';
}