İlk kez tekrar birlikte
Giriş
Yaklaşık otuz yıldır masaüstü bilgisayar deneyimleri, ana kullanıcı giriş cihazlarımız olarak klavye ve fare ya da dokunmatik yüzey etrafında şekilleniyor. Ancak son on yılda akıllı telefonlar ve tabletler yeni bir etkileşim paradigması getirdi: dokunma. Dokunmatik Windows 8 makinelerin kullanıma sunulmasıyla ve şimdi de muhteşem dokunmatik Chromebook Pixel'in piyasaya sürülmesiyle birlikte 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 bazen aynı anda her iki giriş yöntemini de kullanacağı bu cihazlarda çalışacak deneyimler oluşturmaktır.
Bu makalede, dokunma özelliklerinin tarayıcıya nasıl yerleştirildiği, bu yeni arayüz mekanizmasını mevcut uygulamalarınıza nasıl entegre edebileceğiniz ve dokunmanın fare girişiyle nasıl uyumlu olabileceği açıklanmaktadır.
Web Platformunda Dokunma Durumu
iPhone, web tarayıcısında yerleşik özel dokunmatik API'lere sahip ilk popüler platformdu. Diğer bazı tarayıcı tedarikçileri, iOS uygulamasıyla uyumlu olacak şekilde tasarlanmış benzer API arayüzleri oluşturdu. Bu uygulama artık "Touch Events 1 sürümü" spesifikasyonu ile açıklanıyor. Dokunma etkinlikleri; masaüstünde Chrome ve Firefox, iOS'te Safari, Android'de Chrome ve Android tarayıcısı ile Blackberry Tarayıcı gibi diğer mobil tarayıcılar tarafından desteklenir.
İş arkadaşım Boris Smus, dokunma etkinlikleriyle ilgili harika bir HTML5Rocks eğitimi yazdı. Dokunma etkinlikleriyle daha önce hiç ilgilenmediyseniz bu eğitimden yararlanabilirsiniz. Daha önce dokunma etkinlikleriyle çalışmadıysanız devam etmeden önce bu makaleyi okuyun. Devam edin, bekleyeceğim.
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 izleme topu) etkinliklerinden oldukça farklı olabilmesidir. Dokunma arayüzleri genellikle fareleri taklit etmeye çalışır ancak bu taklit mükemmel veya eksiksiz değildir. Her iki etkileşim stilini de kullanmanız ve her bir arayüzü bağımsız olarak desteklemeniz gerekebilir.
En önemlisi: Kullanıcının dokunmatik ekranı ve faresi olabilir
Birçok geliştirici, bir ortamın dokunma etkinliklerini destekleyip desteklemediğini statik olarak algılayan siteler oluşturdu ve ardından yalnızca dokunma etkinliklerini (fare etkinliklerini değil) desteklemeleri gerektiğini varsaydılar. Bu artık hatalı bir varsayımdır. Dokunma etkinliklerinin mevcut olması, kullanıcının öncelikle söz konusu dokunma 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 destekliyor. Yakında daha fazla cihaz bu özelliği destekleyecek. 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, "dokunmayı destekler" ifadesi "fare desteğine ihtiyaç duymaz" ile aynı şey değildir. Sorunu "İki farklı etkileşim stili yazmam ve bunlar arasında geçiş yapmam gerekiyor" şeklinde düşünemezsiniz. Her iki etkileşimin birlikte ve bağımsız olarak nasıl çalışacağını düşünmeniz gerekir. Chromebook Pixel'imde sık sık dokunmatik yüzeyi kullanırım ancak ekrana da uzanıp dokunurum. Aynı uygulama veya sayfada, o anda en doğal geleni yaparım. Öte yandan, bazı dokunmatik ekranlı dizüstü bilgisayar kullanıcı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 kullanıcının tarayıcı ortamının dokunma girişini destekleyip desteklemediğini öğrenmek zor olabilir. İdeal olarak, masaüstü bilgisayardaki bir tarayıcı her zaman dokunma etkinliklerini desteklediğini belirtir. Böylece, dokunmatik ekran her zaman bağlanabilir (ör. KVM üzerinden bağlanan 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 İşlemlerini Birlikte Destekleme
1. Tıklama ve Dokunma: "Doğal" İşlem Sırası
İlk sorun, dokunmatik arayüzlerin genellikle fare tıklamalarını taklit etmeye çalışmasıdır. Dokunmatik arayüzlerin daha önce yalnızca fare etkinlikleriyle etkileşime geçmiş uygulamalarda çalışması gerektiğinden bu durum anlaşılabilir bir durumdur. Kullanıcı fareyle tıklasa veya parmağını ekrana dokundursa da "tıklama" etkinlikleri tetiklenmeye devam edeceğinden bunu kısayol olarak kullanabilirsiniz. Ancak bu kısayolda birkaç sorun vardır.
Öncelikle, daha gelişmiş dokunma etkileşimlerini tasarlarken dikkatli olmanız gerekir: Kullanıcı fare kullandığında bir tıklama etkinliğiyle yanıt verilir ancak kullanıcı ekrana dokunduğunda hem dokunma hem de tıklama etkinlikleri gerçekleşir. Tek tıklama için etkinliklerin sırası şu şekildedir:
- touchstart
- touchmove
- touchend
- fareyle üzerine gelme
- mousemove
- mousedown
- mouseup
- 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 edebilirseniz (etkinlik işleyici içinde preventDefault() çağırın) dokunma için hiçbir fare etkinliği oluşturulmaz. Dokunma işleyicilerle ilgili en önemli kurallardan biri şunlardır:
Ancak bu, dokunma etkinliğini genellikle tamamen işleyicinizde ele alsanız ve varsayılan işlemleri devre dışı bırakmak isteseniz de diğer varsayılan tarayıcı davranışlarını (ör. kaydırma) da engeller. Genel olarak, tüm dokunma etkinliklerini işleyip iptal etmek veya bu etkinlik için işleyici kullanmaktan kaçınmak istersiniz.
İkinci olarak, bir kullanıcı mobil cihazdaki bir web sayfasındaki bir öğeye dokunduğunda, mobil etkileşim için tasarlanmamış sayfalarda touchstart etkinliği ile fare etkinliklerinin işlenmesi (mousedown) arasında en az 300 milisaniyelik bir gecikme olur. Chrome kullanılarak yapılabilir. Dokunmatik olmayan bir sistemde dokunmatik arayüzleri test etmenize yardımcı olması için Chrome Geliştirici Araçları'nda "Dokunma etkinliklerini taklit et" seçeneğini etkinleştirebilirsiniz.
Bu gecikme, kullanıcının başka bir hareket (özellikle de iki kez dokunarak yakınlaştırma) yapıp yapmadığını belirlemek için tarayıcıya zaman tanır. Bu durum, parmak dokunuşuna anında yanıt almak istediğiniz durumlarda soruna yol açabilir. Bu gecikmenin otomatik olarak gerçekleştiği senaryoları sınırlandırmaya yönelik çalışmalar devam etmektedir.
Bu gecikmeyi önlemenin ilk ve en kolay yolu, mobil tarayıcıya sayfanızı yakınlaştırmaya gerek olmadığını "söylemektir". Bu işlem, sabit bir görüntü alanı kullanılarak yapılabilir. Örneğin, sayfanıza şunu ekleyerek:
<meta name="viewport" content="width=device-width,user-scalable=no">
Elbette bu her zaman uygun değildir. Bu işlem, erişilebilirlik nedeniyle gerekli olabilecek iki parmak yakınlaştırma özelliğini devre dışı bırakır. Bu nedenle, bu özelliği mümkünse hiç kullanmayın (kullanıcı ölçeklendirmesini devre dışı bırakırsanız uygulamanızda metin okunabilirliğini artırmanın başka bir yolunu sunabilirsiniz). Ayrıca, dokunmayı destekleyen masaüstü sınıfı cihazlardaki Chrome ve sayfanın ölçeklenebilir olmayan görüntü alanlarını içeren mobil platformlardaki diğer tarayıcılarda bu gecikme geçerli değildir.
#2: Fare hareketi etkinlikleri dokunma ile tetiklenmiyor
Bu noktada, dokunmatik arayüzdeki fare etkinliklerinin emülasyonunun genellikle mousemove etkinliklerini emülasyona dahil etmediğini belirtmek önemlidir. Dolayısıyla, mousemove etkinliklerini kullanan güzel bir fare kontrolörü oluşturursanız touchmove işleyicileri de özel olarak eklemediğiniz sürece bu kontrolör 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 yalnızca dokunma etkileşimlerini kullandığınızda çalışır. Ancak kendi kontrollerinizi uyguladıysanız bunlar muhtemelen tıklayıp sürükleme türü etkileşimlerde çalışmaz. Aslında, yaygın olarak kullanılan bazı kitaplıklar (ör. jQueryUI) henüz bu şekilde dokunma etkileşimlerini doğal olarak desteklemez (ancak jQueryUI için bu sorunla ilgili birkaç düzeltme vardır). Web Audio Playground uygulamamı dokunmatik ekranla çalışacak şekilde yükseltirken karşılaştığım ilk sorunlardan biri bu oldu. Kaydırma çubukları jQueryUI tabanlı olduğundan tıklayıp sürükleme etkileşimleriyle çalışmıyordu. HTML5 aralığı denetimlerine geçtim ve bu denetimler işe yaradı. Alternatif olarak, kaydırma çubuklarını güncellemek için dokunma hareketi işleyicileri de ekleyebilirdim ancak bununla ilgili bir sorun var…
#3: Touchmove ve MouseMove Aynı Şey Değildir
Birkaç geliştiricinin düştüğü bir tuzağa dikkat çekmek istiyorum: touchmove ve mousemove işleyicilerinin aynı kod yollarını çağırması. Bu etkinliklerin davranışı birbirine çok yakındır ancak küçük farklılıklar vardır. Özellikle dokunma etkinlikleri her zaman dokunmanın BAŞLADIĞI öğeyi hedeflerken fare etkinlikleri fare imlecinin altındaki öğeyi hedefler. Bu nedenle, fareyle üzerine gelme ve fareyle üzerinden geçme etkinliklerimiz vardır ancak buna karşılık gelen dokunma üzerine gelme ve dokunma üzerinden geçme etkinlikleri yoktur. Yalnızca dokunma sonu etkinliği vardır.
Bu durumun en yaygın nedeni, kullanıcının dokunmaya başladığı öğeyi kaldırmanız (veya taşımanız) olabilir. Örneğin, özel kaydırma davranışını desteklemek için bandın tamamında dokunma işleyici bulunan bir resim bandı düşünün. Kullanılabilir resimler değiştikçe bazı <img>
öğelerini kaldırıp başkalarını eklersiniz. Kullanıcı bu resimlerden birine dokunmaya başlarsa ve siz resmi kaldırırsanız işleyiciniz (img öğesinin bir üst öğesindedir) dokunma etkinliklerini almayı durdurur (çünkü artık ağaçta olmayan bir hedefe gönderilmektedir). Bu durumda, kullanıcı parmağını hareket ettirip kaldırmış olsa bile parmağını bir yerde tutmuş gibi görünür.
Elbette dokunma etkinken dokunma işleyicileri olan (veya üst öğelerinde dokunma işleyicisi olan) öğeleri kaldırmayarak bu sorunu önleyebilirsiniz. Alternatif olarak, en iyi yöntem statik touchend/touchmove işleyicileri kaydetmek yerine bir touchstart etkinliği alana kadar beklemek ve ardından touchstart etkinliğinin hedefine touchmove/touchend/touchcancel işleyicileri eklemektir (ve bitiş/iptal durumunda bunları kaldırır). Bu sayede, hedef öğe taşınmış/kaldırılmış olsa bile dokunma etkinliklerini almaya devam edersiniz. Burada bu konuyla biraz oynayabilirsiniz. Kırmızı kutuya dokunup ESC tuşunu basılı tutarak DOM'dan kaldırabilirsiniz.
#4: Dokunma ve fareyle üzerine gelme
Fare işaretçisi metaforu, imleç konumunu etkin seçimden ayırdı. Bu da geliştiricilerin, kullanıcılarla alakalı olabilecek bilgileri gizlemek ve göstermek için fareyle üzerine gelme durumlarını kullanmalarına olanak tanıdı. Ancak şu anda çoğu dokunmatik arayüz, bir hedefin üzerinde "fareyle gelip geçen" bir parmak algılamaz.Bu nedenle, fareyle gelip geçmeye dayalı olarak anlamsal açıdan önemli bilgiler (ör. "Bu kontrol nedir?" pop-up'ı) sağlamak, bu bilgilere dokunmatik cihazlar için uygun bir erişim yolu da sağlamadığınız sürece kabul edilemez. Kullanıcılara bilgi aktarmak için fareyle üzerine gelme özelliğini nasıl kullandığınız konusunda dikkatli olmanız gerekir.
İlginç bir şekilde, CSS :hover sözde sınıfı bazı durumlarda dokunmatik arayüzler tarafından tetiklenebilir. Bir öğeye dokunulduğunda, parmak aşağıyken öğe :etkin olur ve :hover durumunu da edinir. (Internet Explorer'da :hover yalnızca kullanıcının parmağı ekrana dokunmuşken geçerlidir. Diğer tarayıcılar ise :hover'ı bir sonraki dokunma veya fare hareketine kadar etkin tutar.) Bu, pop-up menüleri dokunmatik arayüzlerde çalıştırmak için iyi bir yaklaşımdır. Bir öğeyi etkinleştirmenin 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 değildir ve fare işaretçisini öğenin üzerinden hareket ettirdiğinizde olduğu gibi fareyle üzerine gelindiğindeki durum kaybolur. İçeriği sekme durak noktası haline getirmek için bir <a>
öğesine sarmalamak isteyebilirsiniz. Bu sayede kullanıcı, JavaScript'e gerek kalmadan fareyle üzerine gelerek veya tıklayarak, dokunarak ya da tuşa basarak ek bilgileri açabilir veya kapatabilir. Web Audio Playground'u dokunmatik arayüzlerle uyumlu hale getirmeye başladığımda, pop-up menülerimin bu tür bir yapı kullandığım için dokunmatik ekranlarda zaten iyi çalıştığını görmek beni çok şaşırttı.
Yukarıdaki yöntem, fare işaretçisine dayalı arayüzlerin yanı sıra dokunmatik arayüzler için de iyi çalışır. Bu, fareyle üzerine gelindiğinde "title" özelliklerinin kullanılmasının aksinedir. Bu özellikler, öğe etkinleştirildiğinde GÖSTERİLMEZ:
<img src="/awesome.png" title="this doesn't show up in touch">
#5: Dokunma ve Fare Hassasiyeti
Fareler, gerçeklikle kavramsal olarak bağlantılı olmasa da temel işletim sistemi genellikle fare imlecini tam piksel hassasiyetinde izlediği için son derece hassastır. Öte yandan mobil geliştiriciler, dokunmatik ekrana yapılan parmak dokunuşlarının genellikle ekranla temas eden parmağın yüzey alanının büyüklüğü (ve kısmen de parmaklarınızın ekranı engellemesi) nedeniyle o kadar doğru olmadığını öğrendi.
Birçok kişi ve şirket, parmak tabanlı etkileşime uygun uygulamalar ve siteler tasarlama konusunda kapsamlı kullanıcı araştırmaları yaptı ve konu hakkında birçok kitap yazıldı. Temel öneri, dolguyu artırarak dokunma hedeflerinin boyutunu büyütmek ve öğeler arasındaki marjı artırarak yanlış dokunma olasılığını azaltmaktır. (Kenarlıklar, dokunma ve tıklama etkinliklerinin isabet algılama işlemine dahil edilmezken dolgu dahil edilir.) Web Audio Playground'da yapmam gereken en önemli düzeltmelerden biri, bağlantı noktalarının boyutlarını artırarak doğru noktalara daha kolay dokunulmasını sağlamaktı.
Dokunmatik tabanlı arayüzlerle ilgilenen birçok tarayıcı tedarikçisi, kullanıcı ekrana dokunduğunda doğru öğeyi hedeflemeye ve yanlış tıklama olasılığını azaltmaya yardımcı olmak için tarayıcıya mantık da ekledi. 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ülüyor).
#6: Dokunma işleyicilerini kontrol altında tutun, aksi takdirde kaydırma işleminiz bozulur
Dokunma işleyicilerinin yalnızca ihtiyaç duyduğunuz öğelerle sınırlı tutulması da önemlidir. Dokunma öğeleri çok yüksek bant genişliğine sahip olabileceğinden, kaydırma öğelerinde dokunma işleyicilerinden kaçınmak önemlidir (İşleme işleminiz, hızlı ve takılmayan dokunma kaydırma için tarayıcı optimizasyonlarını etkileyebileceğinden - modern tarayıcılar bir GPU iş parçacığında kaydırmaya çalışır ancak her dokunma etkinliğinin uygulama tarafından işlenip işlenmeyeceğini önce JavaScript ile kontrol etmeleri gerekirse bu imkansızdır). Bu davranışa dair bir örneğe göz atabilirsiniz.
Bu sorunu önlemek için uygulayabileceğiniz bir yöntem, yalnızca kullanıcı arayüzünüzün küçük bir kısmında dokunma etkinliklerini işliyorsanız dokunma işleyicileri yalnızca buraya (ör.sayfanın <body>
bölümüne değil) eklemenizdir. Kısacası, dokunma işleyicilerinizin kapsamını mümkün olduğunca sınırlayın.
#7: Çoklu dokunmatik
İlginç bir diğer zorluk da, "Dokunmatik" kullanıcı arayüzü olarak adlandırdığımız bu arayüzün neredeyse her yerde çoklu dokunma için destek sunmasıdır. Yani API'ler aynı anda birden fazla dokunma girişi sağlar. Uygulamalarınızda dokunma özelliğini desteklemeye başladığınızda birden fazla dokunmanın uygulamanızı nasıl etkileyebileceğini göz önünde bulundurmanız gerekir.
Uygulamaları ağırlıklı olarak fareyle geliştiriyorsanız en fazla bir imleç noktasıyla geliştirmeye alışkınsınızdır. Sistemler genellikle birden fazla fare imlecini desteklemez. Birçok uygulamada, dokunma etkinliklerini tek bir imleç arayüzüyle eşlersiniz. Ancak masaüstü dokunma girişi için gördüğümüz donanımların çoğu en az 2 eşzamanlı girişi işleyebilir ve yeni donanımların çoğu en az 5 eşzamanlı girişi destekliyor gibi görünüyor. Ekran klavyesi geliştirmek için birden fazla dokunma girişini aynı anda desteklemeniz gerekir.
Şu anda uygulanmakta olan W3C Touch API'lerinde, donanımın kaç temas noktasını desteklediğini belirleyen bir API yoktur. Bu nedenle, kullanıcılarınızın kaç temas noktası isteyeceği konusunda en iyi tahmininizi kullanmanız veya elbette pratikte kaç temas noktası gördüğünüze dikkat etmeniz ve buna göre uyum sağlamanız gerekir. Örneğin, bir piyano uygulamasında ikiden fazla dokunma noktası görmüyorsanız bazı "akor" kullanıcı arayüzü ekleyebilirsiniz. PointerEvents API'de cihazın özelliklerini belirleyen bir API vardır.
Rötuş
Bu makalenin, fare etkileşimlerinin yanı sıra dokunma özelliğini uygulamayla ilgili yaygın zorluklar konusunda size yol göstermiş olması dileğiyle. Elbette diğer tüm tavsiyelerden daha önemli olan, uygulamanızı mobil cihazlarda, tabletlerde ve fare ile dokunmatik ekranın birlikte kullanıldığı masaüstü ortamlarında test etmenizdir. Dokunmatik ekran ve fare donanımınız yoksa farklı senaryoları test etmek için Chrome'un "Dokunma etkinliklerini taklit et" özelliğini kullanın.
Bu yönergeleri uygulayarak dokunma girişi, fare girişi ve hatta her iki etkileşim tarzıyla aynı anda iyi çalışan ilgi çekici etkileşimli deneyimler oluşturmak hem mümkün hem de nispeten kolaydır.