ออกแบบอินเทอร์เฟซผู้ใช้

อินเทอร์เฟซผู้ใช้ของส่วนขยายควรมีจุดประสงค์และไม่ซับซ้อน UI ควรปรับแต่งหรือปรับปรุงประสบการณ์การท่องเว็บโดยไม่ทำให้เสียสมาธิ เช่นเดียวกับส่วนขยายเอง

คู่มือนี้จะอธิบายถึงฟีเจอร์อินเทอร์เฟซผู้ใช้ที่จำเป็นและที่ไม่บังคับ ใช้ข้อมูลนี้เพื่อทำความเข้าใจว่าควรใช้องค์ประกอบ UI ต่างๆ ภายในส่วนขยายอย่างไรและเมื่อใด

เปิดใช้งานส่วนขยายในทุกหน้า

ใช้ browser_action เมื่อฟีเจอร์ของส่วนขยายใช้งานได้ในสถานการณ์ส่วนใหญ่

ลงทะเบียนการดำเนินการของเบราว์เซอร์

ฟิลด์ "browser_action" ได้รับการลงทะเบียนในไฟล์ Manifest

{
  "name": "My Awesome browser_action Extension",
  ...
  "browser_action": {
    ...
  }
  ...
}

การประกาศ "browser_action" จะทำให้ไอคอนมีสีอยู่เสมอ ซึ่งบ่งบอกว่าผู้ใช้สามารถใช้ส่วนขยายนั้นได้

เพิ่มป้าย

ป้ายจะแสดงแบนเนอร์สีที่มีอักขระไม่เกิน 4 ตัวที่ด้านบนของไอคอนเบราว์เซอร์ ใช้ส่วนขยายที่ประกาศ "browser_action" ในไฟล์ Manifest เท่านั้น

ใช้ป้ายเพื่อระบุสถานะของส่วนขยาย ตัวอย่างกิจกรรมเกี่ยวกับน้ำดื่มจะแสดงป้ายพร้อมคำว่า "เปิด" เพื่อแสดงให้ผู้ใช้ทราบว่าตนตั้งปลุกสำเร็จและไม่แสดงอะไรเลยเมื่อส่วนขยายไม่มีการใช้งาน

เปิดป้าย

ปิดป้าย

กำหนดข้อความของป้ายโดยการเรียกใช้ chrome.browserAction.setBadgeText และสีแบนเนอร์โดยโทรไปที่ chrome.browserAction.setBadgeBackgroundColor

chrome.browserAction.setBadgeText({text: 'ON'});
chrome.browserAction.setBadgeBackgroundColor({color: '#4688F1'});

เปิดใช้งานส่วนขยายในหน้าเว็บที่เลือก

ใช้ page_action เมื่อฟีเจอร์ของส่วนขยายใช้งานได้ภายใต้สถานการณ์ที่กำหนดเท่านั้น

ประกาศการทำงานของหน้าเว็บ

ฟิลด์ "page_action" ได้รับการลงทะเบียนในไฟล์ Manifest

{
  "name": "My Awesome page_action Extension",
  ...
  "page_action": {
    ...
  }
  ...
}

การประกาศ "page_action" จะทำให้ไอคอนมีสีเฉพาะเวลาที่ส่วนขยายพร้อมใช้งานสำหรับผู้ใช้ มิเช่นนั้นส่วนขยายจะแสดงในรูปแบบสีเทา

ไอคอนการทำงานของหน้าเว็บที่ใช้งานอยู่

ไอคอนการทำงานของหน้าเว็บใช้งานไม่ได้

กำหนดกฎสำหรับการเปิดใช้ส่วนขยาย

กำหนดกฎสำหรับกรณีที่ส่วนขยายจะใช้งานได้โดยการเรียกใช้ chrome.declarativeContent ในส่วน Listener ของ runtime.onInstalled ในสคริปต์ในเบื้องหลัง ตัวอย่างส่วนขยายการดำเนินการของหน้าเว็บตาม URL จะกำหนดเงื่อนไขว่า URL ต้องมี "g" ส่วนขยายจะเรียก declarativeContent.ShowPageAction() หากเป็นไปตามเงื่อนไข

