javascript - অবজ - জাভাস্ক্রিপ্ট বাংলা বই




জাভাস্ক্রিপ্ট ব্যবহার করে একবার একাধিক কী চাপলে কীভাবে সনাক্ত করা যায়? (6)

আমি একটি জাভাস্ক্রিপ্ট গেম ইঞ্জিন বিকাশের চেষ্টা করছি এবং আমি এই সমস্যাটি পূরণ করেছি:

  • যখন আমি স্পেস চাপুন অক্ষর ঝাঁপ দাও।
  • যখন আমি প্রেস অক্ষর ডান সরানো।

সমস্যা হচ্ছে যখন আমি ডানদিকে টিপুন এবং তারপর স্পেস টিপুন, চরিত্রটি ঝাঁপিয়ে পড়বে এবং তারপর চলবে।

আমি কী চাপার জন্য keydown ফাংশন ব্যবহার করি। একবার একাধিক কী চাপলে কীভাবে আমি চেক করতে পারি?


Alt টি চাপলে Alt / Crtl / Shift চেপে আপনি এই পদ্ধতিটি ব্যবহার করতে পারেন:

document.body.addEventListener('keydown', keysDown(actions) );

function actions() {
   // do stuff here
}

// simultaneous pressing Alt + R
function keysDown (cb) {
  return function (zEvent) {
    if (zEvent.altKey &&  zEvent.code === "KeyR" ) {
      return cb()
    }
  }
}

আপনি যদি ধারণাটি বুঝতে পারেন তবে একাধিক কীস্ট্রোক সনাক্তকরণ সহজ

আমি এটা করার মত উপায়:

var map = {}; // You could also use an array
onkeydown = onkeyup = function(e){
    e = e || event; // to deal with IE
    map[e.keyCode] = e.type == 'keydown';
    /* insert conditional here */
}

এই কোডটি খুব সহজ: কম্পিউটার শুধুমাত্র একবারে একটি কীস্ট্রোক পাস করে, একাধিক কীগুলির ট্র্যাক রাখতে অ্যারের তৈরি হয়। অ্যারে একবারে এক বা একাধিক কী চেক করার জন্য ব্যবহার করা যেতে পারে।

শুধু ব্যাখ্যা করতে, বলুন আপনি এবং বি টিপুন, প্রতিটি একটি keydown ইভেন্টকে আগুন দেয় যা e.type == keydown মানটি map[e.keyCode] সেট করে, যা সত্য বা মিথ্যাতে মূল্যায়ন করে। এখন উভয় map[65] এবং map[66] true সেট করা true । যখন আপনি A যান, তখন keyup ইভেন্টটি আগুনে পুড়ে যায়, যা একই লজিককে map[65] (A) এর বিপরীত ফলাফল নির্ধারণ করার কারণ দেয়, যা এখন মিথ্যা , কিন্তু map[66] (B) এখনও "ডাউন" ( এটি একটি keyup ইভেন্ট ট্রিগার করেনি), এটা সত্য অবশেষ।

উভয় ইভেন্টের মাধ্যমে, map অ্যারে এই রকম দেখায়:

// keydown A 
// keydown B
[
    65:true,
    66:true
]
// keyup A
// keydown B
[
    65:false,
    66:true
]

এখন আপনি দুটি জিনিস করতে পারেন:

A) একটি কী লগার ( example ) পরে একটি রেফারেন্স হিসাবে তৈরি করা যেতে পারে যখন আপনি দ্রুত এক বা একাধিক কী কোড বের করতে চান। Assuming আপনি একটি এইচটিএমএল উপাদান সংজ্ঞায়িত করেছেন এবং পরিবর্তনশীল element সঙ্গে এটি নির্দেশিত।

element.innerHTML = '';
var i, l = map.length;
for(i = 0; i < l; i ++){
    if(map[i]){
        element.innerHTML += '<hr>' + i;
    }
}

দ্রষ্টব্য: আপনি সহজেই তার id বৈশিষ্ট্য দ্বারা একটি উপাদান দখল করতে পারেন।

