Dokunma ve fare

İlk kez yeniden bir arada

Giriş

Yaklaşık otuz yıldır masaüstü bilgisayar deneyimleri, ana kullanıcı giriş cihazlarımız olarak klavye ve fare veya dokunmatik yüzey etrafında şekillenmiştir. Ancak son on yılda akıllı telefonlar ve tabletler yeni bir etkileşim paradigması getirdi: dokunma. Dokunmatik özellikli Windows 8 makinelerin piyasaya sürülmesi ve şimdi de dokunmatik özellikli muhteşem Chromebook Pixel'in çıkmasıyla dokunma, beklenen masaüstü deneyiminin bir parçası haline geliyor. En büyük zorluklardan biri, yalnızca dokunmatik cihazlarda ve fare cihazlarında değil, kullanıcının her iki giriş yöntemini de (bazen aynı anda) kullanacağı bu cihazlarda da çalışan deneyimler oluşturmaktır.

Bu makale, dokunma özelliklerinin tarayıcıya nasıl yerleştirildiğini, bu yeni arayüz mekanizmasını mevcut uygulamalarınıza nasıl entegre edebileceğinizi ve dokunmanın fare girişiyle nasıl uyumlu bir şekilde çalışabileceğini anlamanıza yardımcı olacaktır.

Web platformunda dokunma özelliğinin durumu

iPhone, web tarayıcısında özel dokunma API'leri bulunan ilk popüler platformdu. Diğer birçok tarayıcı tedarikçisi, iOS uygulamasıyla uyumlu olacak şekilde tasarlanmış benzer API arayüzleri oluşturmuştur. Bu arayüzler artık "Dokunma Etkinlikleri sürüm 1" spesifikasyonunda açıklanmaktadır. Dokunma etkinlikleri masaüstünde Chrome ve Firefox, iOS'te Safari, Android'de Chrome ve Android tarayıcı, ayrıca Blackberry tarayıcı gibi diğer mobil tarayıcılar tarafından desteklenir.

Meslektaşım Boris Smus, dokunma etkinlikleri hakkında harika bir HTML5Rocks eğitimi yazdı. Dokunma etkinliklerine daha önce bakmadıysanız bu eğitim, başlamak için iyi bir yöntemdir. Daha önce dokunma etkinlikleriyle çalışmadıysanız devam etmeden önce bu makaleyi okuyun. Devam edin, bekliyorum.

Hepsi bitti mi? Dokunma etkinlikleri hakkında temel bilgilere sahip olduğunuza göre, dokunma özellikli etkileşimler yazmanın zorluğu, dokunma etkileşimlerinin fare (ve fareyi taklit eden dokunmatik yüzey ve iz topu) etkinliklerinden oldukça farklı olabilmesidir. Dokunma arayüzleri genellikle fareleri taklit etmeye çalışsa da bu taklit mükemmel veya eksiksiz değildir. Her iki etkileşim stili üzerinde de çalışmanız gerekir ve her arayüzü bağımsız olarak desteklemeniz gerekebilir.

En önemlisi: Kullanıcı hem dokunmatik ekran hem de fare kullanıyor olabilir.

