AMP'de Gelişmiş Etkileşim

Accelerated Mobile Pages (AMP) sürekli olarak hızlı, güzel görünen ve yüksek performans gösteren web siteleri ve reklamlar oluşturmayı sağlayan bir açık kaynak girişimidir.

AMP'yi kullanmaya yeni başladıysanız aşağıdaki kaynakları kullanarak genel bir bakış yapabilirsiniz:

Motivasyon

AMP; resim ruloları ve lightbox'lar gibi kullanıcı arayüzü bileşenleri ile zengin ve dinamik içerikleri destekler. AMP, bir bileşenin AMP İşlemleri aracılığıyla başka bir bileşendeki işlemi tetiklemesinin bazı basit yollarını da destekler.

Peki, aşağıdakileri yapmak istersem:

  • AMP bileşeni özelleştirilsin mi?
  • Örneğin, bir resim bandındaki geçerli slaytı ve toplam slayt sayısını gösteren özel bir etiket görüntüleyin.
  • Durum bilgili davranışlar eklensin mi?
  • Örneğin, kullanıcının seçili ürün miktarının mevcut stok durumunu aşması durumunda "Sepete ekle" düğmesini devre dışı bırakın.

Daha önce, kullanıcı arayüzü bileşenleri ile sağlam bir paylaşım durumuna sahip olamamaları nedeniyle AMP'de bu gibi özellikleri uygulamak zordu. Bu kullanım alanlarını çözmek için AMP'de güçlü ve yeni bir bileşen oluşturduk.

<amp-bind>

<amp-bind>, veri bağlama ve JS benzeri ifadeler aracılığıyla özel etkileşim sunan yeni bir AMP bileşenidir. Bu codelab'de, zengin ve özel etkileşime sahip bir AMP sayfası oluşturmak için <amp-bind> kullanma adımlarında size yol göstereceğiz.

Oluşturacağınız uygulama

Bu codelab'de, e-ticaret ürün ayrıntıları sayfası oluşturacaksınız:

  • Hızlı ve zengin bir kullanıcı deneyimi sunan web sayfası oluşturmak için AMP HTML ve AMP bileşenlerini kullanın
  • Öğeler arası etkileşim eklemek için <amp-bind> kullanın
  • İsteğe bağlı olarak ek ürün verileri getirmek için <amp-state> kullanın

Neler öğreneceksiniz?

  • <amp-bind> ile muhteşem ve etkileşimli AMP sayfaları oluşturmak için veri bağlama ve ifadeleri nasıl kullanabilirsiniz?

Gerekenler

  • İstediğiniz bir tarayıcı
  • İstediğiniz metin düzenleyici
  • Node.js ve NPM
  • Örnek kod
  • HTML, CSS ve JavaScript ile ilgili temel bilgiler

Kodu indirin

Öncelikle, codelab'in başlangıç kodunu ZIP dosyası olarak alın:

İndir

Veya git ile:

git clone https://github.com/googlecodelabs/advanced-interactivity-in-amp.git

Bağımlıları yükleyin

Arşiv dosyasını açın (gerekirse) ve dizine gidin. npm install komutunu çalıştırarak bağımlılıkları yükleyin.

cd advanced-interactivity-in-amp-codelab
npm install

Geliştirme sunucusunu çalıştırma

Geliştirme sunucusunu Node.js ile başlatın:

node app.js

AMP sayfasının çalıştığını görmek için web tarayıcınızda http://localhost:3000 adresine gidin.

AMP Ortak Kartı

AMP sayfası, güvenilir performans için bazı kısıtlamalar içeren bir HTML sayfasıdır. AMP sayfalarında, sayfanın Google Arama'da AMP sayfası olarak tanımlanmasını sağlayan özel bir işaretleme bulunur.

Barebones AMP sayfası aşağıdaki gibi görünür:

<!doctype html>
<html amp>
 <head>
   <meta charset="utf-8">
   <link rel="canonical" href="hello-world.html">
   <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
   <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
   <script async src="https://cdn.ampproject.org/v0.js"></script>
 </head>
 <body>Hello World!</body>
</html>

AMP Bileşenleri

Başlangıç kodumuz (static/index.html), sayfa içeriğini (resimler, metin vb.) içeren barebon AMP AMP sayfasının yanı sıra birkaç AMP bileşeni ekler:

<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
<script async custom-element="amp-selector" src="https://cdn.ampproject.org/v0/amp-selector-0.1.js"></script>