chrome.runtime.onInstalled.addListener(function() {
  // Replace all rules ...
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
    // With a new rule ...
    chrome.declarativeContent.onPageChanged.addRules([
      {
        // That fires when a page's URL contains a 'g' ...
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { urlContains: 'g' },
          })
        ],
        // And shows the extension's page action.
        actions: [ new chrome.declarativeContent.ShowPageAction() ]
      }
    ]);
  });
});

เปิดหรือปิดใช้งานส่วนขยาย

ส่วนขยายที่ใช้ "page_action" สามารถเปิดและปิดใช้แบบไดนามิกได้โดยเรียกใช้ pageAction.show และ pageAction.hide

ส่วนขยายตัวอย่าง Mappy จะสแกนหน้าเว็บเพื่อหาที่อยู่ และแสดงตำแหน่งบนแผนที่แบบคงที่ในป๊อปอัป เนื่องจากส่วนขยายขึ้นอยู่กับเนื้อหาของหน้า จึงไม่สามารถประกาศกฎเพื่อคาดการณ์ว่าหน้าใดจะมีความเกี่ยวข้อง แต่ถ้าพบที่อยู่ในหน้าเว็บ ที่อยู่จะเรียกใช้ pageAction.show เพื่อใส่สีให้ไอคอนและส่งสัญญาณว่าส่วนขยายนั้นใช้งานได้ในแท็บนั้น

chrome.runtime.onMessage.addListener(function(req, sender) {
  chrome.storage.local.set({'address': req.address})
  chrome.pageAction.show(sender.tab.id);
  chrome.pageAction.setTitle({tabId: sender.tab.id, title: req.address});
});

ระบุไอคอนส่วนขยาย

ส่วนขยายต้องมีไอคอนอย่างน้อย 1 ไอคอนจึงจะแสดงได้ แสดงไอคอนในรูปแบบ PNG เพื่อให้ได้ผลการค้นหาภาพที่ดีที่สุด แต่ก็ยอมรับทุกรูปแบบที่ WebKit รองรับ ซึ่งรวมถึง BMP, GIF, ICO และ JPEG

กำหนดไอคอนแถบเครื่องมือ

ไอคอนเฉพาะแถบเครื่องมือจะได้รับการบันทึกในช่อง "default_icon" ใต้ browser_action หรือ page_action ในไฟล์ Manifest เราขอแนะนำให้ใช้การรวมหลายขนาด เพื่อปรับขนาดให้พอดีกับพื้นที่ที่ลดลง 16 ระดับ แนะนำขนาด 16x16 และ 32x32 เป็นอย่างน้อย

{
  "name": "My Awesome page_action Extension",
  ...
  "page_action": {
    "default_icon": {
      "16": "extension_toolbar_icon16.png",
      "32": "extension_toolbar_icon32.png"
    }
  }
  ...
}

ไอคอนทั้งหมดควรเป็นรูปสี่เหลี่ยมจัตุรัส มิฉะนั้นอาจบิดเบี้ยว หากไม่ได้ให้ไอคอนมา Chrome จะเพิ่มไอคอนทั่วไปในแถบเครื่องมือ

สร้างและลงทะเบียนไอคอนเพิ่มเติม

ใส่ไอคอนเพิ่มเติมในขนาดต่อไปนี้สำหรับการใช้งานนอกแถบเครื่องมือ

ขนาดไอคอนการใช้ไอคอน
16x16ไอคอน Fav บนหน้าส่วนขยาย
32x32คอมพิวเตอร์ Windows มักต้องใช้ขนาดนี้ การใช้ตัวเลือกนี้จะป้องกันไม่ให้การบิดเบี้ยวของขนาดลดลงจากตัวเลือก 48x48
48x48จะแสดงในหน้าการจัดการส่วนขยาย
128x128แสดงเมื่อมีการติดตั้งและใน Chrome เว็บสโตร์

ไอคอนลงทะเบียนในไฟล์ Manifest ใต้ช่อง "icons"