Birçok geliştirici, bir ortamın dokunma etkinliklerini destekleyip desteklemediğini statik olarak algılayan ve ardından yalnızca dokunma etkinliklerini (fare etkinliklerini değil) desteklemeleri gerektiğini varsayan siteler oluşturmuştur. Bu artık hatalı bir varsayımdır. Dokunma etkinliklerinin mevcut olması, kullanıcının öncelikli olarak dokunmatik giriş cihazını kullandığı anlamına gelmez. Chromebook Pixel ve bazı Windows 8 dizüstü bilgisayarlar gibi cihazlar artık HEM fare HEM DE dokunmatik giriş yöntemlerini desteklemektedir. Yakın gelecekte daha fazla cihaz bu desteği sunacaktır. Bu cihazlarda kullanıcıların uygulamalarla etkileşim kurmak için hem fareyi hem de dokunmatik ekranı kullanması oldukça doğaldır. Bu nedenle, "dokunmatik ekranı destekler" ifadesi "fare desteğine ihtiyaç duymaz" ifadesiyle aynı anlama gelmez. Sorunu "İki farklı etkileşim stili yazmam ve bunlar arasında geçiş yapmam gerekiyor" şeklinde düşünemezsiniz. Her iki etkileşimin hem birlikte hem de bağımsız olarak nasıl çalışacağını düşünmeniz gerekir. Chromebook Pixel'imde sık sık dokunmatik yüzeyi kullanıyorum ancak aynı uygulama veya sayfada ekrana da dokunuyorum. O anda hangisi daha doğal geliyorsa onu yapıyorum. Öte yandan, dokunmatik ekranlı dizüstü bilgisayar kullanıcılarının bazıları dokunmatik ekranı nadiren kullanır veya hiç kullanmaz. Bu nedenle, dokunmatik girişin varlığı fare kontrolünü devre dışı bırakmamalı veya engellememelidir.

Maalesef bir kullanıcının tarayıcı ortamının dokunmatik girişi destekleyip desteklemediğini bilmek zor olabilir. İdeal olarak, masaüstü makinedeki bir tarayıcı her zaman dokunma etkinlikleri için destek gösterir. Böylece, herhangi bir zamanda dokunmatik ekran eklenebilir (ör. KVM aracılığıyla eklenen bir dokunmatik ekran kullanılabilir hale gelirse). Tüm bu nedenlerden dolayı, uygulamalarınız dokunma ve fare arasında geçiş yapmaya çalışmamalı, her ikisini de desteklemelidir.

Fare ve dokunma desteği

1 - Tıklama ve dokunma: İşlerin "doğal" sırası

İlk sorun, dokunma arayüzlerinin genellikle fare tıklamalarını taklit etmeye çalışmasıdır. Dokunma arayüzlerinin daha önce yalnızca fare etkinlikleriyle etkileşim kurmuş uygulamalarda çalışması gerektiği için bu durum normaldir. Kullanıcı fareyle tıklasa veya parmağıyla ekrana dokunsa da "tıklama" etkinlikleri tetiklenmeye devam edeceğinden bunu kısayol olarak kullanabilirsiniz. Ancak bu kısayolla ilgili birkaç sorun var.

Öncelikle, daha gelişmiş dokunma etkileşimleri tasarlarken dikkatli olmanız gerekir: Kullanıcı fare kullandığında tıklama etkinliğiyle yanıt verir ancak kullanıcı ekrana dokunduğunda hem dokunma hem de tıklama etkinlikleri gerçekleşir. Tek bir tıklama için etkinliklerin sırası şöyledir:

  1. touchstart
  2. touchmove
  3. touchend
  4. fareyle üzerine gelme
  5. mousemove
  6. fare düğmesine basma
  7. fare düğmesini bırakma
  8. click

Bu, elbette, touchstart gibi dokunma etkinliklerini işliyorsanız ilgili mousedown ve/veya tıklama etkinliğini de işlemediğinizden emin olmanız gerektiği anlamına gelir. Dokunma etkinliklerini iptal edebiliyorsanız (etkinlik işleyicide preventDefault() çağrısı yapın) dokunma için fare etkinliği oluşturulmaz. Dokunma işleyicilerle ilgili en önemli kurallardan biri şudur:

Ancak bu, diğer varsayılan tarayıcı davranışlarını da (kaydırma gibi) engeller. Bununla birlikte, genellikle dokunma etkinliğini tamamen işleyicinizde işlersiniz ve varsayılan işlemleri devre dışı bırakmak istersiniz. Genel olarak, tüm dokunma etkinliklerini işleyip iptal etmek veya bu etkinlik için bir işleyici kullanmaktan kaçınmak istersiniz.