<div id="element"></div>

এটি একটি HTML উপাদান তৈরি করে যা সহজেই জাভাস্ক্রিপ্টে element সহ উল্লেখ করা যেতে পারে

alert(element); // [Object HTMLDivElement]

এটি দখল করার জন্য আপনাকে document.getElementById() বা $() ব্যবহার করতেও হবে না। কিন্তু সামঞ্জস্যের জন্য jQuery এর $() এর ব্যবহার আরও ব্যাপকভাবে প্রস্তাবিত।

শুধু এইচটিএমএল শরীরের পরে স্ক্রিপ্ট ট্যাগ আসে নিশ্চিত করুন। অপ্টিমাইজেশান টিপ : সর্বাধিক বড় নাম ওয়েবসাইট অপটিমাইজেশনের জন্য শরীরের ট্যাগের পরে স্ক্রিপ্ট ট্যাগ রাখে। এটি স্ক্রিপ্ট ট্যাগটি লোড হওয়া থেকে আরও উপাদানগুলিকে ব্লক করে যতক্ষণ না তার স্ক্রিপ্ট ডাউনলোড শেষ হয়। বিষয়বস্তু এগিয়ে এটি নির্বাণ কন্টেন্ট পূর্বে লোড করতে পারবেন।

B (যেখানে আপনার আগ্রহ থাকে) আপনি একবারে এক বা একাধিক কী চেক করতে পারেন যেখানে /*insert conditional here*/ ছিল, এই উদাহরণটি গ্রহণ করুন:

if(map[17] && map[16] && map[65]){ // CTRL+SHIFT+A
    alert('Control Shift A');
}else if(map[17] && map[16] && map[66]){ // CTRL+SHIFT+B
    alert('Control Shift B');
}else if(map[17] && map[16] && map[67]){ // CTRL+SHIFT+C
    alert('Control Shift C');
}

সম্পাদনা : এটি সবচেয়ে পঠনযোগ্য স্নিপেট নয়। পাঠযোগ্যতা গুরুত্বপূর্ণ, তাই আপনি চোখের দিকে সহজ করতে এটির মতো কিছু চেষ্টা করতে পারেন:

function test_key(selkey){
    var alias = {
        "ctrl":  17,
        "shift": 16,
        "A":     65,
        /* ... */
    };

    return key[selkey] || key[alias[selkey]];
}

function test_keys(){
    var keylist = arguments;

    for(var i = 0; i < keylist.length; i++)
        if(!test_key(keylist[i]))
            return false;

    return true;
}

ব্যবহার:

test_keys(13, 16, 65)
test_keys('ctrl', 'shift', 'A')
test_key(65)
test_key('A')

ইহা কি ভাল?

if(test_keys('ctrl', 'shift')){
    if(test_key('A')){
        alert('Control Shift A');
    } else if(test_key('B')){
        alert('Control Shift B');
    } else if(test_key('C')){
        alert('Control Shift C');
    }
}

(সম্পাদনা শেষ)

এই উদাহরণটি Ctrl Shift A , Ctrl Shift B এবং Ctrl Shift C এর জন্য পরীক্ষা করে

এটা ঠিক যে হিসাবে সহজ :)

নোট

KeyCodes ট্র্যাক রাখা

