অনক্লিক () এবং onblur () ক্রম ইস্যু


107

আমার কাছে একটি ইনপুট ক্ষেত্র রয়েছে যা একটি কাস্টম ড্রপ-ডাউন মেনু নিয়ে আসে। আমি নিম্নলিখিত কার্যকারিতা চাই:

  • যখন ব্যবহারকারী ইনপুট ফিল্ডের বাইরে যে কোনও জায়গায় ক্লিক করে, মেনুটি সরানো উচিত।
  • যদি আরও নির্দিষ্টভাবে বলা যায়, ব্যবহারকারী মেনুর ভিতরে কোনও ডিভের উপর ক্লিক করেন, মেনুটি সরিয়ে ফেলা উচিত এবং কোন ডিভ ক্লিক করা হয়েছিল তার ভিত্তিতে বিশেষ প্রসেসিং হওয়া উচিত।

আমার বাস্তবায়ন এখানে:

ইনপুট ক্ষেত্রে একটি onblur()ইভেন্ট রয়েছে যা innerHTMLব্যবহারকারীরা যখনই ইনপুট ফিল্ডের বাইরে ক্লিক করে মেনুটি মুছে ফেলবে (তার পিতামাতার একটি খালি স্ট্রিংয়ে সেট করে)। মেনুটির ভিতরে ডিভগুলিও এমন onclick()ইভেন্ট রয়েছে যা বিশেষ প্রক্রিয়াকরণ চালায়।

সমস্যাটি হ'ল onclick()মেনুটি ক্লিক করার পরে ইভেন্টগুলি কখনই আগুন দেয় না, কারণ ইনপুট ফিল্ডের onblur()আগুন জ্বলে ও মেনুটি মুছে দেয়, এস সহ onclick()!

আমি মেনু ডিভ ' onclick()কে onmousedown()এবং onmouseup()ইভেন্টগুলিতে বিভক্ত করে এবং মাউসের উপরে একটি বৈশ্বিক পতাকা সেট করে যা মাউস আপগুলিতে সাফ হয়ে গেছে, এই উত্তরটিতে যা প্রস্তাবিত হয়েছিল তার সমানভাবে সমস্যার সমাধান করেছি । onmousedown()আগে আগুন লাগার কারণে onblur(), onblur()মেনু ডিভগুলির একটিতে ক্লিক করা থাকলে পতাকাটি সেট করা হবে , তবে স্ক্রিনের অন্য কোনও জায়গায় থাকলে তা নয়। যদি মেনুটি ক্লিক করা হয়ে থাকে, আমি onblur()মেনুটি মোছা না করেই ততক্ষণে ফিরে আসি , তারপরে onclick()আগুনের অপেক্ষার জন্য অপেক্ষা করুন , সেই সময়ে আমি মেনুটি নিরাপদে মুছতে পারি।

এর থেকেও কি আরও সুন্দর সমাধান?

কোডটি এরকম কিছু দেখাচ্ছে:

<div class="menu" onmousedown="setFlag()" onmouseup="doProcessing()">...</div>
<input id="input" onblur="removeMenu()" ... />

var mouseflag;

function setFlag() {
    mouseflag = true;
}

function removeMenu() {
    if (!mouseflag) {
        document.getElementById('menu').innerHTML = '';
    }
}

function doProcessing(id, name) {
    mouseflag = false;
    ...
}

উত্তর:


177

আমি আপনার মতো ঠিক একই সমস্যাটি নিয়ে আসছিলাম, আমার ইউআইটি ঠিক আপনার যেমন বর্ণনা করেছেন তেমনভাবে তৈরি করা হয়েছে। আমি কেবল onClickমেনু আইটেমগুলির সাথে একটি দ্বারা প্রতিস্থাপন করে সমস্যার সমাধান করেছি onMouseDown। আমি আর কিছু করিনি; না onMouseUp, কোনও পতাকা নেই। আমার দ্বারা কোনও অতিরিক্ত কাজ ছাড়াই ব্রাউজারটিকে এই ইভেন্ট হ্যান্ডলারের অগ্রাধিকারের ভিত্তিতে স্বয়ংক্রিয়ভাবে পুনঃ-অর্ডার দিয়ে সমস্যার সমাধান করেছে।

এটি আপনার পক্ষে কাজ করে না কেন এমন কোনও কারণ আছে?


4
এটি আসলে কাজ করে। আমি এফএফে এটি পরীক্ষা করেছি এবং এটি কবজির মতো কাজ করে।
সুপ্রিম ডলফিন