İkinci olarak, bir kullanıcı mobil cihazdaki bir web sayfasında bulunan bir öğeye dokunduğunda, mobil etkileşim için tasarlanmamış sayfalarda touchstart etkinliği ile fare etkinliklerinin (mousedown) işlenmesi arasında en az 300 milisaniyelik bir gecikme olur. Bu işlem Chrome kullanılarak yapılabilir. Dokunmatik olmayan bir sistemde dokunma arayüzlerini test etmek için Chrome Geliştirici Araçları'nda "Dokunma etkinliklerini taklit et" seçeneğini etkinleştirebilirsiniz.

Bu gecikme, tarayıcıya kullanıcının başka bir hareket (özellikle de çift dokunarak yakınlaştırma) yapıp yapmadığını belirlemesi için zaman tanımak amacıyla uygulanır. Bu durum, parmak dokunuşuna anında yanıt almak istediğiniz durumlarda sorun yaratabilir. Bu gecikmenin otomatik olarak gerçekleştiği senaryoları sınırlamak için çalışmalar devam etmektedir.

Android için Chrome Android Tarayıcı Android için Opera Mobile) Android için Firefox Safari iOS
Ölçeklenemeyen görüntü alanı Gecikme yok 300 ms 300 ms Gecikme yok 300 ms
Görüntü alanı yok 300 ms 300 ms 300 ms 300 ms 300 ms

Bu gecikmeyi önlemenin ilk ve en kolay yolu, mobil tarayıcıya sayfanızın yakınlaştırmaya ihtiyaç duymayacağını "söylemektir". Bu, sabit bir görüntü alanı kullanılarak yapılabilir. Örneğin, sayfanıza şunu ekleyebilirsiniz:

<meta name="viewport" content="width=device-width,user-scalable=no">

Bu her zaman uygun olmayabilir. Bu işlem, erişilebilirlik nedeniyle gerekli olabilecek sıkıştırarak yakınlaştırma özelliğini devre dışı bırakır. Bu nedenle, bu özelliği çok az kullanın (kullanıcı ölçeklendirmeyi devre dışı bırakırsanız uygulamanızda metin okunabilirliğini artırmak için başka bir yöntem sunmak isteyebilirsiniz). Ayrıca, dokunmatik ekranı destekleyen masaüstü sınıfı cihazlardaki Chrome'da ve sayfanın ölçeklendirilemeyen görüntü alanlarına sahip olduğu mobil platformlardaki diğer tarayıcılarda bu gecikme geçerli değildir.

2: Mousemove etkinlikleri dokunmayla tetiklenmez

Bu noktada, dokunma arayüzünde fare etkinliklerinin emülasyonunun genellikle fare hareketi etkinliklerinin emülasyonunu kapsamadığını belirtmek önemlidir. Bu nedenle, fare hareketi etkinliklerini kullanan fareyle kontrol edilen güzel bir kontrol oluşturursanız özellikle dokunma hareketi işleyicileri de eklemediğiniz sürece muhtemelen dokunmatik cihazlarda çalışmaz.

Tarayıcılar genellikle HTML kontrollerindeki dokunma etkileşimleri için uygun etkileşimi otomatik olarak uygular. Örneğin, HTML5 Aralık kontrolleri, dokunma etkileşimlerini kullandığınızda çalışır. Ancak kendi kontrollerinizi uyguladıysanız bunlar muhtemelen tıklama ve sürükleme türü etkileşimlerde çalışmaz. Aslında, en çok tercih edilen bazı kitaplıklar (jQueryUI gibi) henüz dokunma etkileşimlerini bu şekilde yerel olarak desteklememektedir (jQueryUI için bu soruna yönelik birkaç geçici düzeltme vardır). Web Audio Playground uygulamamı dokunmatik cihazlarla çalışacak şekilde yükseltirken karşılaştığım ilk sorunlardan biri buydu. Kaydırma çubukları jQueryUI tabanlı olduğundan tıklayıp sürükleme etkileşimleriyle çalışmıyordu. HTML5 aralık kontrollerine geçtim ve işe yaradı. Alternatif olarak, kaydırıcıları güncellemek için touchmove işleyicileri de ekleyebilirdim ancak bununla ilgili bir sorun var…

