Обрамление тегами выделенного текста
Не хочется изобретать велосипед: эта функция работает во многих движках форумов, включая и этот. Нажимаешь на кнопку "Вставить ссылку" и выходит всплывающее окно, которое, после ввода необходимой информации вставляет её в выделенный текст.
Вот, пример: форум <- сделанный скриптом данного движка. Вопрос: где найти читабельный пример подобного кода? Понимаю, что это где-то в файле типа ckeditor.js, но JS код там сжат и достать его быстро не получается. Есть примеры на Stack Overflow, но там без всплывающего окна для ввода URL. |
<script>
function addLink() {
const textarea = document.querySelector("TextArea");
const text = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
const href = prompt("Адрес ссылки", "https://javascript.ru/forum/misc/");
textarea.value = `${textarea.value.substr(0, textarea.selectionStart)}<a href='${href}'>${text}</a>${textarea.value.substr(textarea.selectionEnd)}`;
document.body.appendChild(code);
}
</script>
<body>
<button onclick='addLink()'>Добавить ссылку</button>
<textarea>Ссылка#1 Ссылка№2</textarea>
</body>
|
Alikberov,
а выделенный текст где? :no: автор просит это ![]() |
Цитата:
|
Alikberov,
после строки 5 if(!href) return; и if(!text) text = href; или так <a href='${href}'>${text||href} |
Цитата:
|
Всем спасибо, но "не работает". :(
Точнее: сам пример решения конечно рабочий, но как только начинаешь его встраивать в свою систему - отказ. Пробовал 2 варианта: 1. Целиком указанный код на страницу перлового скрипта. Получаю серверную ошибку: Not enough arguments for substr at ... near "selectionEnd)" Ругается вот на эту строку:
textarea.value = `${textarea.value.substr(0, textarea.selectionStart)}<a href='${href}'>${text}</a>${textarea.value.substr(textarea.selectionEnd)}`;
Почему Perl падает из-за JS сказать затрудняюсь. 2. Вынос скрипта во внешний файл выдает следующую ошибку: "addLink" не определено. Вроде бы всё правильно, но не работает - ничего не происходит. Да, "button" заменил на <a href="#" onclick="addLink()">Add Link</a> Буду признателен за подсказку: что я сделал не так? |
<script>
function addLink(button) {
const textarea = button.parentNode.TextAreaTag;
const href = prompt("Адрес ссылки", "https://javascript.ru/forum/misc/");
const text = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd) || href;
if(!href)
return;
*!*
// Определите один из этих двух рабочих вариантов
if("ticks" in button.dataset)
textarea.value = `${textarea.value.substr(0, textarea.selectionStart)}<a href='${href}'>${text}</a>${textarea.value.substr(textarea.selectionEnd)}`;
else
textarea.value = textarea.value.substr(0, textarea.selectionStart) + "<a href='" + href + "'>" + text + "</a>" + textarea.value.substr(textarea.selectionEnd);
*/!*
document.body.appendChild(code);
}
</script>
<body>
<form>
<a href='#' onclick='addLink(this)' data-ticks><img src='https://javascript.ru/forum/images/editor/createlink.gif'></a>
<a href='#' onclick='addLink(this)'><img src='https://javascript.ru/forum/images/editor/createlink.gif'></a><br>
<textarea name=TextAreaTag rows=3 cols=80>
Ссылка#1
Ссылка№2
</textarea>
</form>
</body>
|
Вот этот вариант со строкой
textarea.value = textarea.value.substr(0, textarea.selectionStart) + "<a href='" + href + "'>" + text + "</a>" + textarea.value.substr(textarea.selectionEnd); мне более понятен и он работает в моем случае. Спасибо! Но есть еще 1 нюанс. В моем случае в форме используются 2 textarea, но мне бы хотелось обойтись одной кнопкой для них. В любом случае выделить текст можно только в одной textarea, соответственно в нее и надо вставлять модифицированную строку. Вопрос: чем заменить "textarea.value"? Ведь у нас две одинаковых textarea, естественно с разными именами и идентификаторами. |
<script>
function addLink(button) {
if(button.parentNode.dataset.focused) {
const textarea = button.parentNode[button.parentNode.dataset.focused];
const href = prompt("Адрес ссылки", "https://javascript.ru/forum/misc/");
const text = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd) || href;
const pos = textarea.selectionStart;
if(href)
textarea.value = textarea.value.substr(0, textarea.selectionStart) + "<a href='" + href + "'>" + text + "</a>" + textarea.value.substr(textarea.selectionEnd);
textarea.focus();
textarea.selectionStart = textarea.selectionEnd = pos;
}
}
</script>
<body>
<form data-focused>
<a href='#' onclick='addLink(this)'><img src='https://javascript.ru/forum/images/editor/createlink.gif'></a><br>
<textarea name=TextAreaTag rows=3 cols=80 onfocus='this.parentNode.dataset["focused"] = this.name'>
Ссылка#1
Ссылка№2
</textarea><br>
<textarea name=TextAreaTaq rows=3 cols=80 onfocus='this.parentNode.dataset["focused"] = this.name'>
Ссылка#3
Ссылка№4
</textarea>
</form>
</body>
|
Этот вариант не подходит. Надо переписывать программный код которым создаются формы, textarea и т.п. Проще вторую кнопку воткнуть для 2-й textarea.
И у меня еще один вопрос: как проверить href регуляркой? На Perl это выглядело бы так:
if ($url =~ m/^http/) {
...
} else {
...
}
|
Разобрался со вторым вопросом:
if (href.match(/^(http)/)) {
|
Цитата:
<script>
var lastTextArea; // Сохраняет ссылку на TextArea под фокусом при нажатии на кнопку вставки ссылки
var lastUserLink = "https://javascript.ru/forum/misc/"; // Сохраняет адрес последней введенной ссылки
function addLink(button) {
if(button.parentNode.contains(lastTextArea)) {
const href = prompt("Адрес ссылки", lastUserLink);
const text = lastTextArea.value.substring(lastTextArea.selectionStart, lastTextArea.selectionEnd) || href;
const injected = "<a href='" + href + "'>" + text + "</a>";
const from = lastTextArea.selectionStart;
let last = lastTextArea.selectionEnd;
if(href) {
lastUserLink = href; // Запоминаем адрес введённой ссылки
lastTextArea.value = lastTextArea.value.substr(0, from) + injected + lastTextArea.value.substr(last);
last = from + injected.length; // Корректируем выделение, чтобы охватить вставляемый тег ссылки
}
lastTextArea.focus(); // Возвращаем фокус и восстанавливаем выделение
lastTextArea.selectionStart = from;
lastTextArea.selectionEnd = last;
}
}
</script>
<body>
<form>
<a href='#' onfocus='lastTextArea = event.relatedTarget' onclick='addLink(this)'><img src='https://javascript.ru/forum/images/editor/createlink.gif'></a><br>
<textarea rows=3 cols=80>
Ссылка#1
Ссылка№2
</textarea><br>
<textarea rows=3 cols=80>
Ссылка#3
Ссылка№4
</textarea>
</form>
</body>
|
Теперь другая проблема: это не работает в IE 11. :(
|
Еще вопрос: а может быть решать эту задачу другим способом? Не привязываться к каким либо тегам, а работать с выделенным текстом. Т.е. сохранять его где-то, затем обрабатывать добавляя введенную из всплывающего окна информацию (URL в данном случае) и возвращать модифицированный текст обратно, заменяя выделенный и снимая выделение.
Что-то типа этого возможно?
function getSelectionText() {
var txt = '';
txt = window.getSelection().toString();
const href = prompt("Link URL", "");
txt.value = txt + href;
}
Вариант не работает, но смысл думаю понятен. |
| Часовой пояс GMT +3, время: 21:51. |