Вам нужно предотвратить событие по умолчанию после нажатия кнопки.
e.preventDefault(); // Do not submit!
Также я полировал логи c в шифре, чтобы учесть отрицательные сдвиги.
Примечание: нет никаких причин для вызова смены, если сумма равна нулю, просто верните входящее сообщение ... если только вы на самом деле не хотите, чтобы он очищал сообщение от буквенных символов.
Обновление: Добавлена динамическая форма c без кнопки.
Обратите внимание на удобную функцию addEventListeners
, которую я создал ниже. Это позволяет добавить событие к нескольким элементам для множества различных типов событий. Это в лучшем случае элементарно, но экономит ваше время при добавлении каждого слушателя событий. Лучшим подходом был бы объект. Я, вероятно, добавлю альтернативный пример внизу.
const caesarShift = (str, amount) => {
const LOWER_A = 'a'.charCodeAt(0) , LOWER_Z = 'z'.charCodeAt(0),
UPPER_A = 'A'.charCodeAt(0) , UPPER_Z = 'Z'.charCodeAt(0),
SIZE = LOWER_Z - LOWER_A ;
if (amount === 0) return str;
let output = '';
for (let i = 0; i < str.length; i++) {
let c = str[i];
if (c.match(/[a-z]/i)) {
let offset = -1, code = str.charCodeAt(i);
if (code >= LOWER_A && code <= LOWER_Z) {
offset = LOWER_A;
} else if (code >= UPPER_A && code <= UPPER_Z) {
offset = UPPER_A;
}
if (offset !== -1) {
c = String.fromCharCode(offset + ((code - offset) + amount + SIZE) % SIZE);
}
}
output += c;
}
return output;
};
const form = document.forms['caesar-1'];
form.querySelector('button').addEventListener('click', (e) => {
form.result.value = caesarShift(
form.message.value,
parseInt(form.amount.value, 10)
);
e.preventDefault(); // Do not submit!
});
const form2 = document.forms['caesar-2'];
addEventListeners('input, textarea', 'change keyup', (e) => {
form2.result.value = caesarShift(
form2.message.value,
parseInt(form2.amount.value, 10)
);
}, form2);
// Initial change events
triggerEvent(form.querySelector('button'), 'click');
triggerEvent(form2.message, 'change');
// Custom functions to make life easier...
function addEventListeners(selector, eventNames, eventFn, scope) {
scope = scope || document;
const names = eventNames.split(/\s+/g);
selector.split(/\s*,\s*/).forEach(sel => {
Array.from(scope.querySelectorAll(sel)).forEach(el => {
names.forEach(eventName => el.addEventListener(eventName, eventFn));
});
});
}
function triggerEvent(el, eventName) {
let event = document.createEvent('HTMLEvents');
event.initEvent(eventName, true, false);
el.dispatchEvent(event);
}
hr { margin: 1em 0; }
.form-field {
margin-bottom: 0.5em;
}
.form-field label {
display: inline-block;
width: 4em;
font-weight: bold;
}
form button {
margin-left: 5em;
margin-bottom: 0.5em;
}
.form-field-stacked {
display: inline-block;
vertical-align: top;
margin-right: 0.5em;
}
.form-field-stacked label {
display: block;
margin-bottom: 0.25em;
width: auto;
}
.form-field-stacked input[type="number"] {
width: 3em;
}
<h2>Button Form</h2>
<form name="caesar-1">
<div class="form-field">
<label>Message</label>
<input name="message" type="text" value="Hello World"/>
</div>
<div class="form-field">
<label>Amount</label>
<input name="amount" type="number" value="13" />
</div>
<button>Rotate</button>
<div class="form-field">
<label>Output</label>
<input name="result" type="text" disabled="disabled" />
</div>
</form>
<hr />
<h2>Dynamic Form</h2>
<form name="caesar-2">
<div class="form-field form-field-stacked">
<label>Message</label>
<textarea name="message" rows="4" cols="24">Hello World</textarea>
</div>
<div class="form-field form-field-stacked">
<label>Amount</label>
<input name="amount" type="number" value="13" />
</div>
<div class="form-field form-field-stacked">
<label>Output</label>
<textarea name="result" rows="4" cols="24" disabled="disabled"></textarea>
</div>
</form>
Еще более динамическая c функция прослушивания событий.
const caesarShift=(t,e)=>{if(r="a".charCodeAt(0),a="z".charCodeAt(0),o="A".charCodeAt(0),c="Z".charCodeAt(0),h=a-r,0===e)return t;let C="";for(let d=0;d<t.length;d++){let A=t[d];if(A.match(/[a-z]/i)){let C=-1,f=t.charCodeAt(d);f>=r&&f<=a?C=r:f>=o&&f<=c&&(C=o),-1!==C&&(A=String.fromCharCode(C+(f-C+e+h)%h))}C+=A}return C};
const form = document.forms['caesar'];
const handleUpdate = (e) => {
form.result.value = caesarShift(
form.message.value,
parseInt(form.amount.value, 10)
);
}
addEventListeners({
selector : 'input',
listeners : {
'change' : handleUpdate,
'keyup' : handleUpdate
},
scope: form
}, {
selector : 'textarea',
listeners : {
'change' : handleUpdate,
'keyup' : handleUpdate
},
scope: form
});
// Initial change events
triggerEvent(form.message, 'change');
// Custom functions to make life easier...
function addEventListeners(...configs) {
configs.forEach(config => {
let options = config.options || {};
let els = Array.from((config.scope || document).querySelectorAll(config.selector));
Object.keys(config.listeners || {}).forEach(eventName => {
els.forEach(el => {
el.addEventListener(eventName, config.listeners[eventName], options)
});
});
});
}
function triggerEvent(el, eventName) {
let event = document.createEvent('HTMLEvents');
event.initEvent(eventName, true, false);
el.dispatchEvent(event);
}
.form-field {
margin-bottom: 0.5em;
}
.form-field label {
font-weight: bold;
}
.form-field-stacked {
display: inline-block;
vertical-align: top;
margin-right: 0.5em;
}
.form-field-stacked label {
display: block;
margin-bottom: 0.25em;
width: auto;
}
.form-field-stacked input[type="number"] {
width: 3em;
}
<h2>Dynamic Form</h2>
<form name="caesar">
<div class="form-field form-field-stacked">
<label>Message</label>
<textarea name="message" rows="4" cols="24">Hello World</textarea>
</div>
<div class="form-field form-field-stacked">
<label>Amount</label>
<input name="amount" type="number" value="13" />
</div>
<div class="form-field form-field-stacked">
<label>Output</label>
<textarea name="result" rows="4" cols="24" disabled="disabled"></textarea>
</div>
</form>