4
এটা কাজ করে। দেখে মনে হচ্ছে ফায়ারফক্স, ক্রোম এবং ইন্টারনেট এক্সপ্লোরারে পরীক্ষিত onmousedownহওয়ার আগেই এটি কার্যকর করা হয়েছিল onblur
টোনতিও

12
এটি লক্ষণীয় যে আচরণটি কিছুটা স্বাভাবিকভাবে পরিবর্তিত হয় - ক্লিকের কথোপকথনটি তারপরে মাউস আপের চেয়ে মাউস থেকে ডাউন হ্যান্ডল করা হয়। বেশিরভাগ মানুষের ক্ষেত্রে এটি সূক্ষ্ম হতে পারে (এই ক্ষেত্রে স্ব অন্তর্ভুক্ত) তবে কয়েকটি ত্রুটি রয়েছে। উল্লেখযোগ্যভাবে আমি প্রায়শই ক্লিক করি তারপরে বোতামটি টানুন যদি আমি ভুল করে ফেলেছি, যা অনক্লিক কল করা বাধা দেয় - যদি বোতামটি একটি খাঁটি নন ফাংশন সম্পাদন করে (মুছুন, পোস্ট করুন ইত্যাদি) আপনি এটি সংরক্ষণ করতে এবং পতাকা পদ্ধতির সাথে যেতে চান।
ব্রিজি

4
অ্যাক্সেসিবিলিটি সম্পর্কে আপনি অন ক্লিকের পরিবর্তে মাউসডাউন সেট করার মুহুর্তে আপনি কী সমস্ত <বাটন> উপাদানগুলির জন্য অ্যাক্সেসিবিলিটি
মেরেছেন

4
@ Ian-macfarlane দ্বারা নীচে তালিকাভুক্ত উত্তরটি এই সমস্যাটি মোকাবেলার সঠিক উপায়। সংক্ষেপে ... আপনার পছন্দসই ক্রিয়াটি onMouseDownসহ event.preventDefault() এবং এর onClickসাথে with
কনল ট্রিনিট্রোটলুইন দা কোস্টা

56

onClickসঙ্গে প্রতিস্থাপন করা উচিত নয় onMouseDown

এই পদ্ধতির কিছুটা কাজ করার সময় , দুটি মূলত পৃথক ঘটনা যা ব্যবহারকারীর চোখে বিভিন্ন প্রত্যাশা থাকে। onMouseDownপরিবর্তে ব্যবহার করা onClickএক্ষেত্রে আপনার সফ্টওয়্যারটির ভবিষ্যদ্বাণীকে নষ্ট করবে। সুতরাং, দুটি ঘটনা অপরিবর্তনীয়।

উদাহরণস্বরূপ: দুর্ঘটনাক্রমে একটি বোতামে ক্লিক করার পরে, ব্যবহারকারীরা মাউস ক্লিকটি ধরে রাখতে, উপাদানটির বাইরে কার্সারটি টেনে আনতে, এবং মাউস বোতামটি ছেড়ে দিতে সক্ষম হতে পারে, পরিণামে কোনও পদক্ষেপ না নেয়। onClickএই আছে. onMouseDownব্যবহারকারীকে মাউসটি ধরে রাখার অনুমতি দেয় না এবং পরিবর্তে ব্যবহারকারীর জন্য কোনও আশ্রয় ছাড়াই তত্ক্ষণাত কোনও ক্রিয়া শুরু করবে। onClickএটি এমন একটি মান, যার মাধ্যমে আমরা কোনও কম্পিউটারে ক্রিয়াকলাপ প্রত্যাশা করি।

এই পরিস্থিতিতে, ইভেন্টে কল event.preventDefault()করুন onMouseDownonMouseDownডিফল্টরূপে অস্পষ্ট ইভেন্ট সৃষ্টি করবে এবং যখন preventDefaultডাকা হবে তখন তা করবে না । তারপরে, কল onClickকরার একটি সুযোগ থাকবে। একটি অস্পষ্ট ঘটনা এখনও ঘটবে, কেবল পরে onClick

সর্বোপরি, onClickইভেন্টটি একটি সংমিশ্রণ onMouseDownএবং onMouseUp, যদি এবং যদি উভয়ই একই উপাদানগুলির মধ্যে ঘটে।


7
এটি আমার জন্য নিখুঁত সমাধান ছিল এবং মন্তব্য সম্পূর্ণ সঠিক - onMouseDown প্রতিস্থাপন ব্যবহারকারীর অভিজ্ঞতার জন্য বিভ্রান্তিকর। ভোট দিয়েছেন।
পল

