AMP

重要事項:本文件不適用於您目前選取的格式 stories

amp-bind

說明

允許元素透過資料繫結和類似 JS 的簡單運算式,回應使用者動作或資料變更而產生變化。

 

必要指令碼

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

用法

amp-bind 元件可在 AMP 網頁上啟用自訂的狀態互動功能。

為了效能考量,並避免內容意外跳動的風險,amp-bind 不會在網頁載入時評估運算式。這表示視覺元素應具備預設狀態,且不應依賴 amp-bind 進行初始轉譯。

觀看此影片,瞭解 amp-bind 的簡介。

amp-bind 有三個主要概念

  1. 狀態:文件範圍、可變的 JSON 狀態。狀態變數會回應使用者動作而更新。amp-bind 不會在網頁載入時評估運算式。視覺元素應定義其預設「狀態」,且不應依賴 amp-bind 進行初始轉譯。
  2. 運算式:類似 JavaScript 的運算式,可參照狀態
  3. 繫結:特殊屬性,可透過運算式將元素的屬性連結至狀態。屬性會以方括號括住 (形式為 [property]) 的方式繫結。

未宣告狀態的範例

Hello World (哈囉,世界)

<p [text]="'Hello ' + foo">Hello World</p>

<button on="tap:AMP.setState({foo: 'Interactivity'})">
  Say "Hello Interactivity"
</button>
在 Playground 中開啟此程式碼片段

在上述範例中

  • 狀態一開始是空的。
  • 它在 <p> 元素上,具有與 [text] (節點的文字內容) 的單一繫結
  • [text] 值包含運算式 'Hello ' + foo。此運算式會串連字串 'Hello ' 和狀態變數 foo 的值。

當使用者輕觸/按一下按鈕時

  1. 會觸發 tap 事件。
  2. tap 事件會叫用 AMP.setState() 方法。
  3. AMP.setState() 方法會將 foo 狀態變數設為 Interactivity 的值。
  4. 狀態不再是空的,因此網頁會將繫結的屬性更新為其狀態。

在某些範例中,呼叫 AMP.setState() 可能會設定或變更網頁上其他範例的狀態。重新整理本網頁即可查看 AMP.setState() 之前的範例。

已宣告狀態的範例

<amp-state> 規格

狀態

每個使用 amp-bind 的 AMP 文件都有文件範圍的可變 JSON 資料或狀態

大小

<amp-state> 元素的 JSON 資料大小上限為 100KB。

使用 <amp-state> 定義和初始化狀態

運算式不會在網頁載入時評估,但您可以定義初始狀態。<amp-state> 元件包含不同的狀態及其狀態變數。雖然這會定義狀態,但在使用者互動後才會反映在網頁上。

<amp-state id="myDefinedState">
  <script type="application/json">
    {
      "foo": "bar"
    }
  </script>
</amp-state>
<p [text]="myDefinedState.foo"></p>
<button on="tap:AMP.setState({})">See value of initialized state</button>
在 Playground 中開啟此程式碼片段

使用運算式參照狀態變數。如果 JSON 資料未巢狀於 <amp-state> 元件中,請透過點語法參照狀態。在上述範例中,myState.foo 的評估結果為 "bar"。

<amp-state> 元素也可以指定 CORS URL,而非子 JSON 指令碼。詳情請參閱 <amp-state> 規格

<amp-state id="myRemoteState" src="/static/samples/json/websites.json">
</amp-state>

使用 AMP.setState() 更新狀態變數

AMP.setState() 動作會將物件常值合併至狀態。這表示您可以更新已定義狀態變數的值。

<amp-state id="myUpdateState">
  <script type="application/json">
    {
      "foo": "bar",
      "baz": "hello"
    }
  </script>
</amp-state>
<p [text]="myUpdateState.foo"></p>
<p [text]="myUpdateState.baz"></p>
<button on="tap:AMP.setState({})">See value of set state</button>
<!-- Like JavaScript, you can reference existing
     variables in the values of the  object literal. -->
<button on="tap:AMP.setState({myUpdateState:{baz: myUpdateState.foo}})">
  Set value of baz to value of foo
