2014年8月2日土曜日

Chromeアプリで長押しコンテキストメニュー



Chromeアプリ開発でコンテキストメニュー(もどき)を簡単に実装する方法です。
通常の chrome.contextMenus は実際にプログラマティカルにメニュー内容を変更しようとすると background.js とcontent script との通信が発生するので結構面倒です。でも、これから紹介するやり方ならそんな面倒な手間もなく結構楽に実現できます。
ついでなので左マウスボタン長押しでコンテキストメニューを表示するような実装にしてみましょう。

manifest.json
{
  "name": "Long press contextmenus",
  "short_name": "Long press contextmenus",
  "description": "Simple long mousedown contextmenus example",
  "version": "0.1",
  "manifest_version": 2,
  "app": {
    "background": {
      "scripts": ["background.js"]
    }
  },
  "icons": {
    "128": "128.png"
  }
}

background.js
chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('main.html', {
    'bounds': {
      'width': 400,
      'height': 500
    }
  });
});

main.html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="main.css">
  </head>
  <body>
    <div>Long press contextmenus example</div>
    <div id="div" style="border:1px solid gray;padding:10px;background-color:#dadada">press long here</div>
    <div id="result"></div>
    <div id="menus">
      <select size="3">
        <option value="GOOGL">Google</option>
        <option value="AMZN">Amazon</option>
        <option value="AAPL">Apple</option>
      </select>
    </div>
  </body>
  <script src="jquery-2.1.0.min.js"></script>
  <script src="app.js"></script>
</html>
※今回はjQueryを使っています。

main.css
#menus {
  display: none;
  position: fixed;
  vertical-align: top;
  overflow: hidden;
  border: solid gray 1px;
  box-shadow: 2px 2px 4px;
}
#menus select {
  padding: 10px;
  border: 0px solid gray;
  margin:-5px -20px -5px -5px;
  font-size: 1.4em;
}
#menus select option.hovered {
  background-color: navy;
  color: white;
}
#menus select option.selected {
  background-color: black;
  color: white;
}

app.js
var pressTimer;

/* shows the contextmenus by long mousedown */
$("#div").mouseup(function() {
  clearTimeout(pressTimer)
  // Clear timeout
  return false;
}).mousedown(function(e) {
  // Set timeout
  pressTimer = window.setTimeout(function() {
    decorateSelectedItem();
    // get & set 'size' attr of select tag.
    var size = $("#menus option").length;
    $("#menus select").attr("size", size);
    // show menus
    $("#menus")
      .show()
      .offset({
        top: e.clientY,
        left: e.clientX
      });
  }, 1000)
  return false;
})

$("#menus option").hover(function(e) {
  // inverse backgroundColor of the hovered option.
  $(this).addClass("hovered");
}).mouseleave(function(e) {
  $(this).removeClass("hovered");
}).click(function(e) {
  $("#result").text($(this).val());
  $("#menus").hide();
});

function decorateSelectedItem() {
  $("#menus option:selected").removeAttr("selected");
  var symbol = $("#result").text();
  $("#menus option").each(function(i){
    if ($(this).val() == symbol) {
      $(this).addClass("selected");
    } else {
      $(this).removeClass("selected");
    }
  })
}

$("#div").mouseup(... のくだりが左マウスボタン長押し処理です。
コンテキストメニューを表示する具体的な処理は pressTimer = window.setTimeout(function() { の中に記述しています。

関連エントリ
コンテキストメニューなChrome拡張機能の作り方

0 件のコメント:

コメントを投稿