3: Touchmove ve MouseMove aynı şey değildir

Birkaç geliştiricinin düştüğünü gördüğüm bir hata, touchmove ve mousemove işleyicilerinin aynı kod yollarını çağırmasıdır. Bu etkinliklerin davranışları birbirine çok benzer ancak küçük farklılıklar vardır. Özellikle dokunma etkinlikleri her zaman dokunmanın BAŞLADIĞI öğeyi hedeflerken fare etkinlikleri o anda fare imlecinin altındaki öğeyi hedefler. Bu nedenle, fareyle üzerine gelme ve fareyle dışına çıkma etkinlikleri vardır ancak bunlara karşılık gelen dokunmayla üzerine gelme ve dokunmayla dışına çıkma etkinlikleri yoktur, yalnızca dokunmayı sonlandırma etkinliği vardır.

Bu durumun en yaygın nedeni, kullanıcının dokunmaya başladığı öğeyi kaldırmanız (veya yerini değiştirmeniz) olabilir. Örneğin, özel kaydırma davranışını desteklemek için tüm bantta dokunma işleyicisi bulunan bir resim bandı düşünün. Mevcut resimler değiştikçe bazı <img> öğelerini kaldırıp başka öğeler eklersiniz. Kullanıcı bu resimlerden birine dokunmaya başlar ve siz de resmi kaldırırsanız işleyiciniz (img öğesinin üst öğesinde bulunur) dokunma etkinliklerini almayı durdurur (çünkü etkinlikler artık ağaçta olmayan bir hedefe gönderilir). Kullanıcı parmağını hareket ettirmiş ve sonunda kaldırmış olsa bile parmağını tek bir yerde tutuyormuş gibi görünür.