AMP bileşenleri, AMP sayfalarına zengin etkileşim katan ek işlevler ve kullanıcı arayüzü bileşenleri sunmaktadır. Başlangıç kodu aşağıdaki AMP bileşenlerini kullanır:

  • <amp-carousel>
  • Ürünün birden fazla görünümünü gösteren bir resim rulosu.
  • <amp-mustache>
  • amp-form sunucu yanıtlarını oluşturmak için bir şablon sistemi.
  • <amp-form>
  • AMP sayfaları için gerekli olan <form> öğelerine özel işlevler ekler.
  • <amp-selector>
  • Bir öğe grubundan bir veya daha fazla öğe seçmek için semantik bir yöntem sunar. amp-form için giriş kaynağı olarak kullanılabilir.

Temel etkileşim

Başlangıç kodu bazı temel etkileşimler sağlar:

  • Resim rulosu (<amp-carousel>) ürünün birden çok görünümünü gösterir.
  • Ürün, sayfanın en altında bulunan "Sepete ekle" düğmesine dokunarak kullanıcının alışveriş sepetine eklenebilir (<amp-form> ile).

Resim rulosu üzerinde kaydırma yapıp "Sepete ekle" düğmesine dokunmayı deneyin.

Deneyimi iyileştirin

Başlangıç kodu, oldukça yalın bir kullanıcı deneyimi sunar. Bunu iyileştirmenin birkaç yolu vardır:

  • Geçerli slaytı ve toplam slayt sayısını görüntüleyen bir gösterge ekleyin.
  • Kullanıcı farklı bir gömlek rengi seçtiğinde, resim işaretlerinin seçili renkteki gömlek resimlerini gösterecek şekilde değiştirin.

<amp-bind> bileşeni kullanıma sunulmadan önce, bunlara benzer özellikler eklemek mümkün değildi. <amp-bind> ile uygulamalı deneyim kazanıp bu yeni özellikleri örnek kodumuza ekleyelim.

<amp-bind> uzantısını yükleyin

<amp-bind>, veri bağlama ve JS benzeri ifadeler aracılığıyla özel etkileşim sağlayan yeni bir AMP bileşenidir. <amp-bind> kullanmak için sayfaya yüklemeniz gerekir.

static/index.html dosyasını açın ve aşağıdaki komut dosyasını sayfanın <head> bölümündeki AMP bileşenleri listesine ekleyin:

<script async custom-element="amp-bind"
    src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>

Slayt göstergesi ekleme

<amp-bind>, öğe özelliklerini özel ifadelere bağlayarak çalışır. Bu ifadeler, "state" (değişebilir JSON verileri) referansı olabilir. Bu durumu, <amp-bind> ile birlikte gelen <amp-state> bileşeni aracılığıyla başlatabiliriz.

Resim rulosunda gösterilmekte olan slaytın dizinini takip etmek için bir durum değişkeni başlatalım. static/index.html sayfasını açın ve aşağıdakileri sayfanın <body> üst kısmına ekleyin (başlıktan önce):

<amp-state id="selected">
  <script type="application/json">
    {
      "slide": 0
    }
  </script>
</amp-state>

<amp-state> öğelerinin içindeki verilere, ilişkili kimlikleri tarafından erişilebilir. Örneğin, bu değişkene aşağıdaki ifade parçasıyla başvurabiliriz:

selected.slide // Evaluates to 0.

Şimdi, kullanıcı bant üzerinde slaytları değiştirirken mevcut <amp-carousel> öğesine "&t;in" işlemi ekleyerek bu değişkeni güncelleyelim:

<amp-carousel type="slides" layout="fixed-height" height=250 id="carousel"
    on="slideChange:AMP.setState({selected: {slide: event.index}})">

Şimdi, <amp-carousel>&#39'un görüntülenen slaytı her değiştiğinde AMP.setState işlemi aşağıdaki bağımsız değişkenle çağrılacaktır:

{
  selected: {
    slide: event.index
  }
}

event.index ifadesi yeni slayt dizinini değerlendirir ve AMP.setState() işlemi, bu nesne değişmez değerini geçerli durumla birleştirir. Bu işlem, mevcut selected.slide değerini event.index değeriyle değiştirir.

