Materi ke 6 Coding Viewporter.js: Mempermudah Manajemen Viewport Mobile
Bagikan
Viewporter.js: Mempermudah Manajemen Viewport Mobile
Dalam dunia pengembangan web, khususnya yang berfokus pada aplikasi mobile, salah satu tantangan terbesar adalah mengelola viewport agar sesuai dengan berbagai ukuran layar dan perangkat. Viewporter.js adalah sebuah proyek open-source yang diciptakan oleh Zynga untuk mempermudah manajemen viewport mobile. Tujuan utama dari Viewporter.js adalah untuk menyederhanakan proses pengaturan dimensi layar yang tepat dan menghilangkan kesulitan dalam menangani tag meta viewport secara manual.
Apa itu Viewporter.js?
Viewporter.js adalah sebuah library JavaScript yang memungkinkan pengembang untuk dengan mudah mengatur viewport pada aplikasi web mobile. Dengan menggunakan Viewporter.js, pengembang dapat memastikan bahwa aplikasi mereka dapat ditampilkan dengan benar di berbagai perangkat tanpa perlu khawatir tentang masalah ukuran layar atau orientasi perangkat.
Bagaimana Cara Kerja Viewporter.js?
Viewporter.js bekerja dengan cara pertama mencoba menggulirkan URL atau debug bars untuk memaksimalkan jendela yang terlihat, kemudian mengurangi tinggi chrome/UI yang tersisa dari jendela, secara efektif menghilangkan scrollbar yang tidak diinginkan. Selain itu, Viewporter.js juga melacak perubahan orientasi, sehingga pengguna selalu mendapatkan pengalaman tampilan yang maksimal.
Keuntungan Menggunakan Viewporter.js
Menggunakan Viewporter.js memberikan beberapa keuntungan otomatis bagi pengembang, di antaranya:
– Viewport yang dimaksimalkan dengan menggulirkan UI yang tidak diperlukan.
– Layout yang mudah dibuat.
– API yang hampir tanpa konfigurasi.
– Memudahkan pengembangan aplikasi web mobile yang responsif dan kompatibel dengan berbagai perangkat.
Viewporter.js hampir tidak memerlukan konfigurasi. Hanya ada satu konstanta untuk memeriksa apakah Viewporter.js sedang berjalan, metode kenyamanan untuk mendeteksi orientasi landscape, dan fungsi callback ready yang cerdas. Selain itu, ada beberapa event yang mungkin ingin digunakan oleh pengembang.
Bagaimana Cara Menggunakan Viewporter.js?
Untuk menggunakan Viewporter.js, pengembang hanya perlu menambahkan tag meta viewport berikut ke dalam head halaman web mereka:
“`html
<meta name=”viewport” content=”initial-scale=1.0,maximum-scale=1.0″ />
“`
Kemudian, bungkus elemen HTML dengan div wrapper viewporter:
“`html
<body>
<div id=”viewporter”>
<!– Konten aplikasi di sini –>
</div>
</body>
“`
Itu saja yang perlu dilakukan. Pengembang dapat merujuk ke halaman demo Viewporter.js jika ada sesuatu yang tidak berfungsi seperti yang diharapkan.
Viewporter.js telah menjadi solusi yang elegan dan efisien untuk masalah yang sering dihadapi oleh pengembang aplikasi web mobile. Dengan memanfaatkan Viewporter.js, pengembang dapat menghemat waktu dan usaha dalam mengelola viewport, memungkinkan mereka untuk fokus pada pengembangan fitur dan fungsi aplikasi yang lebih penting.
/*
* Viewporter v2.0
* http://github.com/zynga/viewporter
*
* Copyright 2011, Zynga Inc.
* Licensed under the MIT License.
* https://raw.github.com/zynga/viewporter/master/MIT-LICENSE.txt
*/
var viewporter;
(function() {
var _viewporter;
// initialize viewporter object
viewporter = {
// options
forceDetection: false,
disableLegacyAndroid: true,
// constants
ACTIVE: (function() {
// it's best not do to anything to very weak devices running Android 2.x
if(viewporter.disableLegacyAndroid && (/android 2/i).test(navigator.userAgent)) {
return false;
}
// iPad's don't allow you to scroll away the UI of the browser
if((/ipad/i).test(navigator.userAgent)) {
return false;
}
// WebOS has no touch events, but definitely the need for viewport normalization
if((/webos/i).test(navigator.userAgent)) {
return true;
}
// touch enabled devices
if('ontouchstart' in window) {
return true;
}
return false;
}),
READY: false,
// methods
isLandscape: function() {
return window.orientation === 90 || window.orientation === -90;
},
ready: function(callback) {
window.addEventListener('viewportready', callback, false);
},
change: function(callback) {
window.addEventListener('viewportchange', callback, false);
},
refresh: function(){
if (_viewporter) {
_viewporter.prepareVisualViewport();
}
},
preventPageScroll: function() {
// prevent page scroll if `preventPageScroll` option was set to `true`
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
// reset page scroll if `preventPageScroll` option was set to `true`
// this is used after showing the address bar on iOS
document.body.addEventListener("touchstart", function() {
_viewporter.prepareVisualViewport();
}, false);
}
};
// execute the ACTIVE flag
viewporter.ACTIVE = viewporter.ACTIVE();
// if we are on Desktop, no need to go further
if (!viewporter.ACTIVE) {
return;
}
// create private constructor with prototype..just looks cooler
var _Viewporter = function() {
var that = this;
// Scroll away the header, but not in Chrome
this.IS_ANDROID = /Android/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
var _onReady = function() {
// scroll the shit away and fix the viewport!
that.prepareVisualViewport();
// listen for orientation change
var cachedOrientation = window.orientation;
window.addEventListener('orientationchange', function() {
if(window.orientation !== cachedOrientation) {
that.prepareVisualViewport();
cachedOrientation = window.orientation;
}
}, false);
};
// listen for document ready if not already loaded
// then try to prepare the visual viewport and start firing custom events
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
_onReady();
}, false);
} else {
_onReady();
}
};
_Viewporter.prototype = {
getProfile: function() {
if(viewporter.forceDetection) {
return null;
}
for(var searchTerm in viewporter.profiles) {
if(new RegExp(searchTerm).test(navigator.userAgent)) {
return viewporter.profiles[searchTerm];
}
}
return null;
},
postProcess: function() {
// let everyone know we're finally ready
viewporter.READY = true;
this.triggerWindowEvent(!this._firstUpdateExecuted ? 'viewportready' : 'viewportchange');
this._firstUpdateExecuted = true;
},
prepareVisualViewport: function() {
var that = this;
// if we're running in webapp mode (iOS), there's nothing to scroll away
if(navigator.standalone) {
return this.postProcess();
}
// maximize the document element's height to be able to scroll away the url bar
document.documentElement.style.minHeight = '5000px';
var startHeight = window.innerHeight;
var deviceProfile = this.getProfile();
var orientation = viewporter.isLandscape() ? 'landscape' : 'portrait';
// try scrolling immediately
window.scrollTo(0, that.IS_ANDROID ? 1 : 0); // Android needs to scroll by at least 1px
// start the checker loop
var iterations = 40;
var check = window.setInterval(function() {
// retry scrolling
window.scrollTo(0, that.IS_ANDROID ? 1 : 0); // Android needs to scroll by at least 1px
function androidProfileCheck() {
return deviceProfile ? window.innerHeight === deviceProfile[orientation] : false;
}
function iosInnerHeightCheck() {
return window.innerHeight > startHeight;
}
iterations--;
// check iterations first to make sure we never get stuck
if ( (that.IS_ANDROID ? androidProfileCheck() : iosInnerHeightCheck()) || iterations < 0) {
// set minimum height of content to new window height
document.documentElement.style.minHeight = window.innerHeight + 'px';
// set the right height for the body wrapper to allow bottom positioned elements
document.getElementById('viewporter').style.position = 'relative';
document.getElementById('viewporter').style.height = window.innerHeight + 'px';
clearInterval(check);
// fire events, get ready
that.postProcess();
}
}, 10);
},
triggerWindowEvent: function(name) {
var event = document.createEvent("Event");
event.initEvent(name, false, false);
window.dispatchEvent(event);
}
};
// initialize
_viewporter = new _Viewporter();
})();
viewporter.profiles = {
// Motorola Xoom
'MZ601': {
portrait: 696,
landscape: 1176
},
// Samsung Galaxy S, S2 and Nexus S
'GT-I9000|GT-I9100|Nexus S': {
portrait: 508,
landscape: 295
},
// Samsung Galaxy Pad
'GT-P1000': {
portrait: 657,
landscape: 400
},
// HTC Desire & HTC Desire HD
'Desire_A8181|DesireHD_A9191': {
portrait: 533,
landscape: 320
}
};