Dokunma işlemi etkinken dokunma işleyicileri olan (veya dokunma işleyicileri olan üst öğeleri olan) öğeleri kaldırmayarak bu sorunu önleyebilirsiniz. Alternatif olarak, statik touchend/touchmove işleyicileri kaydetmek yerine bir touchstart etkinliği alana kadar bekleyip ardından touchstart etkinliğinin hedefine touchmove/touchend/touchcancel işleyicileri eklemek (ve bunları end/cancel'da kaldırmak) en iyi yöntemdir. Bu sayede, hedef öğe taşınsa veya kaldırılsa bile dokunma etkinliklerini almaya devam edersiniz. Burada biraz deneme yapabilirsiniz. Kırmızı kutuya dokunun ve basılı tutarken Escape tuşuna basarak kutuyu DOM'dan kaldırın.

4: Dokunma ve :hover

Fare işaretçisi metaforu, imleç konumunu etkin seçimden ayırdı. Bu sayede geliştiriciler, kullanıcılarla alakalı olabilecek bilgileri gizlemek ve göstermek için fareyle üzerine gelme durumlarını kullanabildi. Ancak şu anda çoğu dokunma arayüzü, bir parmağın hedefin üzerinde "gezinmesini" algılamaz.Bu nedenle, bu bilgilere erişmek için dokunma dostu bir yol da sunmadığınız sürece, gezinmeye dayalı olarak anlamsal açıdan önemli bilgiler (ör. "Bu kontrol nedir?" pop-up'ı) sağlamak doğru değildir. Kullanıcılara bilgi aktarmak için fareyle üzerine gelme özelliğini nasıl kullandığınız konusunda dikkatli olmanız gerekir.

Ancak ilginç bir şekilde, CSS :hover sözde sınıfı bazı durumlarda dokunma arayüzleri tarafından tetiklenebilir. Bir öğeye dokunulduğunda, parmak basılıyken öğe :active durumuna geçer ve :hover durumunu da alır. (Internet Explorer'da :hover yalnızca kullanıcının parmağı basılıyken geçerlidir. Diğer tarayıcılar, bir sonraki dokunmaya veya fare hareketine kadar :hover'ı geçerli tutar.) Bu, açılır menülerin dokunma arayüzlerinde çalışmasını sağlamak için iyi bir yaklaşımdır. Bir öğeyi etkin hale getirmenin yan etkisi, :hover durumunun da uygulanmasıdır. Örneğin:

<style>
img ~ .content {
  display:none;
}

img:hover ~ .content {
  display:block;
}
</style>

<img src="/awesome.png">
<div class="content">This is an awesome picture of me</div>

Başka bir öğeye dokunulduğunda, öğe artık etkin olmaz ve fareyle üzerine gelme durumu kaybolur. Bu, kullanıcının fare işaretçisi kullanıp işaretçiyi öğenin dışına taşımasına benzer. İçeriği bir <a> öğesine sarmalayarak sekme durağı haline de getirebilirsiniz. Böylece kullanıcı, fareyle üzerine gelerek veya tıklayarak, dokunarak ya da bir tuşa basarak ek bilgileri açıp kapatabilir ve JavaScript gerekmez. Web Audio Playground'u dokunma arayüzleriyle uyumlu hale getirmek için çalışmaya başladığımda, açılır menülerimin dokunma arayüzleriyle zaten uyumlu olduğunu görmek beni şaşırttı. Bunun nedeni, bu tür bir yapı kullanmış olmamdı.

Yukarıdaki yöntem, fare işaretçisi tabanlı arayüzlerin yanı sıra dokunma arayüzlerinde de iyi sonuç verir. Bu, fareyle üzerine gelindiğinde "title" özelliklerinin kullanılmasıyla (öğe etkinleştirildiğinde GÖSTERİLMEZ) çelişir:

<img src="/awesome.png" title="this doesn't show up in touch">

5: Dokunma ve fare hassasiyeti

Fareler gerçeklikten kavramsal olarak ayrışmış olsa da temel işletim sistemi genellikle imleç için tam piksel hassasiyetini izlediğinden son derece doğru sonuçlar verir. Mobil geliştiriciler ise dokunmatik ekrana parmakla dokunmanın o kadar hassas olmadığını öğrendi. Bunun nedeni, çoğunlukla parmağın ekrana temas eden yüzey alanının boyutu (ve kısmen parmaklarınızın ekranı engellemesi).

Birçok kişi ve şirket, parmak tabanlı etkileşime uygun uygulama ve sitelerin nasıl tasarlanacağı konusunda kapsamlı kullanıcı araştırmaları yapmış ve bu konuda birçok kitap yazılmıştır. Temel tavsiye, dolguyu artırarak dokunma hedeflerinin boyutunu artırmak ve öğeler arasındaki kenar boşluğunu artırarak yanlış dokunma olasılığını azaltmaktır. (Kenar boşlukları, dokunma ve tıklama etkinliklerinin isabet algılama işlemine dahil edilmez ancak dolgu dahil edilir.) Web Audio Playground'da yapmam gereken başlıca düzeltmelerden biri, bağlantı noktalarının boyutlarını artırarak daha kolay ve doğru bir şekilde dokunulabilmelerini sağlamaktı.

Dokunmatik arayüzleri işleyen birçok tarayıcı tedarikçisi, kullanıcı ekrana dokunduğunda doğru öğeyi hedeflemeye yardımcı olmak ve yanlış tıklama olasılığını azaltmak için tarayıcıya mantık da eklemiştir. Ancak bu genellikle yalnızca tıklama etkinliklerini düzeltir, hareketleri düzeltmez (Internet Explorer'ın mousedown/mousemove/mouseup etkinliklerini de değiştirdiği görülmektedir).

6: Dokunma işleyicileri sınırlı tutun, aksi takdirde kaydırma işleminiz kesintiye uğrar

Dokunma işleyicileri yalnızca ihtiyaç duyduğunuz öğelerle sınırlı tutmak da önemlidir. Dokunma öğeleri çok yüksek bant genişliğine sahip olabilir. Bu nedenle, kaydırma öğelerinde dokunma işleyicilerden kaçınmak önemlidir (işlemeniz, hızlı ve takılmasız dokunarak kaydırma için tarayıcı optimizasyonlarını engelleyebilir. Modern tarayıcılar bir GPU iş parçacığında kaydırma yapmaya çalışır ancak her dokunma etkinliğinin uygulama tarafından işlenip işlenmeyeceğini görmek için önce JavaScript ile kontrol etmeleri gerekiyorsa bu mümkün olmaz). Bu davranışın örneğini inceleyebilirsiniz.

Bu sorunu önlemek için, kullanıcı arayüzünüzün yalnızca küçük bir bölümünde dokunma etkinliklerini işliyorsanız dokunma işleyicileri yalnızca bu bölüme eklediğinizden (ör.sayfanın <body> öğesine değil) emin olun. Kısacası, dokunma işleyicilerinizin kapsamını mümkün olduğunca sınırlayın.

7: Çoklu dokunma

Son ilginç zorluk ise, "Dokunmatik" kullanıcı arayüzü olarak adlandırmamıza rağmen, neredeyse her yerde desteğin aslında Çoklu Dokunma için olmasıdır. Yani API'ler aynı anda birden fazla dokunmatik giriş sağlar. Uygulamalarınızda dokunma desteği sunmaya başladığınızda birden fazla dokunmanın uygulamanızı nasıl etkileyebileceğini göz önünde bulundurmanız gerekir.

Uygulamalarınızı öncelikle fareyle kullanılacak şekilde geliştiriyorsanız en fazla bir imleç noktasıyla çalışmaya alışmışsınızdır. Sistemler genellikle birden fazla fare imlecini desteklemez. Birçok uygulamada dokunma etkinliklerini tek bir imleç arayüzüyle eşlemeniz yeterli olacaktır. Ancak masaüstü dokunmatik giriş için gördüğümüz donanımların çoğu en az 2 eşzamanlı girişi işleyebilir ve çoğu yeni donanım en az 5 eşzamanlı girişi destekler. Ekran piyano klavyesi geliştirirken elbette aynı anda birden fazla dokunmatik girişi destekleyebilmek istersiniz.

Şu anda uygulanan W3C Touch API'lerinde, donanımın kaç dokunma noktasını desteklediğini belirleyen bir API yoktur. Bu nedenle, kullanıcılarınızın kaç dokunma noktası isteyeceği konusunda en iyi tahmininizi kullanmanız veya elbette uygulamada kaç dokunma noktası gördüğünüzü dikkate alıp buna uyum sağlamanız gerekir. Örneğin, bir piyano uygulamasında ikiden fazla dokunma noktası görmüyorsanız bazı "akor" kullanıcı arayüzleri eklemek isteyebilirsiniz. PointerEvents API'de cihazın özelliklerini belirleyen bir API vardır.

Rötuş yapılıyor

Bu makalenin, fare etkileşimlerinin yanı sıra dokunma etkileşimlerini uygularken karşılaşılan yaygın zorluklar konusunda size yol gösterdiğini umuyoruz. Elbette diğer tüm tavsiyelerden daha önemli olan, uygulamanızı mobil, tablet ve fare ile dokunmatik ekranın bir arada kullanıldığı masaüstü ortamlarında test etmenizdir. Dokunmatik+fare donanımınız yoksa farklı senaryoları test etmenize yardımcı olması için Chrome'un "Dokunma etkinliklerini taklit et" özelliğini kullanın.

Dokunmatik giriş, fare girişi ve hatta her iki etkileşim tarzıyla aynı anda iyi çalışan ilgi çekici etkileşimli deneyimler oluşturmak yalnızca mümkün değil, aynı zamanda bu kılavuzları takip ederek nispeten kolaydır.