{
  "name": "My Awesome Extension",
  ...
  "icons": {
    "16": "extension_icon16.png",
    "32": "extension_icon32.png",
    "48": "extension_icon48.png",
    "128": "extension_icon128.png"
  }
  ...
}

ฟีเจอร์ UI เพิ่มเติม

ป๊อปอัปคือไฟล์ HTML ที่แสดงในหน้าต่างพิเศษเมื่อผู้ใช้คลิกไอคอนแถบเครื่องมือ ป๊อปอัปทำงานคล้ายกับหน้าเว็บมาก โดยอาจมีลิงก์ไปยังสไตล์ชีตและแท็กสคริปต์ แต่ไม่อนุญาตให้ใช้ JavaScript ในหน้า

ป๊อปอัปตัวอย่างกิจกรรมการดื่มน้ำจะแสดงตัวเลือกตัวจับเวลาที่มีอยู่ ผู้ใช้ตั้งปลุกด้วยการคลิกปุ่มใดปุ่มหนึ่งที่มีให้

ภาพหน้าจอตัวอย่างแบบป๊อปอัป

<html>
  <head>
    <title>Water Popup</title>
  </head>
  <body>
      <img src='./stay_hydrated.png' id='hydrateImage'>
      <button id='sampleSecond' value='0.1'>Sample Second</button>
      <button id='15min' value='15'>15 Minutes</button>
      <button id='30min' value='30'>30 Minutes</button>
      <button id='cancelAlarm'>Cancel Alarm</button>
    <script src="popup.js"></script>
  </body>
</html>

คุณสามารถลงทะเบียนป๊อปอัปในไฟล์ Manifest ในส่วนการทำงานของเบราว์เซอร์หรือการทำงานของหน้าเว็บ

{
  "name": "Drink Water Event",
  ...
  "browser_action": {
    "default_popup": "popup.html"
  }
  ...
}

นอกจากนี้ คุณยังตั้งค่าป๊อปอัปแบบไดนามิกได้โดยเรียกใช้ browserAction.setPopup หรือ pageAction.setPopup

chrome.storage.local.get('signed_in', function(data) {
  if (data.signed_in) {
    chrome.browserAction.setPopup({popup: 'popup.html'});
  } else {
    chrome.browserAction.setPopup({popup: 'popup_sign_in.html'});
  }
});

เคล็ดลับเครื่องมือ

ใช้เคล็ดลับเครื่องมือเพื่อให้คำอธิบายหรือวิธีการสั้นๆ แก่ผู้ใช้เมื่อวางเมาส์เหนือไอคอนเบราว์เซอร์

ภาพหน้าจอของเคล็ดลับเครื่องมือตัวอย่าง

เคล็ดลับเครื่องมือจะบันทึกอยู่ในช่อง "default_title" browser_action หรือ page_action ในไฟล์ Manifest

{
"name": "Tab Flipper",
  ...
  "browser_action": {
    "default_title": "Press Ctrl(Win)/Command(Mac)+Shift+Right/Left to flip tabs"
  }
...
}

นอกจากนี้ คุณยังตั้งค่าหรืออัปเดตเคล็ดลับเครื่องมือได้โดยเรียกใช้ browserAction.setTitle และ pageAction.setTitle

chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.browserAction.setTitle({tabId: tab.id, title: "You are on tab:" + tab.id});
});

สตริงภาษาเฉพาะจะใช้กับการทำให้เป็นสากล สร้างไดเรกทอรีเพื่อเก็บรักษาข้อความเฉพาะภาษาในโฟลเดอร์ชื่อ _locales ดังนี้

  • _locales/en/messages.json
  • _locales/es/messages.json

จัดรูปแบบข้อความภายในmessages.jsonของแต่ละภาษา

{
  "__MSG_tooltip__": {
      "message": "Hello!",
      "description": "Tooltip Greeting."
  }
}
{
  "__MSG_tooltip__": {
      "message": "Hola!",
      "description": "Tooltip Greeting."
  }
}

ใส่ชื่อข้อความในช่องเคล็ดลับเครื่องมือแทนข้อความเพื่อเปิดใช้การแปล