</button>
<button on="tap:AMP.setState({myUpdateState:{baz: 'world'}})">
  Set value of baz to "world"
</button>
在 Playground 中開啟此程式碼片段

在上述範例中,觸發第一個按鈕上的 AMP.setState({}) 動作會評估 [text] 繫結運算式。然後,它會將已定義狀態變數的值插入 <p> 標記。

當按一下第二個按鈕 (已定義 AMP.setState({myState:{baz: myState.foo}}) 動作) 時,它會將 "baz" 狀態變數深度合併為與 "foo" 狀態變數值相同。兩個 <p> 標記都會顯示 "bar"。

狀態變數值可以更新為未在初始狀態中定義的值。當按一下第三個按鈕 (已定義 "tap:AMP.setState({myState:{baz: 'world'}})" 動作) 時,它會深度合併 "baz" 狀態變數值,並將其覆寫為 "world"。

在其他兩個按鈕之後按一下第一個按鈕,即可設定目前的狀態。不會有任何變更。

狀態變數會在網頁重新整理時還原為 <amp-state> 中定義的 JSON。

事件觸發和資料

當由特定事件觸發時,AMP.setState() 可以存取 event 屬性上的事件相關資料。

<!-- The "change" event of this <input> element contains
     a "value" variable that can be referenced via "event.value". -->
<select on="change:AMP.setState({ option: event.value })">
  <option value="0">No selection</option>
  <option value="1">Option 1</option>
  <option value="2">Option 2</option>
</select>
<div hidden [hidden]="option != 1">
  Option 1
</div>
<div hidden [hidden]="option != 2">
  Option 2
</div>
在 Playground 中開啟此程式碼片段

更新巢狀變數

巢狀物件通常會合併至最多 10 層的深度。所有變數 (包括在 <amp-state> 中定義的變數) 都可以覆寫。