সাধারণ নিয়ম হিসাবে, কোডটি নথিভুক্ত করা ভাল অভ্যাস, বিশেষ করে কী কোডগুলির মত (যেমন // CTRL+ENTER ) যাতে আপনি মনে রাখতে পারেন যে তারা কী ছিল।

ডকুমেন্টেশন ( CTRL+ENTER => map[17] && map[13] , map[13] && map[17] ) এর মতো একই কোডগুলিতেও আপনাকে কী কোডগুলি রাখতে হবে। আপনি ফিরে যান এবং কোড সম্পাদনা করার প্রয়োজন যখন এই ভাবে আপনি বিভ্রান্ত হবে না।

যদি-অন্য চেইন সঙ্গে একটি গোচা

ভিন্ন পরিমাণে কম্বোসের জন্য পরীক্ষা করা হলে (যেমন Ctrl Shift Alt Enter এবং Ctrl Enter ), বড় কম্বোসের পরে ছোট কম্বো লাগান অথবা অন্যথায় ছোট কম্বোগুলি যদি যথেষ্ট পরিমাণে থাকে তবে বড় কম্বোগুলি ওভাররাইড করবে। উদাহরণ:

// Correct:
if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
    alert('Whoa, mr. power user');
}else if(map[17] && map[13]){ // CTRL+ENTER
    alert('You found me');
}else if(map[13]){ // ENTER
    alert('You pressed Enter. You win the prize!')
}

// Incorrect:
if(map[17] && map[13]){ // CTRL+ENTER
    alert('You found me');
}else if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
    alert('Whoa, mr. power user');
}else if(map[13]){ // ENTER
    alert('You pressed Enter. You win the prize!');
}
// What will go wrong: When trying to do CTRL+SHIFT+ENTER, it will
// detect CTRL+ENTER first, and override CTRL+SHIFT+ENTER.
// Removing the else's is not a proper solution, either
// as it will cause it to alert BOTH "Mr. Power user" AND "You Found Me"

গোচাঃ "এই কী কম্বো অ্যাক্টিভেট করছে যদিও আমি কী চাপাচ্ছি না"

সতর্কতা বা প্রধান উইন্ডো থেকে ফোকাস করা যেকোন কিছু সঙ্গে যখন আচরণ করা হয়, তখন শর্তটি শেষ হওয়ার পরে আপনি অ্যারের পুনরায় সেট করতে map = [] অন্তর্ভুক্ত করতে চাইতে পারেন। এটি কিছু বিষয়, যেমন alert() , প্রধান উইন্ডো থেকে ফোকাসটি দূরে নিয়ে যান এবং 'কীউপ' ইভেন্টটি ট্রিগার না হওয়ার কারণ করে। উদাহরণ স্বরূপ:

if(map[17] && map[13]){ // CTRL+ENTER
    alert('Oh noes, a bug!');
}
// When you Press any key after executing this, it will alert again, even though you 
// are clearly NOT pressing CTRL+ENTER
// The fix would look like this:

if(map[17] && map[13]){ // CTRL+ENTER
    alert('Take that, bug!');
    map = {};
}
// The bug no longer happens since the array is cleared

গোচাঃ ব্রাউজার ডিফল্ট

সমাধান পাওয়া সহ এখানে পাওয়া একটি বিরক্তিকর জিনিস:

সমস্যা: ব্রাউজারটি সাধারণত কী কম্বোগুলিতে ডিফল্ট অ্যাকশন থাকে (যেমন Ctrl D বুকমার্ক উইন্ডো সক্রিয় করে, বা Ctrl Shift C maxthon এ স্কিনোট সক্রিয় করে), আপনি map = [] পরে return false যোগ করতে চাইতে return false , তাই আপনার সাইটের ব্যবহারকারীরা Ctrl D এ থাকা "সদৃশ ফাইল" ফাংশনটি হতাশ হবেন না, পরিবর্তে পৃষ্ঠাটি বুকমার্ক করে।

if(map[17] && map[68]){ // CTRL+D
    alert('The bookmark window didn\'t pop up!');
    map = {};
    return false;
}

return false ছাড়া, ব্যবহারকারীর হতাশার জন্য বুকমার্ক উইন্ডোটি পপ আপ করবে

ফেরত বক্তব্য (নতুন)

ঠিক আছে, তাই আপনি সবসময় যে বিন্দু ফাংশন থেকে প্রস্থান করতে চান না। এজন্য event.preventDefault() ফাংশন আছে। এটি একটি অভ্যন্তরীণ পতাকা সেট করে যা ইন্টারপ্রেটারকে ব্রাউজারটিকে তার ডিফল্ট অ্যাকশন চালানোর অনুমতি দেয় না । তারপরে, ফাংশনটি কার্যকর করা চলবে (যখন return ফাংশনটি তাত্ক্ষণিকভাবে প্রস্থান করবে)।