{
"name": "Tab Flipper",
  ...
  "browser_action": {
    "default_title": "__MSG_tooltip__"
  }
...
}

แถบอเนกประสงค์

ผู้ใช้สามารถเรียกใช้ฟังก์ชันการทำงานของส่วนขยายผ่านแถบอเนกประสงค์ ใส่ฟิลด์ "omnibox" ในไฟล์ Manifest และกำหนดคีย์เวิร์ด ตัวอย่างส่วนขยายการค้นหาแท็บใหม่ของแถบอเนกประสงค์ ใช้ "nt" เป็นคีย์เวิร์ด

{
  "name": "Omnibox New Tab Search",\
  ...
  "omnibox": { "keyword" : "nt" },
  "default_icon": {
    "16": "newtab_search16.png",
    "32": "newtab_search32.png"
  }
  ...
}

เมื่อผู้ใช้พิมพ์ "nt" ในแถบอเนกประสงค์ ระบบจะเปิดใช้งานส่วนขยายดังกล่าว เพื่อส่งสัญญาณแจ้งเรื่องนี้ต่อผู้ใช้ ไอคอนจะปรับขนาดเป็นไอคอนขนาด 16x16 ที่มีให้และรวมไว้ในแถบอเนกประสงค์ข้างชื่อส่วนขยาย

ส่วนขยายแถบอเนกประสงค์ที่ใช้งานอยู่

ส่วนขยายจะคอยฟังเหตุการณ์ omnibox.onInputEntered หลังจากเริ่มทำงานแล้ว ส่วนขยายจะเปิดแท็บใหม่ที่มีการค้นหาของ Google สำหรับรายการของผู้ใช้

chrome.omnibox.onInputEntered.addListener(function(text) {
  // Encode user input for special characters , / ? : @ & = + $ #
  var newURL = 'https://www.google.com/search?q=' + encodeURIComponent(text);
  chrome.tabs.create({ url: newURL });
});

เมนูตามบริบท

เพิ่มตัวเลือกเมนูตามบริบทใหม่โดยการให้สิทธิ์ "contextMenus" ในไฟล์ Manifest

{
  "name": "Global Google Search",
  ...
  "permissions": [
    "contextMenus",
    "storage"
  ],
  "icons": {
    "16": "globalGoogle16.png",
    "48": "globalGoogle48.png",
    "128": "globalGoogle128.png"
  }
  ...
}

ไอคอน 16x16 จะแสดงข้างรายการเมนูใหม่

ไอคอนเมนูบริบท

สร้างเมนูตามบริบทด้วยการเรียกใช้ contextMenus.create ในสคริปต์พื้นหลัง ซึ่งควรดำเนินการดังกล่าวในส่วนเหตุการณ์ Listener runtime.onInstalled

chrome.runtime.onInstalled.addListener(function() {
  for (let key of Object.keys(kLocales)) {
    chrome.contextMenus.create({
      id: key,
      title: kLocales[key],
      type: 'normal',
      contexts: ['selection'],
    });
  }
});
const kLocales = {
  'com.au': 'Australia',
  'com.br': 'Brazil',
  'ca': 'Canada',
  'cn': 'China',
  'fr': 'France',
  'it': 'Italy',
  'co.in': 'India',
  'co.jp': 'Japan',
  'com.ms': 'Mexico',
  'ru': 'Russia',
  'co.za': 'South Africa',
  'co.uk': 'United Kingdom'
};

ตัวอย่างเมนูตามบริบทของ Google Search ทั่วโลกจะสร้างตัวเลือกหลายรายการจากรายการใน locales.js เมื่อส่วนขยายมีเมนูตามบริบทมากกว่า 1 เมนู Google Chrome จะยุบรายการเป็นเมนูหลักเมนูเดียวโดยอัตโนมัติ

เมนูตามบริบทหลายรายการจะยุบ

คำสั่ง

ส่วนขยายจะกำหนดคำสั่งที่เฉพาะเจาะจงและเชื่อมโยงกับชุดคีย์ได้ ลงทะเบียนคำสั่งอย่างน้อย 1 รายการในไฟล์ Manifest ใต้ช่อง "commands"