<amp-state id="myState">
  <script type="application/json">
    {
      "foo": "bar",
      "first": {
        "a": "nested once",
        "ab": {
          "b": "nested twice",
          "bc": {
            "c": "nested three times",
            "cd": {
              "d": "nested four times",
              "de": {
                "e": "nested five times",
                "ef": {
                  "f": "nested six times",
                  "fg": {
                    "g": "nested seven times",
                    "gh": {
                      "h": "nested nine times",
                      "hi": {
                        "i": "nested ten times"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  </script>
</amp-state>
<p [text]="myState.foo"></p>
<p [text]="myState.first.ab.bc.cd.de.ef.fg.gh.hi.i"></p>
<button on="tap:AMP.setState({})">See value of set state</button>
<button
  on="tap:AMP.setState({ myState: {first: {ab: {bc: {cd: {de: {ef: {fg: {gh: {hi: {i:'this is as far as you should merge nested values'} } } } } } } } } } })"
>
  Merge 10th nested object
</button>
在 Playground 中開啟此程式碼片段

循環參考

如果 object 包含循環參考,AMP.setState(object) 會擲回錯誤。

移除變數

將現有的狀態變數的值設為 AMP.setState() 中的 null,即可移除該變數。

<button on="tap:AMP.setState({removeMe: null})"></button>

使用 AMP.setState() 進行深度合併

呼叫 AMP.setState() 會將提供的物件常值與目前的狀態進行深度合併。amp-bind 會將所有常值直接寫入狀態,但巢狀物件除外,巢狀物件會以遞迴方式合併。狀態中的基本類型和陣列一律會被物件常值中相同名稱的變數覆寫。

姓名

年齡

交通工具

<p [text]="employee.name">Name</p>
<p [text]="employee.age">Age</p>
<p [text]="employee.vehicle">Vehicle</p>
<!-- Pressing this button changes state to: -->
<button
  on="tap:AMP.setState({
              employee: {
                name: 'John Smith',
                age: 47,
                vehicle: 'Car'
              }
            })"
>
  Set employee to John Smith
</button>
<!-- Pressing this button recursively merges the object literal argument,  -->
<!-- `{employee: {age: 64}}`, into the existing state. -->

<button
  on="tap:AMP.setState({
              employee: {
                age: 64
              }
            })"
>
  Set employee age to 64
</button>
<!-- The value updates from 47 to 64 at employee.age.  -->
<!-- No other values change. -->
在 Playground 中開啟此程式碼片段

運算式

amp-bind 使用類似 JavaScript 的運算式,可以參照狀態。

與 JavaScript 的差異

  • 運算式只能存取包含文件的狀態
  • 運算式無法存取 windowdocumentglobal 參照最上層狀態。
  • 只有 amp-bind 允許清單函數和運算子可以使用。可以使用。允許將箭頭函數做為函數參數,例如 [1, 2, 3].map(x => x + 1)
    • 不允許使用自訂函數、類別和迴圈。
  • 未定義的變數和超出陣列索引範圍會傳回 null,而不是 undefined 或擲回錯誤。
  • 為了效能考量,單一運算式目前限制為 250 個運算元。如果您的使用案例需要更多運算元,請聯絡我們

以下都是有效的運算式

<p [text]="myExpressionsState.foo"></p>
<!-- 1 + '1'; // 11 -->
<button on="tap:AMP.setState({myExpressionsState: {foo: 1 + '1'}})">
  foo: 1 + "1"
</button>
<!-- 1 + +'1'; // 2 -->
<button on="tap:AMP.setState({myExpressionsState: {foo: 1 + + '1'}})">
  foo: 1 + + "1"
</button>
<!-- !0; // true -->
<button on="tap:AMP.setState({myExpressionsState: {foo: !0}})">foo: !0</button>
<!-- null || 'default'; // 'default' -->
<button on="tap:AMP.setState({myExpressionsState: {foo: null || 'default'}})">
  null || "default"
</button>
<!-- [1, 2, 3].map(x => x + 1); // 2,3,4 -->
<button
  on="tap:AMP.setState({myExpressionsState: {foo: [1, 2, 3].map(x => x + 1)}})"
>
  [1, 2, 3].map(x => x + 1)
</button>
在 Playground 中開啟此程式碼片段

如要尋找完整的運算式文法和實作方式,請參閱 bind-expr-impl.jisonbind-expression.js

允許清單函數

陣列

單一參數箭頭函數不能有括號,例如,請使用 x => x + 1,而不是 (x) => x + 1sort()splice() 會傳回修改後的副本,而不是就地運算。

concat:1、2、3

filter:字母少於三個的字詞

includes:"hello" 或 "world"

indexOf:"world"

join:所有字詞以破折號分隔

lastIndexOf:"amp-bind"

map:將每個數字加到前一個數字

reduce:將陣列中的所有數字加總

slice:傳回索引 1 和 3 的字詞

some:某些數字小於 2

sort:依字母順序排列字詞

splice:將 "amp-bind" 放在索引 2

<amp-state id="myArrayState">
  <script type="application/json">
    {
      "foo": [1, 2, 3],
      "bar": ["hello", "world", "bar", "baz"],
      "baz": "Hello world, welcome to amp-bind"
    }
  </script>
</amp-state>
<p [text]="'concat: ' + myArrayState.foo.concat(4)">concat: 1, 2, 3</p>
<p [text]="'filter: ' + myArrayState.bar.filter(word => word.length > 3)">
  filter: words with less than three letter
</p>
<p [text]="'includes: ' + myArrayState.bar.includes('hello' || 'world')">
  includes: "hello" or "world"
</p>
<p [text]="'indexOf: ' + myArrayState.bar.indexOf('world')">indexOf: "world"</p>
<p [text]="'join: ' + myArrayState.bar.join('-')">
  join: all words with a dash
</p>
<p [text]="'lastIndexOf: ' + myArrayState.baz.lastIndexOf('amp-bind')">
  lastIndexOf: "amp-bind"
</p>
<p [text]="'map: ' + myArrayState.foo.map((x, i) => x + i)">
  map: add each number to previous number
</p>
<p [text]="'reduce: ' + myArrayState.foo.reduce((x, i) => x + i)">
  reduce: add all numbers in array together
</p>
<p [text]="'slice: ' + myArrayState.bar.slice(1,3)">
  slice: return words at index 1 and 3
</p>
<p [text]="'some: ' + myArrayState.foo.some(x => x < 2)">
  some: some numbers are less than 2
</p>
<p [text]="'sort: ' + myArrayState.bar.sort()">
  sort: place words in alphabetical order
</p>
<p [text]="'splice: ' + myArrayState.bar.splice(2, 0, 'amp-bind')">
  splice: place "amp-bind" at index 2
</p>
<button on="tap:AMP.setState({})">Evaluate</button>
在 Playground 中開啟此程式碼片段

數字

toExponential:100 的 5 次方

toFixed:1.99 四捨五入並固定到小數點後第一位

toPrecision:1.234567 以字串形式傳回至第三位數字

toString:3.14 以字串形式傳回

<p [text]="'toExponential: ' + (100).toExponential(5)">
  toExponential: 100 to the exponent of 5
</p>
<p [text]="'toFixed: ' + (1.99).toFixed(1)">
  toFixed: 1.99 rounded and fixed to first decimal
</p>
<p [text]="'toPrecision: ' + (1.234567).toPrecision(3)">
  toPrecision: 1.234567 returned as a string to the third digit
</p>
<p [text]="'toString ' + (3.14).toString()">
  toString: 3.14 returned as a string
</p>
<button on="tap:AMP.setState({})">Evaluate</button>
在 Playground 中開啟此程式碼片段

字串

charAt:索引 6 的字元

charCodeAt:索引 6 字元的 UTF-16 程式碼單元

concat:合併 foo 和 bar

lastIndexOf:"w" 的索引

replace:將 "world" 取代為 "amp-bind"

slice:擷取前 5 個字元

split:在空格處分割字詞並以陣列形式傳回

toLowerCase:將所有字母設為小寫

toUpperCase:將所有字母設為大寫

<amp-state id="myStringState">
  <script type="application/json">
    {
      "foo": "Hello world",
      "bar": ", welcome to amp-bind"
    }
  </script>
</amp-state>
<p [text]="'charAt: ' + myStringState.foo.charAt(6)">
  charAt: The character at index 6
</p>
<p [text]="'charCodeAt: ' + myStringState.foo.charCodeAt(6)">
  charCodeAt: The UTF-16 code unit of the character at index 6
</p>
<p [text]="'concat: ' + myStringState.foo.concat(myState.bar)">
  concat: Combine foo and bar
</p>
<p [text]="'lastIndexOf: ' + myStringState.foo.lastIndexOf('w')">
  lastIndexOf: The index of "w"
</p>
<p [text]="'replace: ' + myStringState.foo.replace('world', 'amp-bind')">
  replace: Replace "world" with "amp-bind"
</p>
<p [text]="'slice: ' + myStringState.foo.slice(5)">
  slice: Extract the first 5 characters
</p>
<p [text]="'split: ' + myStringState.foo.split(' ')">
  split: Split words at space and return as array
</p>
<p [text]="'toLowerCase: ' + myStringState.foo.toLowerCase()">
  toLowerCase: Make all letters lower case
</p>
<p [text]="'toUpperCase: ' + myStringState.foo.toUpperCase()">
  toUpperCase: Make all letters upper case
</p>
<button on="tap:AMP.setState({})">Evaluate</button>
在 Playground 中開啟此程式碼片段

數學

靜態函數未命名空間,例如,請使用 abs(-1),而不是 Math.abs(-1)

abs:5 - 9 的絕對值

abs:將 1.01 無條件進位到下一個最大的整數

floor:將 1.99 無條件捨去到整數

max:傳回最大的數字

min:傳回最小的數字

pow:傳回 5 的 3 次方

random:傳回大於 0 且小於 1 的數字

round:將 1.51 四捨五入

sign:評估正數或負數

<p [text]="'abs: ' + abs(5 - 9)">abs: absolute number of 5 - 9</p>
<p [text]="'ceil: ' + ceil(1.01)">
  abs: round 1.01 up to the next largest whole number
</p>
<p [text]="'floor: ' + floor(1.99)">floor: round 1.99 down to a whole number</p>
<p [text]="'max: ' + max(100, 4, 98)">max: return largest number</p>
<p [text]="'min: ' + min(100, 4, 98)">min: return smalled number</p>
<p [text]="'pow: ' + pow(5, 3)">pow: return 5 to the power of 3</p>
<p [text]="'random: ' + random()">
  random: return a number greater than 0 and less than 1
</p>
<p [text]="'round: ' + round(1.51)">round: round 1.51</p>
<p [text]="'sign: ' + sign(-9)">sign: evaluate if positive or negative</p>
<button on="tap:AMP.setState({})">Evaluate</button>
在 Playground 中開啟此程式碼片段

物件

靜態函數未命名空間,例如,請使用 keys(Object),而不是 Object.abs(Object)

keys:myObjectState JSON 物件金鑰

values:myObjectState JSON 物件值

<amp-state id="myObjectState">
  <script type="application/json">
    {
      "hello": "world",
      "foo": "bar"
    }
  </script>
</amp-state>
<p [text]="'keys: ' + keys(myObjectState)">
  keys: myObjectState JSON object keys
</p>
<p [text]="'values: ' + values(myObjectState)">
  values: myObjectState JSON object values
</p>
<button on="tap:AMP.setState({})">Evaluate</button>
在 Playground 中開啟此程式碼片段

全域

encodeURI:編碼 URI 並忽略通訊協定前置字串

encodeURIComponent:編碼 URI

<p [text]="'encodeURI: ' + encodeURI('https://amp.dev.org.tw/😉')">
  encodeURI: Encode a URI and ignore protocol prefix
</p>
<p [text]="'encodeURIComponent: ' + encodeURIComponent('https://amp.dev.org.tw/😉')">
  encodeURIComponent: Encode a URI
</p>
<button on="tap:AMP.setState({})">Evaluate</button>
在 Playground 中開啟此程式碼片段

使用 amp-bind-macro 定義巨集

透過定義 amp-bind-macro,重複使用 amp-bind 運算式片段。amp-bind-macro 元素允許使用零或多個引數並參照目前狀態的運算式。像函數一樣叫用 amp-bind-macros,從文件中的任何位置參照 id 屬性值。

輸入半徑值

圓形的面積為 0

<amp-bind-macro
  id="circleArea"
  arguments="radius"
  expression="3.14 * radius * radius"
></amp-bind-macro>
<p>
  Input a radius value
</p>
<input
  type="number"
  min="0"
  max="100"
  value="0"
  on="input-throttled:AMP.setState({myCircle:{radius: event.value}})"
/>
<p>
  The circle has an area of
  <span [text]="circleArea(myCircle.radius)">0</span>.
</p>
在 Playground 中開啟此程式碼片段

巨集也可以呼叫在自身之前定義的其他巨集。巨集無法以遞迴方式呼叫自身。

繫結

繫結[property] 形式的特殊屬性,可將元素的屬性連結至運算式。如果要在 XML 中開發,請使用替代的XML 相容語法。

狀態變更時,會評估與該狀態相關聯的運算式。繫結狀態的元素屬性會使用新的運算式結果更新。

布林值運算式結果會切換布林值屬性。例如:<amp-video [controls]="expr"...>。當 expr 評估為 true 時,<amp-video> 元素具有 controls 屬性。當 expr 評估為 false 時,系統會移除 controls 屬性。

您的瀏覽器不支援 video 元素。

<amp-video
  [controls]="controls"
  width="640"
  height="360"
  layout="responsive"
  poster="/static/inline-examples/images/kitten-playing.png"
>
  <source
    src="/static/inline-examples/videos/kitten-playing.webm"
    type="video/webm"
  />
  <source
    src="/static/inline-examples/videos/kitten-playing.mp4"
    type="video/mp4"
  />
  <div fallback>
    <p>This browser does not support the video element.</p>
  </div>
</amp-video>
<button on="tap:AMP.setState({ controls: true })">
  Controls
</button>
<button on="tap:AMP.setState({ controls: false })">
  No Controls
</button>
在 Playground 中開啟此程式碼片段

React 和 XML 相容性

如果使用 React 或 XML 開發,請使用替代的 data-amp-bind-property 語法。屬性名稱中的 [] 字元在 XML 中是無效的,因此無法使用 [property] 語法。

property 欄位取代為您想要在 data-amp-bind-property 中定義的屬性名稱。

例如,[text]="myState.foo" 會變成 data-amp-bind-text="myState.foo"

繫結類型

amp-bind 支援五種元素狀態的資料繫結。

Node.textContent

使用 [text] 屬性繫結 Node.textContent。大多數文字元素都支援 [text] 屬性。

<p [text]="'Hello ' + myState.foo">Hello World</p>
<p></p>

CSS 類別

使用 [class] 屬性繫結元素的 class[class] 運算式必須產生以空格分隔的字串。也就是說,如果您要繫結多個類別,請在名稱之間使用空格。逗號或破折號會評估為類別名稱。

<head>
  <style amp-custom>
    .background-green {
      background: green;
    }
    .background-red {
      background: red;
    }
    .border-red {
      border-color: red;
      border-width: 5px;
      border-style: solid;
    }
  </style>
</head>
<body>
  <div class="background-red" [class]="myClass">Hello World</div>
  <!-- This button adds both classes -->
  <button on="tap:AMP.setState({ myClass: 'background-green border-red' })">
    Working: Change Class
  </button>
  <!-- String arrays also work -->
  <button
    on="tap:AMP.setState({ myClass: ['background-green', 'border-red'] })"
  >
    Working string array: Change Class
  </button>
  <!-- This expression evaluates to class="background-green,border-red" -->
  <button on="tap:AMP.setState({ myClass: 'background-green,border-red' })">
    Broken: Change Class
  </button>
</body>
在 Playground 中開啟此程式碼片段

hidden 屬性

使用 [hidden] 屬性隱藏和顯示元素。[hidden] 運算式應為布林值運算式。

您好!

<p [hidden]="hiddenState">Hello there!</p>
<button on="tap:AMP.setState({hiddenState: true})">Hide</button>
<button on="tap:AMP.setState({hiddenState: false})">Show</button>
在 Playground 中開啟此程式碼片段

AMP 元件的大小

使用 [width][height] 屬性變更 widthheight

<amp-img
  src="https://unsplash.it/400/200"
  width="200"
  [width]="myImageDimension.width"
  height="100"
  [height]="myImageDimension.height"
>
</amp-img>
<button
  on="tap:AMP.setState({
              myImageDimension: {
              width: 400,
              height: 200
              }
              })"
>
  Change size
</button>
在 Playground 中開啟此程式碼片段

無障礙狀態和屬性

用於動態更新輔助技術 (例如螢幕閱讀器) 可用的資訊。所有 [aria-*] 屬性皆可繫結。

AMP 元件特定屬性和 HTML 屬性

部分 AMP 元件和 HTML 元素具有特定的可繫結屬性。這些屬性如下所示。

AMP 元件特定屬性

<amp-carousel type=slides>

  • [slide] 變更目前顯示的投影片索引。

查看範例.

<amp-lightbox>

  • [open] 切換燈箱的顯示狀態。

使用 on="lightboxClose: AMP.setState(...)" 在燈箱關閉時更新變數。

<details>

  • [open]

請參閱對應的 details 屬性

<fieldset>

  • [disabled] 啟用或停用 fieldset。

<image>

  • [xlink:href]

請參閱對應的 image 屬性

<option>

  • [disabled]
  • [label]
  • [selected]
  • [value]

請參閱對應的 option 屬性

<optgroup>

  • [disabled]
  • [label]

請參閱對應的 optgroup 屬性

<section>

  • [data-expand] 變更 amp-accordionsection 的展開狀態。

不允許的繫結

基於安全性考量,不允許繫結至 innerHTML

所有屬性繫結都會針對不安全的值 (例如,javascript:) 進行清理。

偵錯

警告

在開發模式中,當繫結屬性的預設值與其對應運算式的初始結果不符時,amp-bind 會發出警告。這有助於防止因其他狀態變數變更而導致的非預期變化。例如

<!-- The element's default class value ('def') doesn't match the expression result for [class] ('abc'),
     so a warning will be issued in development mode. -->
<p [class]="'abc'" class="def"></p>

在開發模式中,當取消參照未定義的變數或屬性時,amp-bind 也會發出警告。這也有助於防止因 null 運算式結果而導致的非預期變化。例如

<amp-state id="myAmpState">
  <script type="application/json">
    {"foo": 123}
  </script>
</amp-state>

<!-- The amp-state#myAmpState does not have a `bar` variable, so a warning
     will be issued in development mode. -->
<p [text]="myAmpState.bar">Some placeholder text.</p>

錯誤

以下概述使用 amp-bind 時可能發生的錯誤類型。

類型 訊息 建議
無效的繫結 不允許繫結至 <P> 上的 [foo]. 僅使用允許清單中的繫結
語法錯誤 運算式編譯錯誤,發生在...。 檢查運算式是否有錯字。
未在允許清單中的函數 不支援 alert 函數。 僅使用允許清單中的函數
已清理的結果 "javascript:alert(1)" 不是 [href] 的有效結果。 避免使用遭禁止的 URL 通訊協定或會導致 AMP 驗證工具失敗的運算式。
CSP 違規 拒絕從 'blob:...' 建立 Worker,因為這違反了下列內容安全政策指令...。 default-src blob: 新增至您來源的內容安全政策。amp-bind 會將耗時的工作委派給專用 Web Worker,以確保良好的效能。

偵錯狀態

使用 AMP.printState() 將目前的狀態列印到主控台。如要讓此功能運作,您需要啟用開發模式

運算式文法

amp-bind 運算式的 BNF 類文法

expr:
    operation
  | invocation
  | member_access
  | '(' expr ')'
  | variable
  | literal
  ;

operation:
    '!' expr
  | '-' expr %prec UMINUS
  | '+' expr %prec UPLUS
  |  expr '+' expr
  | expr '-' expr
  | expr '*' expr
  | expr '/' expr
  | expr '%' expr
  | expr '&&' expr
  | expr '||' expr
  | expr '<=' expr
  | expr '<' expr
  | expr '>=' expr
  | expr '>' expr
  | expr '!=' expr
  | expr '==' expr
  | expr '?' expr ':' expr
  ;

invocation:
    NAME args
  | expr '.' NAME args
  | expr '.' NAME '(' arrow_function ')'
  | expr '.' NAME '(' arrow_function ',' expr ')'
  ;

arrow_function:
    '(' ')' '=>' expr
  | NAME '=>' expr
  | '(' params ')' '=>' expr
  ;

params:
    NAME ',' NAME
  | params ',' NAME
  ;

args:
    '(' ')'
  | '(' array ')'
  ;

member_access:
    expr member
  ;

member:
    '.' NAME
  | '[' expr ']'
  ;

variable:
    NAME
  ;

literal:
    primitive
  | object_literal
  | array_literal
  ;

primitive:
    STRING
  | NUMBER
  | TRUE
  | FALSE
  | NULL
  ;

array_literal:
    '[' ']'
  | '[' array ']'
  | '[' array ',' ']'
  ;

array:
    expr
  | array ',' expr
  ;

object_literal:
    '{' '}'
  | '{' object '}'
  | '{' object ',' '}'
  ;

object:
    key_value
  | object ',' key_value
  ;

key_value:
  key ':' expr
  ;

key:
    NAME
  | primitive
  | '[' expr ']'
  ;
需要更多協助嗎?

您已閱讀本文件十幾次,但它並未真正涵蓋您的所有問題?或許其他人也有相同的感受:在 Stack Overflow 上與他們交流。

前往 Stack Overflow
發現錯誤或缺少功能?

AMP 專案非常鼓勵您的參與和貢獻!我們希望您能成為我們開放原始碼社群的長期參與者,但我們也歡迎您針對您特別感興趣的問題提供一次性的貢獻。

前往 GitHub