5
এটি সঠিক উত্তর হওয়া উচিত। এই পোস্ট করার জন্য আপনাকে ধন্যবাদ
ব্যবহারকারীর 1189352

4
এটি লক্ষণীয় যে এটির কিছু ক্ষুদ্রতর পার্শ্ব প্রতিক্রিয়াও রয়েছে, যেমন উপাদানটির মধ্যে ক্লিক করে পাঠ্য নির্বাচন করতে সক্ষম না হওয়া। খুব বেশি ক্ষেত্রে এটি ভাবতে পারে না যেখানে এটি একটি সমস্যা হবে, কেবল এটি খানিকটা মজার মনে হয়েছে।
রি মিয়াসাকা

4
যদি আমি ব্যবহার event.preventDefault()উপর onMouseDownঘটনা, আমার onFocusঘটনা বলা হয় না
ব্যাটম্যান

3

onmousedownসঙ্গে প্রতিস্থাপন onfocus। পাঠ্যবক্সের অভ্যন্তরে যখন ফোকাস থাকবে তখন এই ইভেন্টটি ট্রিগার করা হবে।

onmouseupসঙ্গে প্রতিস্থাপন onblur। আপনি যে মুহুর্তে পাঠ্যবক্স থেকে আপনার ফোকাসটি সরিয়ে নেবেন, সেই মুহূর্তে অনব্লুর কার্যকর হবে।

আমার ধারণা এটি আপনার প্রয়োজন হতে পারে।

আপডেট :

আপনি যখন আপনার ফাংশন অনফোকসটি সম্পাদন করেন -> অনব্লুরটিতে আপনি যে ক্লাসগুলি প্রয়োগ করবেন তা সরিয়ে ফেলুন এবং অনফোকাসে কার্যকর করতে চান এমন ক্লাসগুলি যুক্ত করুন

এবং

আপনি যখন নিজের ফাংশনটি onblur কার্যকর করেন -> আপনি অনফোকাসে যে ক্লাসগুলি প্রয়োগ করবেন সেগুলি সরিয়ে ফেলুন এবং অনব্লিউর কার্যকর করতে চান এমন ক্লাসগুলি যুক্ত করুন

আমি পতাকা ভেরিয়েবলের কোনও প্রয়োজন দেখছি না।

আপডেট 2:

আপনি ইভেন্টগুলি অনমাউসআউট এবং অনমাউসওভারটি ব্যবহার করতে পারেন

onmouseover -Detects কার্সার এটি উপর যখন।

onmouseout -Detects যখন কার্সার পাতার।


আমি আমার প্রশ্নটি স্বচ্ছতার জন্য সম্পাদনা করেছি। এই সমাধানটি কীভাবে পতাকা নির্ধারণের প্রয়োজনীয়তা এড়াতে পারে? এছাড়াও, আমি ব্যবহার onmousedown()এবং onmouseup()মেনু, না পাঠ্যবাক্স / ইনপুট ক্ষেত্রের উপর।
1 ''

আমি এই উত্তরটি এখনও গ্রহণ করতে পারি না কারণ আমি জানি না যে এটি সঠিক। আমি উপরে আমার মন্তব্যে উত্থাপিত উদ্বেগগুলির প্রতিক্রিয়া জানাতে পারি?
1 ''

অবশ্যই, আমি দেখতে পাচ্ছি যে আপনি কীভাবে অনমাউসওভারটি ব্যবহার করতে পারেন এবং মেনুতে মাউসটি চলে গেলে পতাকা নির্ধারণের জন্য আমি বর্তমানে যা করছি ঠিক একইভাবে অনমাইলআউট ব্যবহার করতে পারেন। যাইহোক, আমি এখনও মনে করি যে আপনি অনমাউসওভারে একটি পতাকা সেট করা দরকার যা অন্মাউসআউটে সাফ হয়ে গেছে, যাতে আপনি জানতে পারবেন যে আপনি ক্লিক করার সময় মেনুতে ছিলেন কিনা। আপনি কী এমন কোনও উপায়ের কথা ভাবতে পারেন যে পতাকা স্থাপনের প্রয়োজন নেই?
1 ''

আমি কি আপনার কোডটি দেখতে পাচ্ছি ... এটিকে একটি ধাঁধাতে রেখে দিন ... কেবলমাত্র প্রাসঙ্গিক অংশটি দিন এবং এটির ঠিক আছে যদি আমি ফলাফলগুলি দেখতে না পেলাম ... কোডটি ঠিক করুন ..
হিরা ঠাকুর