{
  "name": "Tab Flipper",
  ...
  "commands": {
    "flip-tabs-forward": {
      "suggested_key": {
        "default": "Ctrl+Shift+Right",
        "mac": "Command+Shift+Right"
      },
      "description": "Flip tabs forward"
    },
    "flip-tabs-backwards": {
      "suggested_key": {
        "default": "Ctrl+Shift+Left",
        "mac": "Command+Shift+Left"
      },
      "description": "Flip tabs backwards"
    }
  }
  ...
}

คุณสามารถใช้คำสั่งต่างๆ เพื่อสร้างทางลัดใหม่ของเบราว์เซอร์หรือทางเลือกอื่น ส่วนขยายตัวอย่าง Tab Flipper จะตรวจจับเหตุการณ์ commands.onCommand ในสคริปต์พื้นหลังและกำหนดฟังก์ชันสำหรับชุดค่าผสมที่บันทึกไว้แต่ละรายการ

chrome.commands.onCommand.addListener(function(command) {
  chrome.tabs.query({currentWindow: true}, function(tabs) {
    // Sort tabs according to their index in the window.
    tabs.sort((a, b) => { return a.index < b.index; });
    let activeIndex = tabs.findIndex((tab) => { return tab.active; });
    let lastTab = tabs.length - 1;
    let newIndex = -1;
    if (command === 'flip-tabs-forward')
      newIndex = activeIndex === 0 ? lastTab : activeIndex - 1;
    else  // 'flip-tabs-backwards'
      newIndex = activeIndex === lastTab ? 0 : activeIndex + 1;
    chrome.tabs.update(tabs[newIndex].id, {active: true, highlighted: true});
  });
});

คําสั่งยังสร้างการเชื่อมโยงคีย์ที่ทำงานกับส่วนขยายเป็นพิเศษได้ด้วย ตัวอย่าง สวัสดีส่วนขยาย จะมีคำสั่งเพื่อเปิดป๊อปอัป

{
  "name": "Hello Extensions",
  "description" : "Base Level Extension",
  "version": "1.0",
  "browser_action": {
    "default_popup": "hello.html",
    "default_icon": "hello_extensions.png"
  },
  "manifest_version": 2,
  "commands": {
    "_execute_browser_action": {
      "suggested_key": {
        "default": "Ctrl+Shift+F",
        "mac": "MacCtrl+Shift+F"
      },
      "description": "Opens hello.html"
    }
  }
}

เนื่องจากส่วนขยายกำหนด browser_action จึงสามารถระบุ "execute_browser_action" ในคำสั่งเพื่อเปิดไฟล์ป๊อปอัปโดยไม่มีสคริปต์พื้นหลัง หากใช้ page_action คุณจะใช้ "execute_page_action" แทนได้ ทั้งคำสั่งของเบราว์เซอร์และส่วนขยายสามารถใช้ ในส่วนขยายเดียวกันได้

ลบล้างหน้าเว็บ

ส่วนขยายจะลบล้างและแทนที่หน้าเว็บประวัติการเข้าชม แท็บใหม่ หรือบุ๊กมาร์กด้วยไฟล์ HTML ที่กำหนดเองได้ อาจมีตรรกะและสไตล์พิเศษเหมือนกับป๊อปอัป แต่ไม่อนุญาตให้มี JavaScript ในหน้า ส่วนขยายหนึ่งรายการจะถูกจำกัดให้ลบล้างหน้าเว็บที่เป็นไปได้เพียง 1 หน้าจาก 3 หน้าเท่านั้น

ลงทะเบียนหน้าการลบล้างในไฟล์ Manifest ในช่อง "chrome_url_overrides"

{
  "name": "Awesome Override Extension",
  ...

  "chrome_url_overrides" : {
    "newtab": "override_page.html"
  },
  ...
}

ควรแทนที่ช่อง "newtab" ด้วย "bookmarks" หรือ "history" เมื่อลบล้างหน้าเหล่านั้น

<html>
  <head>
  <title>New Tab</title>
  </head>
  <body>
    <h1>Hello World</h1>
  <script src="logic.js"></script>
  </body>
</html>