Şimdi de hâlihazırda gösterilen slaytı izleyen bu durum değişkenini kullanalım ve bir slayt göstergesi oluşturun. Slayt göstergesi öğesini bulun (<!-- TODO: "Add a slide indicator" --> öğesini bulun) ve alt bağlamalarına aşağıdaki bağlamaları ekleyin:

<!-- TODO: "Add a slide indicator" -->
<p class="dots">
  <!-- The <span> element corresponding to the current displayed slide
       will have the 'current' CSS class. -->
  <span [class]="selected.slide == 0 ? 'current' : ''" class="current"></span>
  <span [class]="selected.slide == 1 ? 'current' : ''"></span>
  <span [class]="selected.slide == 2 ? 'current' : ''"></span>
</p>

[class], class özelliğini değiştiren bir bağlamadır. Bu özelliği kullanarak herhangi bir öğeye CSS sınıfı ekleyebilir veya kaldırabilirsiniz.

Şimdi sayfayı yenileyip deneyin. Banttaki slaytı değiştirerek:

  1. slideChange etkinliğini tetikler...
  2. AMP.setState işlemini çağıran...
  3. selected.slide durum değişkenini günceller...
  4. Bu gösterge <span> öğelerinde [class] bağlamasını günceller.

Güzel! Şimdi ise çalışan bir slayt göstergesi var.

Seçili rengi değiştirdiğimizde farklı gömlek renklerinin resimlerini görmekten memnun oluruz. amp-bind ile bunu <amp-carousel> içindeki <amp-img> öğelerine [src] bağlayarak bağlayabiliriz.

Ancak öncelikle, her bir renk gömleğinin resim kaynağı URL'leriyle durum verilerini başlatmamız gerekir. Bunu yeni bir <amp-state> öğesiyle yapalım:

<!-- Available shirts. Maps unique string identifier to color and image URL string. -->
<amp-state id="shirts">
  <script type="application/json">
    {
      "1001": {
        "color": "black",
        "image": "./shirts/black.jpg"
      },
      "1002": {
        "color": "blue",
        "image": "./shirts/blue.jpg"
      },
      "1010": {
        "color": "brown",
        "image": "./shirts/brown.jpg"
      },
      "1014": {
        "color": "dark green",
        "image": "./shirts/dark-green.jpg"
      },
      "1015": {
        "color": "gray",
        "image": "./shirts/gray.jpg"
      },
      "1016": {
        "color": "light gray",
        "image": "./shirts/light-gray.jpg"
      },
      "1021": {
        "color": "navy",
        "image": "./shirts/navy.jpg"
      },
      "1030": {
        "color": "wine",
        "image": "./shirts/wine.jpg"
      }
    }
  </script>
</amp-state>

Bu <amp-state> öğesi, bir gömlek tanımlayıcı dizesini (ör. SKU) ilgili gömleğin rengi ve resim URL'siyle eşleyen bir JSON nesnesi içerir. Bir JSON dizisi de burada çalışır, ancak nesne kullanmanız, yakında göreceğiniz daha hoş şeyler yapmamıza olanak tanır.

Artık resim URL'sine gömlek tanımlayıcısı üzerinden ulaşabiliyoruz. Örneğin shirts['10014'].color, "dark green" olarak değerlendirilir. shirts['10030'].image ise "şarap" gömleği renginin resim URL'sini döndürür.

Seçilen SKU'yu izleyen başka bir durum değişkeni eklersek seçili SKU değiştiğinde src özelliklerini güncellemek için <amp-img> öğelerine bir ifade bağlayabiliriz. Mevcut amp-state#selected öğesine ait yeni bir sku anahtarı ekleyin:

<amp-state id="selected">
  <script type="application/json">
    {
      "slide": 0,
      "sku": "1001"
    }
  </script>
</amp-state>

<amp-selector> ürününe yeni bir renk seçildiğinde selected.sku değişkenini güncelleyen bir işlem ekleyin:

<amp-selector name="color" 
    on="select:AMP.setState({selected: {sku: event.targetOption}})">

Ardından, <amp-carousel> içindeki <amp-img> öğelerine bağlama ekleyin (<!-- TODO: "Changing images in amp-carousel-->" öğesini arayın):

<!-- Update the `src` of each <amp-img> when the `selected.sku` variable changes. -->
<amp-img width=200 height=250 src="./shirts/black.jpg"
    [src]="shirts[selected.sku].image"></amp-img>
<amp-img width=300 height=375 src="./shirts/black.jpg"
    [src]="shirts[selected.sku].image"></amp-img>