return false বা e.preventDefault() ব্যবহার করতে হবে কিনা তা নির্ধারণ করার আগে এই পার্থক্যটি বুঝুন

event.keyCode হয়

ব্যবহারকারী SeanVieira মন্তব্য নির্দেশ করে যে event.keyCode হয়।

সেখানে, তিনি একটি চমত্কার বিকল্প দিয়েছেন: event.key , যা টি event.key একটি স্ট্রিং উপস্থাপনা প্রদান করে, যেমন A এর জন্য "a" বা "Shift" জন্য "Shift"

আমি এগিয়ে গিয়েছিলাম এবং স্ট্রিং পরীক্ষার জন্য একটি tool রান্না করা।

element.onevent বনাম element.addEventListener

addEventListener সাথে নিবন্ধিত হ্যান্ডলারগুলি স্ট্যাক করা যেতে পারে এবং রেজিস্ট্রেশন করার সময় বলা হয়। সেটিংটি সরাসরি আক্রমনাত্মক এবং আপনার পূর্বে যেকোন কিছুকে ওভাররাইড করে।

document.body.onkeydown = function(ev){
    // do some stuff
    ev.preventDefault(); // cancels default actions
    return false; // cancels this function as well as default actions
}

document.body.addEventListener("keydown", function(ev){
    // do some stuff
    ev.preventDefault() // cancels default actions
    return false; // cancels this function only
});

.onevent সম্পত্তি সবকিছু এবং ev.preventDefault() এর আচরণ ওভাররাইড এবং return false; বরং অনির্দেশ্য হতে পারে।

উভয় ক্ষেত্রেই, addEventlistener মাধ্যমে নিবন্ধিত হ্যান্ডলারগুলি লিখতে এবং সম্পর্কে সহজ বলে মনে হচ্ছে।

ইন্টারনেট এক্সপ্লোরারের অ-মানক বাস্তবায়ন থেকে attachEvent("onevent", callback) , তবে এটি অপ্রচলিত এবং জাভাস্ক্রিপ্টের সাথে সম্পর্কিত নয় (এটি জ্যাস্রিপ্ট নামে একটি গোয়েন্দা ভাষা সম্পর্কিত)। যতটা সম্ভব পলিগ্লট কোড এড়াতে আপনার সেরা আগ্রহের মধ্যে এটি হবে।

একটি সহায়ক ক্লাস

বিভ্রান্তি / অভিযোগগুলি মোকাবেলার জন্য, আমি একটি "বর্গ" লিখেছি যা এই বিমূর্ততা ( পেস্টবিন লিঙ্ক ) করে:

function Input(el){
    var parent = el,
        map = {},
        intervals = {};

    function ev_kdown(ev)
    {
        map[ev.key] = true;
        ev.preventDefault();
        return;
    }

    function ev_kup(ev)
    {
        map[ev.key] = false;
        ev.preventDefault();
        return;
    }

    function key_down(key)
    {
        return map[key];
    }

    function keys_down_array(array)
    {
        for(var i = 0; i < array.length; i++)
            if(!key_down(array[i]))
                return false;

        return true;
    }

    function keys_down_arguments()
    {
        return keys_down_array(Array.from(arguments));
    }

    function clear()
    {
        map = {};
    }

    function watch_loop(keylist, callback)
    {
        return function(){
            if(keys_down_array(keylist))
                callback();
        }
    }

    function watch(name, callback)
    {
        var keylist = Array.from(arguments).splice(2);

        intervals[name] = setInterval(watch_loop(keylist, callback), 1000/24);
    }

    function unwatch(name)
    {
        clearInterval(intervals[name]);
        delete intervals[name];
    }

    function detach()
    {
        parent.removeEventListener("keydown", ev_kdown);
        parent.removeEventListener("keyup", ev_kup);
    }

    function attach()
    {
        parent.addEventListener("keydown", ev_kdown);
        parent.addEventListener("keyup", ev_kup);
    }

    function Input()
    {
        attach();

        return {
            key_down: key_down,
            keys_down: keys_down_arguments,
            watch: watch,
            unwatch: unwatch,
            clear: clear,
            detach: detach
        };
    }

    return Input();
}

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

