ব্যবহারকারী <textarea>-এ Enter প্রেস করলে, অনেক চ্যাট ইন্টারফেস তাদের মেসেজ জমা দেয়।
এটি সেইসব ব্যবহারকারীর জন্য কাজ করে যারা সরাসরি ল্যাটিন কীবোর্ড ইনপুট (যেমন, ইংরেজি) ব্যবহার করে টাইপ করেন, কিন্তু জাপানি, চাইনিজ বা কোরিয়ানের মতো ভাষায় টেক্সট কম্পোজ করার জন্য ইনপুট পদ্ধতি সম্পাদক (IME) ব্যবহার করে টাইপ করা ব্যবহারকারীদের জন্য কাজ করে না।
এইসব ক্ষেত্রে, বর্তমান অক্ষর কনভার্সন ক্যান্ডিডেট কনফার্ম করতে Enter/Return কী ব্যবহার করা হয়। কাস্টম জাভাস্ক্রিপ্ট যদি Enter-এ keydown শোনে এবং সাথে সাথে জমা দেয়, তাহলে ব্যবহারকারীর মেসেজ পাঠানো হয় যখন তারা এখনও অক্ষর কনভার্ট করছেন, যার ফলে অসম্পূর্ণ, খণ্ডিত বা ভুল মেসেজ পাঠানো হয়।
কম্পোজিশন-অ্যাক্টিভ চেক যেকোনও কাস্টম keydown হ্যান্ডলারের ক্ষেত্রে প্রযোজ্য হয় যা Enter-এ কাজ করে, শুধু মাল্টিলাইন <textarea> ফিল্ডের ক্ষেত্রে নয়। সিঙ্গেল-লাইন <input> ফিল্ড, যেগুলি নিজস্ব Enter হ্যান্ডেল করে, যেমন সার্চ ও ফাইন্ড বার, ইনলাইন রিনেম ফিল্ড, মোডাল ডায়ালগ ফিল্ড ও কমান্ড প্যালেট, সেগুলি <textarea>-এর মতো একই IME-কনফার্মিং Enter কীডাউন পায়, যেখানে isComposing-কে true-এ সেট করা থাকে। কোনও কাস্টম Enter হ্যান্ডলার ছাড়া <input> থেকে <form>-এর নেটিভ ইমপ্লিসিট জমা দেওয়ার জন্য কোনও এক্সপ্লিসিট হ্যান্ডলিংয়ের প্রয়োজন হয় না, কারণ Enter কিস্ট্রোক কোনও IME-এর মাধ্যমে ব্যবহার করা হলে ব্রাউজার ইমপ্লিসিট জমা দেওয়াকে সাপ্রেস করে।
প্রয়োগ করার স্ট্র্যাটেজি
কাস্টম এন্টার-টু-সাবমিট সহ <textarea> বা <input>-এর জন্য, কন্টেন্ট জমা দেওয়ার আগে KeyboardEvent-এর নেটিভ isComposing প্রপার্টি চেক করুন। এছাড়াও event.preventDefault() কল করুন: Enter-এর ডিফল্ট অ্যাকশন <textarea>-এ একটি নতুন লাইন যোগ করে এবং <form>-এর মধ্যে <input>-এ এটি ব্রাউজারের অন্তর্নিহিত জমা দেওয়ার প্রক্রিয়াকে ট্রিগার করে, যা দ্বিতীয়বার জমা দেবে।
<form id="chat-form">
<label for="chat-input" class="visually-hidden">Message</label>
<textarea id="chat-input" placeholder="Type a message..."></textarea>
<button type="submit" id="send-button">Send</button>
</form>
const textarea = document.getElementById('chat-input');
const form = document.getElementById('chat-form');
textarea.addEventListener('keydown', (event) => {
if (event.key === 'Enter' && !event.shiftKey) {
// Prevent the default action (newline in a textarea, implicit form submission in an input)
event.preventDefault();
// If the user is composing text, return early.
if (event.isComposing) {
return;
}
form.requestSubmit();
}
});
এক লাইনের <input>-এর জন্য, !event.shiftKey শর্ত ছাড়াই একই হ্যান্ডলার ব্যবহার করুন, যা শুধুমাত্র Shift+Enter-এর কারণে <textarea>-এ নতুন লাইন যোগ করে।
অ্যাক্সেসিবিলিটি ও টেস্টিং
- স্পষ্ট সাবমিট বোতাম: সবসময়
<button type="submit">এলিমেন্ট অন্তর্ভুক্ত করুন। কীবোর্ড শর্টকাট হল সাহায্যকারী; এগুলি নেটিভ ফর্ম জমা দেওয়ার পাথকে প্রতিস্থাপন করবে না। - অ্যাক্সেসযোগ্য ইনপুট: নিশ্চিত করুন যে সব
<input>এবং<textarea>এলিমেন্ট প্রোগ্রামগতভাবে<label>-এর সাথে যুক্ত, যা ম্যাচিংidএবংforঅ্যাট্রিবিউট ব্যবহার করে।
ফলব্যাক স্ট্র্যাটেজি
Safari-এর সাম্প্রতিক ভার্সনে, ইভেন্ট-অর্ডারিং সংক্রান্ত সমস্যার (WebKit বাগ 165004) কারণে, Enter keydown কনফার্ম করার আগেই স্ক্রিপ্ট হ্যান্ডলারের কাছে compositionend ডেলিভার করা হয়েছে, যদিও অন্তর্নিহিত ইভেন্টগুলি বিপরীত ক্রমে পাঠানো হয়েছিল। keydown হ্যান্ডলার রান করার সময়, event.isComposing আগে থেকেই false-এ রিসেট করা ছিল, যার অর্থ হল, শুধু স্ট্যান্ডার্ড চেক করলে, সময়ের আগে জমা দেওয়া আটকানো যেত না।
Safari-এর পুরনো ভার্সন এবং অন্যান্য প্ল্যাটফর্ম জুড়ে ক্রস-ব্রাউজার কম্প্যাটিবিলিটি সংক্রান্ত সহায়তা প্রয়োজন হলে, নিম্নলিখিত ফলব্যাক স্ট্র্যাটেজির মধ্যে যেকোনও একটি গ্রহণ করুন:
কৌশল ১: keyCode === 229 চেক যোগ করুন (সাজেস্ট করা হয়েছে)
event.keyCode === 229-এর জন্য চেক করার সাথে event.isComposing পেয়ার করার মাধ্যমে, আপনি নির্ভরযোগ্যভাবে Safari-এর আউট-অফ-অর্ডার কনফার্মিং Enter কীডাউন ধরতে পারবেন। এটি event.key === 'Enter' গেটের মধ্যে নেস্ট করা থাকে বলে, মোবাইল ভার্চুয়াল কীবোর্ড থেকে সুরক্ষিত থাকে, যা সাধারণ অক্ষর লেআউট এন্ট্রির জন্য 229 ব্যবহার করতে পারে।
textarea.addEventListener('keydown', (event) => {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
// Block submission if composing natively or if keyCode is 229
if (event.isComposing || event.keyCode === 229) {
return;
}
form.requestSubmit();
}
});
কৌশল ২: event.timeStamp উইন্ডো সংক্রান্ত সমাধান (বিকল্প)
যেসব কোডবেসে keyCode-এর মতো বন্ধ হয়ে যাওয়া API ব্যবহার করার অনুমতি নেই অথবা নির্দিষ্ট টার্গেট করা পরিবেশে 229 চেক করার ক্ষেত্রে কোনও সমস্যা থাকলে, আপনি ব্রাউজার-রিপোর্ট করা ইভেন্ট ডিসপ্যাচ টাইমস্ট্যাম্প ট্র্যাক করতে পারেন।
যেহেতু Safari কনফার্মিং Enter কীডাউন ইভেন্ট compositionend ইভেন্টের খুব কাছাকাছি পাঠায় (প্রায়শই ৫ মিলিসেকেন্ডের মধ্যে এবং কখনও কখনও হ্যান্ডলার ডেলিভারি অর্ডারের ইনভার্সনের কারণে কীডাউন টাইমস্ট্যাম্প কিছুটা আগে থাকে), তাই সময়ের পার্থক্য চেক করা অত্যন্ত নির্ভরযোগ্য এবং স্ট্যান্ডার্ড পরিস্থিতিতে মোবাইল ভার্চুয়াল কীবোর্ডে ফলস-পজিটিভ ট্রিগার করার সম্ভাবনা কম।
let lastCompositionEndAt = null;
textarea.addEventListener('compositionend', (event) => {
// IMPORTANT: Always use event.timeStamp, not Date.now() or performance.now().
// Handler-time measurements are vulnerable to drift when the main thread is blocked.
lastCompositionEndAt = event.timeStamp;
});
textarea.addEventListener('keydown', (event) => {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
if (event.isComposing) {
return;
}
// Block submission if the event occurs within a 50ms window of composition ending.
// Math.abs handles Safari's inverted event delivery timing bug.
if (
lastCompositionEndAt !== null &&
Math.abs(event.timeStamp - lastCompositionEndAt) < 50
) {
return;
}
form.requestSubmit();
}
});