<amp-img width=400 height=500 src="./shirts/black.jpg"
    [src]="shirts[selected.sku].image"></amp-img>

Not: Pratikte banttaki her resmin büyük olasılıkla farklı bir src'sı olur. Bu işlem, tek resmin bir resim dizisiyle değiştirilmesiyle yapılabilir. Basitlik sağlamak için bu codelab'de farklı büyütme değerlerinde tek bir resim kullanılmaktadır.

Şimdi sayfayı yenileyin ve gömlek için farklı bir renk seçin. Bunu yaptığınızda, atlı karınca resimleri seçilen renkteki gömlekleri gösterecek şekilde güncellenir.

Bağlanabilir verileriniz sayfa yüklemesinde alınamayacak kadar büyük veya karmaşıksa ne yapmalıyım? Ya da her SKU'nun aranması uzun süren bir fiyat varsa ne olur? Görüntülenmeyen öğeler için SKU fiyatlarına yapılan aramalar boşa harcanır.

Gömlek için mevcut bedenler alınıyor

Codelab örneğimizde SKU'ların fiyatlarını aramak için uzaktan veri alma özelliğinden yararlanalım. app.js içindeki Express.js geliştirme sunucumuz zaten bir gömlek SKU'su olduğunda her beden için mevcut boyutları ve fiyatı döndüren bir /shirts/sizes?shirt=<sku> uç noktasına sahip. Ağ gecikmesini simüle etmek için yanıtı bir saniyelik yapay gecikmeyle gönderir.

İstek

Yanıt

GET /shirts/sizesAndPrices?sku=1001

