SORU
5 Mart 2011, CUMARTESİ


javascript birden fazla tuşa aynı anda basıldığında

Javascript oyun motoru geliştirmeye çalışıyorum ve bu sorunla karşılaştım.

Ben basınboşlukkarakteri atlar. Sağ ok tuşuna basıldığında karakter sağa taşır.

Şeyi hemen sonra basarak devam ediyorum ne zaman karakter hareket etmeyi bırakır o zaman atlar boşluk tuşuna basın.

İ kullanınkapatıyorsatuşunu basılı almak için fonksiyon nasıl eğer birden fazla anahtar basılı ise orada kontrol edebilir miyim?

CEVAP
16 EYLÜL 2012, Pazar


Birden fazla tuş algılama kavramı anlamak kolaydır

Ben böyle yapıyorum böyle

var map = []; // Or you could call it "key"
onkeydown = onkeyup = function(e){
    e = e || event; // to deal with IE
    map[e.keyCode] = e.type == 'keydown';
    /*insert conditional here*/
}

Bu kod çok basit: bilgisayarı bir seferde sadece tek bir vuruşu geçirmeden bu Yana, bir dizi birden çok anahtarları takip etmek için oluşturulur. Bu dizi bir veya daha fazla tuşa aynı anda kontrol etmek için kullanılabilir.

Sadece açıklamak için, tuşuna basınBirveBher yangınları da değerlendiren e.type == keydown değerine map[e.keyCode] ayarlar keydown bir olaydoğruyayanlış. Şimdi map[65] map[66] 15* *için ayarlanır. A, keyup olay bıraktığınızda, map[65] ters sonucu belirlemek için aynı mantığı neden patlar (A), şimdi de buyanlışmap[66] (B) hala olduğu için , ama "" (keyup olayı harekete değil), o kalırdoğru.

map dizi, her iki olay ile, bu gibi görünüyor:

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

Şimdi yapabileceğin iki şey vardır:

A)Bir Key logger (example) daha sonra hızlı bir veya daha fazla anahtar kodları anlamaya istediğiniz için bir referans olarak oluşturulabilir. Bir html öğesi tanımlanmış ve değişken ile işaret varsayarsak 22**.

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

Not: kolayca id özniteliği bir öğe kapmak.

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

Bu kolayca element javascript başvurulan bir html belgesi oluşturur

alert(element); // [Object HTMLDivElement]

Hatta document.getElementById() $() yakala kullanmak zorunda değilsin. Ama uyumluluk için, DV kullanımı $() daha yaygın olarak tavsiye edilir.

Sadece emin olunscriptetiket HTML vücut sonra gelir.Optimizasyon ipucuEn büyük isim web sitelerinin komut dosyası etiketi koymaksonraoptimizasyon için body etiketi. Bu script script indirme tamamlanana kadar etiketi bloklar yüklenmesini daha fazla element olmasıdır. İçeriğin önüne koyarak içeriğini yüklemek için önceden izin verir.

B ilgi de burada yatıyor/*insert conditional here*/ olduğu bir zamanda, bu örnek alırsak, bir veya daha fazla anahtar için kontrol edebilirsiniz:

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');
}

Bu örnek için kontrol ederCtrlShiftBir,CtrlShiftBveCtrlShiftC

O:) bu kadar basit

Notlar

KeyCodes Takip

Genel bir kural olarak, ne olduklarını hatırlayabilir kodu, özellikle Anahtar kodları gibi şeyler (// CTRL ENTER gibi) belge için iyi bir yöntemdir.

Ayrıca belgeleri (CTRL ENTER => map[17] && map[13], map[13] && map[17]) aynı sırada anahtar kodlarını koymalısın. Bu şekilde hiç geri dönüp kodunu düzenlemek için ihtiyacınız olduğunda karışık olmayacak.

Eğer başka zincirler ile yakaladım

Eğer farklı oranlarda kombinasyonları kontrol (gibiCtrlShiftAltGirinveCtrlGirin), koyun küçük taraksonrabüyük tarak, yoksa küçük tarak benzer yeterince büyük tarak geçersiz kılar. Örnek:

// 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"

Yakaladım: "Bu anahtar combo tuşları olmasam da aktive ediyor"

Uyarılar ya da ana pencereden odak alan herhangi bir şey ile uğraşırken, map = [] durumu bittikten sonra dizinin sıfırlamak için eklemek isteyebilirsiniz. Bu bazı şeyler olduğu için, alert() ana pencereden uzak odak alır ve olayı tetiklemek için neden yok gibi. Örneğin:

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

Yakaladım: Tarayıcı Varsayılanları

İşte buldum sinir bozucu bir şey, çözümü dahil:

Sorun: tarayıcı genellikle anahtar kombinasyonları varsayılan eylemler vardır Beri (gibiCtrlDyer işareti penceresinde ya . etkinleştirir ^kbd>CtrlShiftCaktive maxthon skynote üzerinde), ayrıca eklemek için return false sonra map = [], kullanıcıların sitenize olmaz sinirli zaman "Yinelenen Dosya" işlevi, alınmakCtrlDyerine sayfayı yer imlerine.

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

return false İmi pencere olmadanpop-up, kullanıcı dehşet.

Return deyimi (yeni)

Tamam, bu yüzden her zaman bu noktada işlevi çıkmak istemezsin. event.preventDefault() işlevi var. Ne tercüman belirten bir iç bayrak ayarlanırdeğiltarayıcı varsayılan eylem çalıştırmak için izin verir. Fonksiyonun yürütülmesine devam return hemen işlevi çıkılacak ise () sonra.

return false e.preventDefault() kullanmak için olup olmadığını karar vermeden önce bu ayrım anlıyorum


İyice açıklanmış bu cevap yardımcı oldu umarım :)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • BioHunta

    BioHunta

    28 Mayıs 2006
  • Evan Coury

    Evan Coury

    29 NİSAN 2007
  • UlyssesForever's channel

    UlyssesForev

    28 ŞUBAT 2012