এই বর্গটি ব্যবহার করার জন্য, একটি উদাহরণ তৈরি করুন এবং যে উপাদানটি আপনি কীবোর্ড ইনপুট যুক্ত করতে চান তা নির্দেশ করুন:

var input_txt = Input(document.getElementById("txt"));

input_txt.watch("print_5", function(){
    txt.value += "FIVE ";
}, "Control", "5");

এইটি কী করবে তা হল #txt সাথে উপাদানটিতে একটি নতুন ইনপুট শ্রোতা সংযুক্ত করুন (আসুন এটি একটি #txt অনুমান করা যাক), এবং কী কম্বো Ctrl+5 জন্য একটি #txt সেট করুন। যখন Ctrl এবং 5 উভয়ই ডাউন হয়, তখন আপনি যে কলব্যাক ফাংশনটি পাস করেছেন (এই ক্ষেত্রে, একটি ফাংশন যা "FIVE " টেক্সট টেক্সারে যুক্ত করে) বলা হবে। কলব্যাক নাম print_5 সাথে যুক্ত, তাই এটি সরানোর জন্য, আপনি কেবল ব্যবহার করেন:

input_txt.unwatch("print_5");

input_txt উপাদান থেকে input_txt আলাদা করতে:

input_txt.detach();

এইভাবে, আবর্জনা সংগ্রহ বস্তুটি নিতে পারে ( input_txt ), এটি নিক্ষেপ করা উচিত, এবং আপনার পুরানো জাম্বি ইভেন্ট শ্রোতা বামে থাকবে না।

পুঙ্খানুপুঙ্খতার জন্য, এখানে শ্রেণির API এর একটি দ্রুত রেফারেন্স, যা সি / জাভা শৈলীতে উপস্থাপিত হয়েছে যাতে আপনি জানেন যে তারা কী ফিরে আসে এবং তারা কোন আর্গুমেন্টগুলি প্রত্যাশা করে।

Boolean  key_down (String key);

key ডাউন থাকলে true ফেরৎ, মিথ্যা অন্যথায়।

Boolean  keys_down (String key1, String key2, ...);

সব কি key1 .. keyN keys যদি true ফিরে key1 .. keyN নিচে, অন্যথায় মিথ্যা।

void     watch (String name, Function callback, String key1, String key2, ...);

একটি "ওয়াচপয়েন্ট" তৈরি করে যেমন keyN চাপিয়ে কলব্যাক ট্রিগার করবে

void     unwatch (String name);

তার নামের মাধ্যমে watchpoint বলেন

void     clear (void);

"চাবি নিচে" ক্যাশে wipes। উপরে map = {} সমান

void     detach (void);

অভিভাবক উপাদান থেকে ev_kdown এবং ev_kup শ্রোতাদের বিচ্ছিন্ন করে, এটি নিরাপদভাবে উদাহরণ থেকে পরিত্রাণ পেতে পারে

আপডেট 2017-12-02 জিথুব এ প্রকাশ করার অনুরোধের প্রতিক্রিয়ায়, আমি একটি তালিকা তৈরি করেছি।

2018-07-21 আপডেট করুন আমি কিছুদিনের জন্য ঘোষণামূলক স্টাইল প্রোগ্রামিং দিয়ে খেলছি, এবং এইভাবে এখন আমার ব্যক্তিগত প্রিয়: fiddle , pastebin

সাধারনত, এটি প্রকৃতপক্ষে আপনি চান এমন ক্ষেত্রে কাজ করবেন (ctrl, alt, shift), তবে যদি একই সময়ে a+w আঘাত করতে হয় তবে এটি "একত্রিত করা" খুব কঠিন হবে না। একটি বহু-কী-সন্ধানের মধ্যে পন্থা।