{"1001: {"sizes": {"XS": 8.99, "S" 9.99}}}

<amp-state> öğelerinin içindeki JSON verilerine benzer şekilde, bu getirmelerden döndürülen uzak veriler öğenin id özelliği altında birleştirilir ve kullanılabilir. Örneğin, yukarıdaki örnek yanıttan döndürülen verilere bir ifadede erişilebilir:

İfade

Sonuç

shirts['1001'].sizes['XS']

8.99

Şimdi bunu e-ticaret örneğimize uygulayalım. Yeni bir SKU seçildiğinde ilk olarak bu gömlek verilerini getirelim. amp-state#shirts öğemize bir [src] bağlama ekleyin:

<!-- When `selected.sku` changes, update the `src` attribute and fetch
     JSON at the new URL. Then, merge that data under `id` ("shirts"). -->
<amp-state id="shirts" [src]="'/shirts/sizesAndPrices?sku=' + selected.sku">

Ardından, belirli bir SKU için kullanılamayan boyutları bu şekilde açıkça işaretleyelim. "unavailable" CSS sınıfı, bir öğe yoluyla çapraz çizgi ekler. Bunu, amp-selector[name="size"] içindeki öğelere kullanılamayan boyutlara karşılık gelen şekilde ekleyebiliriz:

<amp-selector name="size">
  <table>
    <tr>
      <!-- If 'XS' size is available for selected SKU, return empty string.
           Otherwise, return 'unavailable'. -->
      <td [class]="shirts[selected.sku].sizes['XS'] ? '' : 'unavailable'">
        <div option="XS">XS</div>
      </td>
      <td [class]="shirts[selected.sku].sizes['S'] ? '' : 'unavailable'">
        <div option="S">S</div>
      </td>
      <td [class]="shirts[selected.sku].sizes['M'] ? '' : 'unavailable'">
        <div option="M">M</div>
      </td>
      <td [class]="shirts[selected.sku].sizes['L'] ? '' : 'unavailable'">
        <div option="L">L</div>
      </td>
      <td [class]="shirts[selected.sku].sizes['XL'] ? '' : 'unavailable'">
        <div option="XL">XL</div>
      </td>
    </tr>
  </table>
</amp-selector>

Şimdi sayfayı yeniden yükleyip deneyin. Yeni bir SKU (tişört rengi) seçildiğinde, kullanılamayan boyutların üstü çizilir (kısa bir gecikmenin ardından).

Yine de küçük bir sorun var. Varsayılan siyah renk olan siyah gömlek nasıl? Siyah gömleğin beden ve fiyat verilerini amp-state#shirts ürününe eklememiz gerekiyor.

<amp-state id="shirts" [src]="'/shirts/sizesAndPrices?sku=' + selected.sku">
  <script type="application/json">
    {
      "1001": {
        "color": "black",
        "image": "./shirts/black.jpg",
        "sizes": {
          "XS": 8.99,
          "S": 9.99
        }
      },
<!-- ... -->

...alakalı öğelerin varsayılan durumunu da güncelleyebilir.

<amp-selector name="size">
  <table>
    <tr>
      <!-- If 'XS' size is available for selected SKU, return empty string.
           Otherwise, return 'unavailable'. -->
      <td [class]="shirts[selected.sku].sizes['XS'] ? '' : 'unavailable'">
        <div option="XS">XS</div>
      </td>
      <td [class]="shirts[selected.sku].sizes['S'] ? '' : 'unavailable'">
        <div option="S">S</div>
      </td>
      <!-- Add the ‘unavailable' class to the next three <td> elements
           to be consistent with the available sizes of the default SKU. -->
      <td class="unavailable" 
          [class]="shirts[selected.sku].sizes['M'] ? '' : 'unavailable'">
        <div option="M">M</div>
      </td>
      <td class="unavailable" 
          [class]="shirts[selected.sku].sizes['L'] ? '' : 'unavailable'">
        <div option="L">L</div>
      </td>
      <td class="unavailable" 
          [class]="shirts[selected.sku].sizes['XL'] ? '' : 'unavailable'">
        <div option="XL">XL</div>
      </td>
    </tr>
  </table>
</amp-selector>

Değişken gömlek fiyatları

Mevcut boyutları doğru şekilde gösterdiğimize göre şimdi doğru fiyatın da gösterildiğinden emin olalım.

AMPPAREL mağazamız, gömlek fiyatının hem renk hem de bedene özgü olmasıdır. Yani, kullanıcı tarafından seçilen boyutu izlemek için yeni bir değişkene ihtiyacımız var. Beden <amp-selector> öğemize yeni bir işlem ekleyin:

<!-- When an element is selected, set the `selectedSize` variable to the
     value of the "option" attribute of the selected element.  -->
<amp-selector name="size" 
    on="select:AMP.setState({selectedSize: event.targetOption})">

selectedSize değerini amp-state#selected öğesi aracılığıyla başlatmadığımızı unutmayın. Bunun nedeni, bilinçli olarak varsayılan bir boyut sağlamamamız ve bunun yerine kullanıcıyı boyut seçmeye zorlamaktır.

Fiyat etiketini sarmalayan yeni bir <span> öğesi ekleyin ve varsayılan boyut seçimi olmadığından varsayılan metni "---" olarak değiştirin.

<h6>PRICE :
  <!-- Display the price of the selected shirt in the selected size if available.
       Otherwise, display the placeholder text '---'. -->
  <span [text]="shirts[selected.sku].sizes[selectedSize] || '---'">---</span>
</h6>

Ve doğru fiyatlar! Bu hizmeti kullanmayı deneyin.

Koşula bağlı olarak etkinleştirilen düğme

Neredeyse bitti! Şimdi, seçilen boyut kullanılamadığında "Sepete ekle" düğmesini devre dışı bırakalım:

<!-- Disable the "ADD TO CART" button when:
     1. There is no selected size, OR
     2. The available sizes for the selected SKU haven't been fetched yet
-->
<input type="submit" value="ADD TO CART" disabled
    class="mdl-button mdl-button--raised mdl-button--accent"
    [disabled]="!selectedSize || !shirts[selected.sku].sizes[selectedSize]">

Her bir SKU için değişken boyut ve fiyatların yer aldığı, isteğe bağlı uzak bir JSON uç noktasından getirilen etkileşimli e-ticaret ürün ayrıntıları sayfası vardır.

Takıldığınız nokta varsa çözümün tamamı için static/final.html adresine bakın.

Bu codelab'in, <amp-bind> ile etkileşimli AMP sayfaları oluşturma gücünü ve esnekliğini gösterdiğini umuyoruz. Daha fazla bilgi için <amp-bind> dokümanlarını inceleyin.

Geri bildirim almayı seviyoruz. Lütfen özellik isteklerinizi, önerilerinizi veya hata raporlarınızı bize gönderin. <amp-bind> ürününü gerçek kullanıcılarla test etmek istiyorsanız kaynak denemesi için başvurabilirsiniz.

<amp-bind> uygulamasını kısa süre içinde kullanıma sunmanın heyecanını yaşıyoruz ve onunla neler geliştirebileceğinizi görmek için sabırsızlanıyoruz.