求助:基于jQuery实现点击插入文本至Textarea并支持删除功能
Great question! Let's break this down step by step. First, we'll simplify your existing code to remove the drag-and-drop functionality you don't need. Then, we'll solve the deletion problem—since textareas only handle plain text, we can't embed clickable "X" buttons directly inside them, but we have two solid workarounds to choose from.
1. Simplify the Code: Remove Drag-and-Drop
First, let's strip out all the drag-and-drop related code to keep things clean. We'll keep only the click-to-insert logic, and tweak it to work with our deletion solutions later.
Simplified jQuery Code
$(document).ready(function() { // Handle click to insert text (or HTML, for our first workaround) $('#ClickWordList li').click(function() { const insertContent = $(this).text(); // We'll adjust this function based on which workaround you use insertAtCaret($('#txtMessage'), insertContent); return false; }); }); // Updated insertAtCaret function to work with both textarea and contenteditable function insertAtCaret(element, content) { if (element.is('textarea') || element.is('input')) { // Original textarea logic const el = element[0]; if (document.selection) { el.focus(); const sel = document.selection.createRange(); sel.text = content; el.focus(); } else if (el.selectionStart || el.selectionStart === 0) { const startPos = el.selectionStart; const endPos = el.selectionEnd; const scrollTop = el.scrollTop; el.value = el.value.substring(0, startPos) + content + el.value.substring(endPos, el.value.length); el.focus(); el.selectionStart = startPos + content.length; el.selectionEnd = startPos + content.length; el.scrollTop = scrollTop; } else { el.value += content; el.focus(); } } else if (element.attr('contenteditable') === 'true') { // Logic for contenteditable elements (to insert HTML) const sel = window.getSelection(); const range = sel.getRangeAt(0); range.deleteContents(); const contentNode = document.createRange().createContextualFragment(content); range.insertNode(contentNode); // Move cursor to end of inserted content range.setStartAfter(contentNode.lastChild); range.setEndAfter(contentNode.lastChild); sel.removeAllRanges(); sel.addRange(range); } }
Simplified HTML (Remove Drag Section)
<body> <div id="maincontainer"> <div id="contentwrapper"> <div id="maincolumn"> <div class="text"> <h2>Message Template</h2> <!-- We'll replace this textarea with a contenteditable div in Option 1 --> <textarea name="txtMessage" id="txtMessage" cols="80" rows="15"></textarea> </div> </div> </div> <div id="leftcolumn"> <fieldset> <legend>Click to insert template fields:</legend> <ul id="ClickWordList"> <li>{Text A}</li> <li>{Text B}</li> </ul> </fieldset> </div> </div> </body>
2. Workarounds for Deletion
Since textareas can't contain clickable buttons, here are two practical solutions:
Option 1: Use a contenteditable Div (Best User Experience)
This lets you insert text blocks with inline "X" buttons that users can click to delete specific fields directly in the editable area.
Updated HTML (Replace Textarea with Contenteditable Div)
<div id="txtMessage" contenteditable="true" style="width: 640px; height: 200px; border: 1px solid #ccc; padding: 8px; font-family: monospace;"></div>
Updated Click Handler (Insert HTML with Delete Buttons)
Modify the $('#ClickWordList li').click function in the jQuery code above to this:
$('#ClickWordList li').click(function() { const fieldText = $(this).text(); // Create a wrapped field with a delete button const insertContent = ` <span style="background: #f0f8ff; padding: 2px 6px; border-radius: 4px; margin: 0 4px; position: relative;"> ${fieldText} <button style="border: none; background: #ff4444; color: white; border-radius: 50%; width: 16px; height: 16px; font-size: 10px; line-height: 16px; padding: 0; margin-left: 4px; cursor: pointer;" class="delete-field">X</button> </span> `; insertAtCaret($('#txtMessage'), insertContent); // Bind delete button click event $('.delete-field').off('click').on('click', function() { $(this).parent().remove(); }); return false; });
This will insert styled field blocks with an "X" button—clicking the button removes just that field block.
Option 2: Placeholder Tags + External Delete Buttons (If You Need to Keep Textarea)
If you must use a textarea, insert unique placeholder tags (like {Text A}) and generate a list of delete buttons next to the textarea. Clicking a button removes the corresponding tag from the textarea.
Add HTML for Delete Buttons
Add this div right after the textarea:
<div id="fieldDeleteButtons" style="margin-top: 8px;"></div>
Updated Click Handler (Insert Tags and Generate Buttons)
Modify the $('#ClickWordList li').click function to this:
$('#ClickWordList li').click(function() { const fieldText = $(this).text(); // Insert the tag into the textarea insertAtCaret($('#txtMessage'), ` ${fieldText} `); // Create a delete button for this field const deleteBtn = $(`<button style="margin-right: 8px; padding: 4px 8px;">Delete ${fieldText}</button>`); deleteBtn.click(function() { // Remove the tag from the textarea const currentValue = $('#txtMessage').val(); $('#txtMessage').val(currentValue.replace(new RegExp(`\\s*${fieldText}\\s*`, 'g'), ' ').trim()); // Remove the button itself $(this).remove(); }); // Add the button to the container $('#fieldDeleteButtons').append(deleteBtn); return false; });
This will add a delete button for every field you insert—clicking the button removes that specific field from the textarea.
内容的提问来源于stack exchange,提问作者Sachith Wickramaarachchi