আমি এই পুঙ্খানুপুঙ্খভাবে উত্তর মিনি ব্লগ সাহায্য সহায়ক ব্যাখ্যা :)


আমি এই ভাবে ব্যবহার করেছি (সিফ্ট + Ctrl চেপে যেকোনো জায়গায় চেক করতে হবে):

// create some object to save all pressed keys
var keys = {
    shift: false,
    ctrl: false
};

$(document.body).keydown(function(event) {
// save status of the button 'pressed' == 'true'
    if (event.keyCode == 16) {
        keys["shift"] = true;
    } else if (event.keyCode == 17) {
        keys["ctrl"] = true;
    }
    if (keys["shift"] && keys["ctrl"]) {
        $("#convert").trigger("click"); // or do anything else
    }
});

$(document.body).keyup(function(event) {
    // reset status of the button 'released' == 'false'
    if (event.keyCode == 16) {
        keys["shift"] = false;
    } else if (event.keyCode == 17) {
        keys["ctrl"] = false;
    }
});

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

এই উদাহরণটি দেখুন: http://jsfiddle.net/vor0nwe/mkHsU/

(হালনাগাদ: আমি এখানে কোডটি পুনঃপ্রবর্তন করছি, যদি জেএসফিলিট.net বেলে :) HTML:

<ul id="log">
    <li>List of keys:</li>
</ul>

... এবং জাভাস্ক্রিপ্ট (jQuery ব্যবহার করে):

var log = $('#log')[0],
    pressedKeys = [];

$(document.body).keydown(function (evt) {
    var li = pressedKeys[evt.keyCode];
    if (!li) {
        li = log.appendChild(document.createElement('li'));
        pressedKeys[evt.keyCode] = li;
    }
    $(li).text('Down: ' + evt.keyCode);
    $(li).removeClass('key-up');
});

$(document.body).keyup(function (evt) {
    var li = pressedKeys[evt.keyCode];
    if (!li) {
       li = log.appendChild(document.createElement('li'));
    }
    $(li).text('Up: ' + evt.keyCode);
    $(li).addClass('key-up');
});

এই উদাহরণে, কোন কী চাপানো হচ্ছে তা ধরে রাখতে আমি একটি অ্যারে ব্যবহার করছি। একটি বাস্তব অ্যাপ্লিকেশনে, আপনি তাদের সংযুক্ত কী ছেড়ে দেওয়ার পরে প্রতিটি উপাদান delete পারেন।

উল্লেখ্য, আমি এই উদাহরণে নিজের জন্য জিনিসগুলিকে সহজ করার জন্য jQuery ব্যবহার করেছি, যখন 'কাঁচা' জাভাস্ক্রিপ্টে কাজ করার সময় ধারণাটি ঠিক একইভাবে কাজ করে।


যার জন্য সম্পূর্ণ উদাহরণ কোড প্রয়োজন। ডান + বাম যোগ করা

var keyPressed = {};
document.addEventListener('keydown', function(e) {

   keyPressed[e.key + e.location] = true;

    if(keyPressed.Shift1 == true && keyPressed.Control1 == true){
        // Left shift+CONTROL pressed!
        keyPressed = {}; // reset key map
    }
    if(keyPressed.Shift2 == true && keyPressed.Control2 == true){
        // Right shift+CONTROL pressed!
        keyPressed = {};
    }

}, false);

document.addEventListener('keyup', function(e) {
   keyPressed[e.key + e.location] = false;

   keyPressed = {};
}, false);

case 65: //A
jp = 1;
setTimeout("jp = 0;", 100);

if(pj > 0) {
ABFunction();
pj = 0;
}
break;

case 66: //B
pj = 1;
setTimeout("pj = 0;", 100);

if(jp > 0) {
ABFunction();
jp = 0;
}
break;

ভাল উপায় না, আমি জানি।






keydown