No Description

orientation.js 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. Copyright 2013-2015 ASIAL CORPORATION
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. import MicroEvent from './microevent';
  14. var create = function create() {
  15. /**
  16. * @object ons.orientation
  17. * @category util
  18. * @description
  19. * [en]Utility methods for orientation detection.[/en]
  20. * [ja]画面のオリエンテーション検知のためのユーティリティメソッドを収めているオブジェクトです。[/ja]
  21. */
  22. var obj = {
  23. /**
  24. * @event change
  25. * @description
  26. * [en]Fired when the device orientation changes.[/en]
  27. * [ja]デバイスのオリエンテーションが変化した際に発火します。[/ja]
  28. * @param {Object} event
  29. * [en]Event object.[/en]
  30. * [ja]イベントオブジェクトです。[/ja]
  31. * @param {Boolean} event.isPortrait
  32. * [en]Will be true if the current orientation is portrait mode.[/en]
  33. * [ja]現在のオリエンテーションがportraitの場合にtrueを返します。[/ja]
  34. */
  35. /**
  36. * @method on
  37. * @signature on(eventName, listener)
  38. * @description
  39. * [en]Add an event listener.[/en]
  40. * [ja]イベントリスナーを追加します。[/ja]
  41. * @param {String} eventName
  42. * [en]Name of the event.[/en]
  43. * [ja]イベント名を指定します。[/ja]
  44. * @param {Function} listener
  45. * [en]Function to execute when the event is triggered.[/en]
  46. * [ja]このイベントが発火された際に呼び出される関数オブジェクトを指定します。[/ja]
  47. */
  48. /**
  49. * @method once
  50. * @signature once(eventName, listener)
  51. * @description
  52. * [en]Add an event listener that's only triggered once.[/en]
  53. * [ja]一度だけ呼び出されるイベントリスナーを追加します。[/ja]
  54. * @param {String} eventName
  55. * [en]Name of the event.[/en]
  56. * [ja]イベント名を指定します。[/ja]
  57. * @param {Function} listener
  58. * [en]Function to execute when the event is triggered.[/en]
  59. * [ja]イベントが発火した際に呼び出される関数オブジェクトを指定します。[/ja]
  60. */
  61. /**
  62. * @method off
  63. * @signature off(eventName, [listener])
  64. * @description
  65. * [en]Remove an event listener. If the listener is not specified all listeners for the event type will be removed.[/en]
  66. * [ja]イベントリスナーを削除します。もしイベントリスナーを指定しなかった場合には、そのイベントに紐づく全てのイベントリスナーが削除されます。[/ja]
  67. * @param {String} eventName
  68. * [en]Name of the event.[/en]
  69. * [ja]イベント名を指定します。[/ja]
  70. * @param {Function} listener
  71. * [en]Function to execute when the event is triggered.[/en]
  72. * [ja]削除するイベントリスナーを指定します。[/ja]
  73. */
  74. // actual implementation to detect if whether current screen is portrait or not
  75. _isPortrait: false,
  76. /**
  77. * @method isPortrait
  78. * @signature isPortrait()
  79. * @return {Boolean}
  80. * [en]Will be true if the current orientation is portrait mode.[/en]
  81. * [ja]オリエンテーションがportraitモードの場合にtrueになります。[/ja]
  82. * @description
  83. * [en]Returns whether the current screen orientation is portrait or not.[/en]
  84. * [ja]オリエンテーションがportraitモードかどうかを返します。[/ja]
  85. */
  86. isPortrait: function isPortrait() {
  87. return this._isPortrait();
  88. },
  89. /**
  90. * @method isLandscape
  91. * @signature isLandscape()
  92. * @return {Boolean}
  93. * [en]Will be true if the current orientation is landscape mode.[/en]
  94. * [ja]オリエンテーションがlandscapeモードの場合にtrueになります。[/ja]
  95. * @description
  96. * [en]Returns whether the current screen orientation is landscape or not.[/en]
  97. * [ja]オリエンテーションがlandscapeモードかどうかを返します。[/ja]
  98. */
  99. isLandscape: function isLandscape() {
  100. return !this.isPortrait();
  101. },
  102. _init: function _init() {
  103. document.addEventListener('DOMContentLoaded', this._onDOMContentLoaded.bind(this), false);
  104. if ('orientation' in window) {
  105. window.addEventListener('orientationchange', this._onOrientationChange.bind(this), false);
  106. } else {
  107. window.addEventListener('resize', this._onResize.bind(this), false);
  108. }
  109. this._isPortrait = function () {
  110. return window.innerHeight > window.innerWidth;
  111. };
  112. return this;
  113. },
  114. _onDOMContentLoaded: function _onDOMContentLoaded() {
  115. this._installIsPortraitImplementation();
  116. this.emit('change', { isPortrait: this.isPortrait() });
  117. },
  118. _installIsPortraitImplementation: function _installIsPortraitImplementation() {
  119. var isPortrait = window.innerWidth < window.innerHeight;
  120. if (!('orientation' in window)) {
  121. this._isPortrait = function () {
  122. return window.innerHeight > window.innerWidth;
  123. };
  124. } else if (window.orientation % 180 === 0) {
  125. this._isPortrait = function () {
  126. return Math.abs(window.orientation % 180) === 0 ? isPortrait : !isPortrait;
  127. };
  128. } else {
  129. this._isPortrait = function () {
  130. return Math.abs(window.orientation % 180) === 90 ? isPortrait : !isPortrait;
  131. };
  132. }
  133. },
  134. _onOrientationChange: function _onOrientationChange() {
  135. var _this = this;
  136. var isPortrait = this._isPortrait();
  137. // Wait for the dimensions to change because
  138. // of Android inconsistency.
  139. var nIter = 0;
  140. var interval = setInterval(function () {
  141. nIter++;
  142. var w = window.innerWidth;
  143. var h = window.innerHeight;
  144. if (isPortrait && w <= h || !isPortrait && w >= h) {
  145. _this.emit('change', { isPortrait: isPortrait });
  146. clearInterval(interval);
  147. } else if (nIter === 50) {
  148. _this.emit('change', { isPortrait: isPortrait });
  149. clearInterval(interval);
  150. }
  151. }, 20);
  152. },
  153. // Run on not mobile browser.
  154. _onResize: function _onResize() {
  155. this.emit('change', { isPortrait: this.isPortrait() });
  156. }
  157. };
  158. MicroEvent.mixin(obj);
  159. return obj;
  160. };
  161. export default create()._init();