2

আরও মার্জিত (তবে সম্ভবত কম পারফরম্যান্ট) সমাধান:

মেনুটি সরাতে ইনপুটটির অন্বলুর ব্যবহার না করে ব্যবহার করুন document.onclick, যা পরে জ্বলে onblur

যাইহোক, এর অর্থ হ'ল মেনুটি সরানো হবে যখন ইনপুট নিজেই ক্লিক করা হবে, যা অনাকাঙ্ক্ষিত আচরণ। একটি সেট input.onclickসঙ্গে event.stopPropagation()নথি ক্লিক ইভেন্টে ক্লিক প্রচারের এড়ানো।


5
ঠিক আছে, এই উত্তরটির সাথে সমস্যাটি হ'ল এটি যদি কোনও ক্লিক ইভেন্ট না হয় যা অস্পষ্টতাটিকে ট্রিগার করে। যদি ব্যবহারকারী ইনপুট থেকে ট্যাবড করে রাখে? এতে অস্পষ্ট ইভেন্টটি ট্রিগার হতে পারে তবে ফ্লাইআউট মেনুটি দৃশ্যমান হবে।
ক্রিস্টোফ

0

অনফোকাস দ্বারা অনক্লিক পরিবর্তন করুন

এমনকি যদি onblur এবং onclick খুব ভালভাবে না পায় তবে স্পষ্টতই onfocus এবং হ্যাঁ onblur। মেনু বন্ধ হওয়ার পরেও অনফোকাসটি ভিতরে ক্লিক করা উপাদানটির জন্য এখনও বৈধ for

আমি করেছি এবং এটি কাজ করে।


-7

আপনি setIntervalআপনার onBlurহ্যান্ডলারের ভিতরে কোনও ফাংশন ব্যবহার করতে পারেন :

<input id="input" onblur="removeMenu()" ... />

function removeMenu() {
    setInterval(function(){
        if (!mouseflag) {
            document.getElementById('menu').innerHTML = '';
        }
    }, 0);
}

setIntervalফাংশন আপনার সরাবে onBlur ফাংশন কল আউট স্ট্যাক থেকে 0 সেট সময়, কারণ আপনি যোগ করুন, এই ফাংশন অবিলম্বে পরে অন্যান্য ইভেন্ট হ্যান্ডলার সমাপ্ত ডাকা হবে


5
setIntervalএকটি খারাপ ধারণা, আপনি এটি কখনই বাতিল করছেন না যাতে এটি ক্রমাগত আপনার ফাংশনটি পরিচালনা করে এবং সম্ভবত আপনার সাইটের সর্বাধিক সিপিইউ ব্যবহার করার কারণ হয়ে থাকে। setTimeoutআপনি যদি এই কৌশলটি ব্যবহার করতে যাচ্ছেন (তবে আমি প্রস্তাব দিই না) এর পরিবর্তে ব্যবহার করুন । আপনার অ্যাপ্লিকেশনটি নির্দিষ্ট ইভেন্টগুলির সময়ের উপর নির্ভরশীল করে তোলা ঝুঁকিপূর্ণ ব্যবসা।
কেসী

6
ডেঞ্জার রবিনসন! বিপদ! সামনে রেসের অবস্থা!
গোরডেফেক্স

আমি মূলত এই সমাধানটি নিয়ে এসেছি (ভাল setTimeoutনয় setInterval) তবে 250সময়টি সঠিক ক্রমে হওয়ার আগেই আমাকে এটি এমএস পর্যন্ত বাম করতে হয়েছিল । এই বাগটি সম্ভবত এখনও ধীর ডিভাইসে থাকবে এবং এটি বিলম্বকে লক্ষণীয় করে তোলে। আমি চেষ্টা করেছিলাম onMouseDownএবং এটি ঠিক কাজ করে। আমি ভাবছি যদি এটির পাশাপাশি স্পর্শ ইভেন্টগুলিও প্রয়োজন হয়।
ব্রেনান চেউং

যদি আপনি সত্যিই অনক্লিক ব্যবহার করতে চান তবে একটি বিরতির মতো কিছু খারাপ নয়। তবে আপনি অন্তরালের চেয়ে শর্তযুক্ত পুনরাবৃত্তির সময়সীমা চেয়েছিলেন যাতে এটি চিরকাল স্থায়ী হয় না। এটি একই প্যাটার্নটি সেলেনিয়াম শর্তাধীন অপেক্ষা করে।
কেইন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.