Sunday, March 31, 2013

Plugin JavaScript Kotak Dialog

Screenshoot of JavaScript dialog box plugin.

Plugin kotak dialog ini pada dasarnya hanyalah pengembangan sederhana dari konsep draggable element yang pernah Saya tuliskan sebelumnya. Kotak dialog ini hanya menggunakan JavaScript mentah, jadi tentu saja akan memiliki beberapa keterbatasan, diantaranya adalah:

  1. Tidak ada fitur resizable.
  2. Tidak ada efek animasi.
  3. Tidak bisa membuka beberapa kotak dialog sekaligus, hanya satu kotak dialog dengan isi dan ukuran yang berubah-ubah.

Untuk lebih jelasnya bisa dilihat di halaman demo:

Lihat Demo

Memasang Plugin

Untuk memasang plugin kotak dialog, Anda perlu menambahkan file CSS ini di atas kode </head>:

<link rel="stylesheet" href="../dialog-box.min.css"/>

Kemudian tambahkan juga file JavaScript ini di atas </body>:

<script src="../dialog-box.min.js"></script>

Aktivasi

Konsep dasar aktivasi ada dua, yaitu membuka kotak dialog dan menutup kotak dialog. Untuk membuka kotak dialog berdasarkan aksi klik pada tombol, jalankan fungsi setDialog dengan parameter open. Sedangkan untuk menutup kotak dialog, gunakan parameter close:

<a href='javascript:setDialog("open");'>Buka kotak dialog</a>
<a href='javascript:setDialog("close");'>Tutup kotak dialog</a>

Lihat Demo

Daftar Konfigurasi Lengkap

Setelah Anda mengerti mengenai bagaimana caranya menampilkan dan menyembunyikan kotak dialog, selanjutnya Anda perlu mengetahui cara menyisipkan konten dan juga merekayasa tombol-tombol kotak dialog. Yang mana semua pengaturan itu akan dilakukan pada parameter ke dua, berupa objek seperti ini:

<a href='javascript:setDialog("open", { ... });'>Buka kotak dialog</a>
Opsi Keterangan
title Digunakan untuk menentukan judul kotak dialog.
content Digunakan untuk menentukan konten kotak dialog.
width Digunakan untuk menentukan lebar kotak dialog dalam piksel.
height Digunakan untuk menentukan tinggi kotak dialog dalam piksel.
top Digunakan untuk menentukan jarak atas kotak dialog terhadap layar.
left Digunakan untuk menentukan jarak kiri kotak dialog terhadap layar.
specialClass Digunakan untuk menambahkan kelas CSS khusus pada kotak dialog (untuk keperluan modifikasi penampilan).
fixed Jika bernilai true, posisi kotak dialog akan melayang dan tidak akan terbawa gulungan layar. Jika bernilai false, posisi kotak dialog bisa terbawa gulungan layar.
overlay Pilihan untuk menampilkan atau menyembunyikan tabir kotak dialog.
buttons Adalah deret objek yang nantinya akan berubah menjadi daftar tombol baru (akan Saya jelaskan nanti).

Konfigurasi secara keseluruhan:

setDialog("open", {
    title: 'Judul kotak dialog',
    content: 'Isi kotak dialog',
    width: 300,
    height: 150,
    top: false,
    left: false,
    specialClass: "",
    fixed: true,
    overlay: false,
    buttons: {}
});

Contoh-Contoh Dasar

Kotak dialog dengan judul dan konten berupa kode HTML:

<a href='javascript:setDialog("open", {title: "Judul Dialog", content: "Konten dialog dan &lt;strong&gt;sedikit kode HTML&lt;/strong&gt;"});'>Buka</a>

Lihat Demo

Menyisipkan elemen <iframe>:

<a href='javascript:setDialog("open", {title: "Judul Dialog", content: "&lt;iframe src=&quot;URL-IFRAME.html&quot;&gt;&lt;/iframe&gt;"});'>Buka</a>

Lihat Demo

Catatan Penting: Mohon perhatikan mengenai penulisan tanda petik pada pengeksekusian fungsi secara langsung. Jika tanda petik yang digunakan pada atribut HTML adalah petik ganda, gunakan petik tunggal pada pengaturan fungsi setDialog, sebaliknya, jika tanda petik yang digunakan pada atribut HTML adalah petik tunggal, gunakan petik ganda pada pengaturan fungsi setDialog:

<a href="javascript:setDialog('open');">
        ^                     ^    ^  ^
        A                     B    B  A

<a href='javascript:setDialog("open");'>
        ^                     ^    ^  ^
        B                     A    A  B

Mengingat konten kotak dialog bisa berukuran sangat panjang, dan juga untuk mengatasi masalah penulisan tanda petik yang sangat rawan kesalahan seperti yang Saya jelaskan di atas, sebenarnya akan lebih baik jika eksekusi fungsi setDialog() dilakukan di luar elemen tersebut dengan cara menghubungkannya melalui ID atau kelas elemen HTML seperti ini:

<a id="dialog-link-1" href="#">Buka</a>
<script>
document.getElementById('dialog-link-1').onclick = function() {
    setDialog("open", {
        title: 'Judul Dialog',
        content: 'Konten dialog super panjaaaaaaaaaaaaaaaannnnggggggg...!!!',
        width: 600,
        height: 300
    });
    return false;
};
</script>

Pertama-tama nyatakan kode HTML untuk tombol pemicu kotak dialog dengan ID yang spesifik, setelah itu eksekusi fungsi setDialog dengan cara mengakses elemen melalui document.getElementById()

Lihat Demo

Anda juga bisa menyisipkan konten dari elemen lain:

<div id="foo" style="display:none;">
    <h2>Lorem Ipsum Text</h2>
    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit,
    sed diam <strong>nonummy</strong> nibh euismod
    magna aliquam erat volutpat. Ut wisi enim ad minim veniam,
    quis nostrud exerci tation ullamcorper suscipit lobortis
    nisl ut aliquip ex ea commodo consequat.
    Duis autem vel eum iriure dolor in hendrerit in vulputate
    velit esse molestie consequat, vel illum dolore eu feugiat
    nulla facilisis at vero eros et accumsan et iusto odio
    dignissim qui blandit praesent luptatum zzril delenit
    augue duis dolore te feugait nulla facilisi.</p>
</div>
<a id="dialog-link-2" href="#">Buka</a>
<script>
document.getElementById('dialog-link-2').onclick = function() {
    setDialog("open", {
        title: 'Judul Dialog',
        content: document.getElementById('foo').innerHTML,
        width: 600,
        height: 300
    });
    return false;
};
</script>

Lihat Demo

Rekayasa Tombol

Masing-masing tombol dapat dibuat melalui konfigurasi buttons dengan nilai berupa objek:

setDialog("open", {
    title: 'Judul Kotak Dialog',
    content: 'Konten kotak dialog.',
    buttons: {
        "Yes": function() {
            alert("Tombol YES ditekan!");
        },
        "No": function() {
            alert("Tombol NO ditekan!");
        }
    }
});

Setiap key dari buttons akan mewakili nama/label tombol, dan fungsi yang mengikutinya akan tereksekusi ketika tombol tersebut ditekan:

Lihat Demo


Kode Sumber

  1. dialog-box.css
  2. dialog-box.js
  3. dialog-box.min.css
  4. dialog-box.min.js

Labels: ,

Wednesday, March 27, 2013

Tentang Tooltip Deskripsi pada Formulir HTML

Gambaran Tooltip pada Formulir HTML

Memaksimalkan kerja selektor adjacent sibling sangat bermanfaat untuk menciptakan komunikasi yang lebih hidup pada saat proses pengisian formulir untuk pengunjung/anggota. Idenya adalah, seorang calon anggota mencoba untuk mengisi formulir. Dan saat kursor teks aktif di dalam elemen formulir tersebut, maka akan muncul pesan singkat di sebelahnya yang menjelaskan tentang apa saja yang harus calon anggota lakukan terhadap formulir yang sedang aktif tersebut.

Ide di atas bisa kita realisasikan hanya dengan cara seperti ini:

HTML

<input type="text">
<label>Mohon ketik setiap awalan dengan huruf kapital</label>

CSS

/* Menyembunyikan label-label formulir */
label {visibility:hidden}

/* Menampilkan label formulir saat elemen input terfokus */
input:focus + label {visibility:visible}

Yang kemudian akan menghasilkan komunikasi antarmuka seperti ini:

Lihat Demo

Melakukan beberapa pembaharuan pada tampilan elemen <label> untuk membuatnya tampak sebagai tooltip serta menambahkan efek transisi untuk memperlembut proses tampilnya deskripsi/pesan formulir, maka akan membuat komunikasi antarmuka menjadi semakin tegas tanpa harus meminta pengunjung yang sedang mengisi formulir tersebut pergi menuju ke halaman khusus mengenai panduan cara mengisi formulir. Dengan cara ini, pengunjung/calon anggota akan dipandu pada saat yang sama ketika mereka sedang mengisi formulir:

HTML

<div class="form-item">
    <input type="text">
    <label>Descriptions...</label>
</div>

CSS

/* Form item wrapper */
.form-item {
  margin:1em 0 0;
  position:relative;
}

/* Form item title */
.form-item strong {
  display:block;
  margin:0 0 5px;
}

/* Form items */
.form-item input,
.form-item textarea {
  display:block;
  border:1px solid #ccc;
  padding:4px;
  margin:0 0;
  width:250px;
  font:inherit;
  line-height:normal;
  color:inherit;
  -webkit-box-shadow:inset 0 1px 3px -1px rgba(0,0,0,.2);
  -moz-box-shadow:inset 0 1px 3px -1px rgba(0,0,0,.2);
  box-shadow:inset 0 1px 3px -1px rgba(0,0,0,.2);
}

/* Tooltip */
.form-item label {
  display:block;
  position:absolute;
  bottom:100%;
  left:150px;
  margin-bottom:2em;
  font-size:11px;
  font-weight:bold;
  color:white;
  white-space:nowrap;
  line-height:normal;
  padding:.6em 1em;
  background-color:black;
  -webkit-border-radius:3px;
  -moz-border-radius:3px;
  border-radius:3px;
  visibility:hidden;
  opacity:0;
  /* Transition effect */
  -webkit-transition:all .2s ease-out;
  -moz-transition:all .2s ease-out;
  -ms-transition:all .2s ease-out;
  -o-transition:all .2s ease-out;
  transition:all .2s ease-out;
}

/* Tooltip arrow */
.form-item label:after {
  content:"";
  display:block;
  width:0;
  height:0;
  border:5px solid transparent;
  position:absolute;
  top:100%;
  left:2em;
  border-top-color:black;
}

.form-item input:focus,
.form-item textarea:focus {border-color:#aaa}

/* Show tooltip when the form is being focused */
.form-item input:focus + label,
.form-item textarea:focus + label {
  visibility:visible;
  opacity:1;
  margin-bottom:-.5em;
}

Lihat Demo

Labels: ,

Saturday, March 23, 2013

Print/Mencetak Sebagian Halaman Saja dengan JavaScript

Gambar untuk dialog pencetakan pada Google Chrome
Mencetak sebagian halaman dengan JavaScript

Berbeda dengan dasar window.print() yang akan mencetak keseluruhan halaman, fungsi ini akan mencetak halaman pada bagian-bagian tertentu saja. Cara kerjanya adalah fungsi ini akan mencetak duplikat konten area di dalam iframe pencetakan.

Dua buah elemen, yaitu <textarea> dan <iframe> dibuat untuk keperluan ini. Area teks digunakan untuk menyimpan kode CSS pencetakan, sedangkan iframe digunakan untuk menampung salinan bagian halaman yang ingin dicetak. Saat salinan bagian halaman tersebut sudah masuk ke dalam iframe yang kita sembunyikan wujudnya, hal yang perlu kita lakukan selanjutnya adalah mencetak konten iframe tersebut, bukan halaman yang sedang aktif:

<textarea id="printing-css" style="display:none;">.no-print{display:none}</textarea>
<iframe id="printing-frame" name="print_frame" src="about:blank" style="display:none;"></iframe>
<script>
//<![CDATA[
function printDiv(elementId) {
    var a = document.getElementById('printing-css').value;
    var b = document.getElementById(elementId).innerHTML;
    window.frames["print_frame"].document.title = document.title;
    window.frames["print_frame"].document.body.innerHTML = '<style>' + a + '</style>' + b;
    window.frames["print_frame"].window.focus();
    window.frames["print_frame"].window.print();
}
//]]>
</script>

Aktivasi bisa dilakukan dengan cara memicu fungsi printDiv(elementId) pada tautan atau tombol, dimana elementId adalah ID dari area khusus yang ingin dicetak:

<a class="no-print" href="javascript:printDiv('area-1');">Print</a>

...

<div id="area-1">Teks ini akan tercetak di kertas...</div>
<div id="area-2">Tapi tidak untuk teks ini.</div>

Lihat Demo

Kode CSS pencetakan yang digunakan Saya sarankan adalah kode CSS yang pernah Saya tuliskan di sini, untuk memastikan agar tampilan halaman yang dicetak tertata dengan rapi. Atau kosongkan saja textarea tersebut dan biarkan User Agent Stylesheet pada masing-masing peramban menangani tampilan elemen yang ada.

Alternatif lain, Anda juga bisa menggunakan CSS eksternal jika Anda merasa bahwa textarea tanpa makna di atas hanya akan mengganggu kebersihan kode sumber web Anda:

<iframe id="printing-frame" name="print_frame" src="about:blank" style="display:none;"></iframe>
<script>
//<![CDATA[
function printDiv(elementId) {
    var a = "/path/to/printing-css.css";
    var b = document.getElementById(elementId).innerHTML;
    window.frames["print_frame"].document.title = document.title;
    window.frames["print_frame"].document.body.innerHTML = '<link rel="stylesheet" href="' + a + '">' + b;
    window.frames["print_frame"].window.focus();
    window.frames["print_frame"].window.print();
}
//]]>
</script>

Hasilnya akan terlihat jelas pada peramban Google Chrome yang notabene memiliki komunikasi pencetakan halaman yang berbeda dengan peramban lainnya.

Labels: , , ,

CSS3 Facebook Chatbox

HTML

.chat-box {
  font:normal normal 11px/1.4 Tahoma,Verdana,Sans-Serif;
  color:#333;
  width:200px; /* Chatbox width */
  border:1px solid #344150;
  border-bottom:none;
  background-color:white;
  position:fixed;
  right:10px;
  bottom:0;
  z-index:9999;
  -webkit-box-shadow:1px 1px 5px rgba(0,0,0,.2);
  -moz-box-shadow:1px 1px 5px rgba(0,0,0,.2);
  box-shadow:1px 1px 5px rgba(0,0,0,.2);
}

.chat-box > input[type="checkbox"] {
  display:block;
  margin:0 0;
  padding:0 0;
  position:absolute;
  top:0;
  right:0;
  left:0;
  width:100%;
  height:26px;
  z-index:4;
  cursor:pointer;
  opacity:0;
  filter:alpha(opacity=0);
}

.chat-box > label {
  display:block;
  height:24px;
  line-height:24px;
  background-color:#344150;
  color:white;
  font-weight:bold;
  padding:0 1em 1px;
}

.chat-box > label:before {content:attr(data-collapsed)}

.chat-box .chat-box-content {
  /* padding:10px; */
  display:none;
}

/* hover state */
.chat-box > input[type="checkbox"]:hover + label {background-color:#404D5A}

/* checked state */
.chat-box > input[type="checkbox"]:checked + label {background-color:#212A35}
.chat-box > input[type="checkbox"]:checked + label:before {content:attr(data-expanded)}
.chat-box > input[type="checkbox"]:checked ~ .chat-box-content {display:block}

HTML

<div class="chat-box">
    <input type="checkbox">
    <label data-expanded="Close Chatbox" data-collapsed="Open Chatbox"></label>
    <div class="chat-box-content">

        <!-- Kode buku tamu dsb... -->

    </div>
</div>

Lihat Demo

Labels: , ,

Wednesday, March 20, 2013

Toggle Side Navigation

Image of toggle side navigation example. See the navicon symbol!

HTML

<div id="outer-wrapper">

    <section id="nav">
        <a href="#nav" id="toggle-nav-btn" title="Show Navigation">&equiv;</a>
        <div class="inner">
            <ul class="menu">
                <li><a href="#">Home</a></li>
                <li><a href="#">About</a></li>
                <li><a href="#">Archive</a></li>
                <li><a href="#">Contact</a></li>
            </ul>
            ...
            ...
        </div>
    </section>

    <section id="main">
        Artikel di sini...
    </section>

</div>

CSS

/* Outer wrapper */
#outer-wrapper {
  background-color:black;
  overflow:hidden;
}

/* Left sidebar */
#nav {
  float:left;
  width:2.8em;
  color:#999;
  position:relative;
}

#nav .inner {
  padding:1em;
  display:none;
}

.menu,
.menu li {
  margin:0 0;
  padding:0 0;
  list-style:none;
}

.menu {margin:2em -1em 1em}

.menu a {
  display:block;
  font-weight:bold;
  color:white;
  text-decoration:none;
  height:2.4em;
  line-height:2.4em;
  padding:0 1em;
}

.menu a:hover {background-color:#222}

/* Right sidebar */
#main {
  background-color:white;
  margin-left:2.8em; /* Same with the `#nav` width */
  padding:1em 2em;
}

/* Toggle navigation button */
#toggle-nav-btn {
  text-decoration:none;
  font-size:200%;
  line-height:100%;
  color:#666;
  display:block;
  position:absolute;
  top:.2em;
  right:.4em;
}

#toggle-nav-btn:hover {color:#888}

/* When the `.menu-is-visible` class applied */
.menu-is-visible #nav {width:200px}
.menu-is-visible #nav .inner {display:block}
.menu-is-visible #main {margin-left:200px} /* Same with the `.menu-is-visible #nav` width */
.menu-is-visible #toggle-nav-btn {color:#aaa}

JavaScript

JavaScript ini digunakan untuk menambahkan dan melepaskan kelas .menu-is-visible pada elemen <body> secara bergantian:

(function() {

    var page = document.body,
        btn = document.getElementById('toggle-nav-btn');

    btn.onclick = function() {

        // Toggle the `.menu-is-visible` class to the <body> tag based on `#toggle-btn-nav` click event
        page.className = (/(^| )menu-is-visible( |$)/.test(page.className)) ?
            page.className.replace(/menu-is-visible/,"") :
                page.className + " menu-is-visible";

        // Toggle the toggle navigation title too...
        this.title = (this.title == "Show Navigation") ?
            "Hide Navigation" :
                "Show Navigation";

        return false;

    };

})();

Lihat Demo

Alternatif Lain

Kita juga bisa menggunakan plugin jQuery Toggle Sidebar untuk menampilkan dan menyembunyikan sidebar, dimana menu navigasi berada di dalam sidebar tersebut. Tapi dalam kasus ini Saya tidak menyarankannya, mengingat menggunakan JavaScript mentah saja masih bisa:

$('#nav').toggleSidebar({
    expand: "#main",
    defaultHidden: true
});

Labels: , , ,

Tuesday, March 19, 2013

Plugin Feed Rotator untuk Blogger

Image of Blogger Feed Rotator plugin demo

Plugin ini pada dasarnya merupakan perpaduan antara Basic jQuery Image Rotator dengan yang kemudian Saya jadikan sebagai semacam slideshow dengan konten yang akan diperbaharui secara otomatis berdasarkan posting yang sudah terbit. Saya memutuskan untuk membuat ini karena ada beberapa orang yang menanyakan melalui email mengenai bagaimana cara memadukan plugin Image Rotator dengan JSON Blogger.

Plugin jQuery Image Rotator ini juga sudah dimodifikasi hampir secara keseluruhan, khusus untuk diaplikasikan pada widget ini. Beberapa hal yang Saya tambahkan diantaranya adalah navigasi, efek animasi kontainer dan dukungan fungsi callback yang dapat dijalankan pada sesi-sesi tertentu.

Lihat Demo

Implementasi Dasar

Berikut ini adalah contoh implementasi paling mendasar yang bisa Anda lakukan untuk mengaktifkan plugin:

<link rel="stylesheet" href="//blogger-json-experiment.googlecode.com/svn/resources/blogger-feed-rotator-plugin/default-style.min.css"/>
<div id="slider-rotator" class="slider-rotator loading"></div><script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><script src="//blogger-json-experiment.googlecode.com/svn/resources/blogger-feed-rotator-plugin/blogger-feed-rotator.min.js"></script>
<script>
makeSlider({
    url: "//nama_blog.blogspot.com" // URL blog Anda
});
</script>

Susun file CSS dan plugin Blogger Feed Rotator sesuai dengan urutan yang Saya perlihatkan di atas. Tambahkan juga elemen HTML yang berfungsi untuk menampilkan slideshow sebelum plugin. Setelah itu aktifkan fungsi makeSlider() dengan parameter berupa objek tunggal url yang diisi dengan URL blog Anda. Salin dan tempelkan di dalam formulir elemen halaman HTML/JavaScript. Dengan ini maka Anda sudah bisa menampilkan sebuah slideshow sederhana seperti yang terlihat pada halaman demo di atas.

Daftar Opsi Konfigurasi Dasar

Konfigurasi dasar Saya batasi pada opsi-opsi yang berhubungan dengan pengaturan posting:

{
    url: "//www.dte.web.id", // Your blog URL
    numPost: 5, // Number of posts to display
    newTabLink: false, // `true` to automatically open link in new window tab
    labelName: null, // Show posts in specific label. Specify name of the post label, or `null` to show all posts
    showDetail: true, // `false` to hide the blog post title & description
    summaryLength: 60, // Length of post summary
    titleLength: "auto", // Length of the post title. "auto" by default, or specify number to crop the post title characters and truncate it with `...`
    showThumb: true, // `false` to hide the post thumbnails
    thumbWidth: 250, // Width of post thumbnail in pixels
    squareThumb: true, // Thumbnail mode: Square mode or use the scaled thumbnail with original width and height ratio
    noThumb: "images/grey.png", // Fallback thumbnail for no picture posts
    showNav: true, // `true` to show both next/prev navigation and navigation number, "next/prev" to show next/prev navigation only, "number" to show navigation number only, `false` to hide the navigation
    navText: {
        prev: "&lt;", // Label of the previous navigation
        next: "&gt;" // Label of the next navigation
    },
    containerId: "slider-rotator" // HTML element ID that is used to display the slideshow/rotator
}
Opsi Keterangan
url Isi dengan URL halaman muka blog Anda
numPost Digunakan untuk menentukan jumlah posting yang akan ditampilkan
newTabLink Ubah nilainya menjadi true untuk membuat tautan-tautan di dalam widget ini terbuka di jendela/tab baru saat diklik
labelName Digunakan untuk menampilkan daftar posting dengan label/kategori tertentu. Nilai null berarti menampilkan semua posting terbaru. Ganti nilainya menjadi nama label untuk menampilkan posting dengan label tertentu. Misalnya labelName:"Foto" untuk menampilkan semua posting yang memiliki label Foto - Contoh
showDetail Ubah nilainya menjadi false untuk menyembunyikan judul dan ringkasan posting. Berguna untuk membuat slideshow foto/gambar tanpa tulisan - Contoh
summaryLength Digunakan untuk membatasi panjang ringkasan posting. Akhir pemotongan ringkasan posting akan digantikan dengan simbol “…”
titleLength Digunakan untuk membatasi panjang judul posting. Secara normal bernilai "auto". Ubah nilainya dengan angka tertentu untuk memotong panjang judul jika Anda merasa judul posting yang tampil terlalu panjang. Akhir pemotongan judul posting akan digantikan dengan simbol “…”
showThumb Ubah nilainya menjadi false untuk menyembunyikan gambar posting. Berguna untuk membuat slideshow teks - Contoh
thumbWidth Digunakan untuk menentukan lebar thumbnail posting dan juga sekaligus menentukan lebar slideshow
squareThumb Opsi untuk memilih mode thumbnail. true untuk menampilkan gambar dengan resolusi /sN-c, false untuk menampilkan gambar dengan resolusi /sN
noThumb Isi dengan URL gambar. Gambar ini akan digunakan sebagai cadangan jika posting yang tampil tidak memiliki gambar
showNav Opsi untuk menampilkan atau menyembunyikan navigasi slideshow. Ubah nilainya menjadi false untuk menyembunyikan navigasi. "number" untuk menampilkan navigasi angka saja. "next/prev" untuk menampilkan navigasi next/prev saja. true untuk menampilkan keduanya
navText Opsi untuk menentukan label navigasi Next dan Previous
containerId Digunakan untuk menentukan di mana slideshow akan ditampilkan. Isi dengan ID elemen HTML. Dan jangan lupa untuk menyertakan elemen HTML tersebut sebelum eksekusi plugin.

Pengaturan Animasi

Pengaturan animasi Saya batasi pada opsi-opsi yang berhubungan dengan animasi plugin:

{
    interval: 6000, // Slideshow interval
    speed: 1000, // Slideshow animation speed
    hoverPause: true, // `false` to make the slideshow/rotator keep running on mouse-over
    crossFade: false, // `true` if you want to make the slide change effect occurs simultaneously between disappearance and appearance
    autoHeight: false, // Animate the rotator to adjust the height of the displayed item
    autoSlide: true // `false` to run the slideshow manually (with navigation)
}
Opsi Keterangan
interval Digunakan untuk menentukan rentang waktu perpindahan setiap item slide dalam satuan milidetik
speed Digunakan untuk menentukan kecepatan animasi dalam satuan milidetik
hoverPause Jika bernilai true maka slideshow akan berhenti bergerak saat pointer mouse berada di atasnya
crossFade Digunakan untuk menentukan apakah efek penghilangan dan pemunculan slide dilakukan secara bergantian atau bersamaan dalam waktu yang sama tanpa ada jeda
autoHeight Jika bernilai true, maka tinggi slideshow akan menyesuaikan diri berdasarkan tinggi item slide yang tampil dengan efek animasi - Contoh
autoSlide Ubah nilainya menjadi false untuk membuat slideshow berjalan secara manual melalui aksi klik navigasi

Konfigurasi Lanjutan

Bagian ini Saya khususkan untuk menjelaskan fungsi-fungsi callback dan implementasi lanjutan, khususnya dalam hal modifikasi:

{
    onInit: function() {}, // Callback function that will be executed when slideshow is starting
    onHide: function(index) {}, // Callback function that will be executed when slideshow is start hiding the slide item
    onShow: function(index) {} // Callback function that will be executed after the slideshow showing the slide item
}

onInit

Fungsi ini akan dijalankan pada saat pertama kali slideshow terbentuk. Saat slideshow tampil, maka fungsi ini akan langsung dieksekusi. Contoh penerapan:

makeSlider({
    url: "//nama_blog.blogspot.com",
    onInit: function() {
        alert('Slideshow ready!'); 
    }
});

Kode di atas akan menampilkan pesan “Slideshow ready!” segera setelah slideshow tampil.

onHide

Fungsi ini akan dijalankan setiap kali item slide mulai menghilang. Saat item slide menghilang, maka fungsi ini akan tereksekusi. Contoh penerapan:

makeSlider({
    url: "//nama_blog.blogspot.com",
    onHide: function() {
        alert('Mengganti slide...'); 
    }
});

Kode di atas akan menampilkan pesan “Mengganti slide...” setiap kali slide mulai berganti.

onShow

Fungsi ini akan dijalankan setiap kali item slide tampil. Saat item slide tampil, maka fungsi ini akan tereksekusi. Contoh penerapan:

makeSlider({
    url: "//nama_blog.blogspot.com",
    onShow: function(index) {
        alert('Slide ke ' + index + ' berhasil tampil.'); 
    }
});

Kode di atas akan menampilkan pesan “Slide ke {nomor urut slide yang tampil} berhasil tampil.” setiap kali slide ditampilkan.

Parameter `index`

Parameter index hanya berlaku untuk onHide dan onShow. Parameter ini akan menampilkan indeks slide yang aktif:

makeSlider({
    url: "//nama_blog.blogspot.com",
    onInit: function() {
        console.log('Slideshow dimulai...');
    },
    onHide: function(index) {
        console.log('Menyembunyikan slide ke ' + index); 
    },
    onShow: function(index) {
        console.log('Menampilkan slide ke ' + index);
    }
});

Beberapa Contoh Modifikasi Dasar

Mengubah Tampilan

Dengan mengubah ukuran lebar pada gambar dan slideshow, ukuran tinggi pada slideshow dan mengubah tampilan deskripsi/detail posting sebagai caption, maka Anda bisa semakin memperkuat status plugin ini sebagai “slideshow”:

CSS

<link rel="stylesheet" href="//blogger-json-experiment.googlecode.com/svn/resources/blogger-feed-rotator-plugin/default-style.min.css"/>
<style>

/* Custom CSS... */

.slider-rotator {
  width:600px;
  height:240px;
  padding:0 0;
  background-color:white;
  font:italic normal 12px/1.4 Georgia,Serif;
  color:white;
  border:1px solid black;
}

.slider-rotator .slider-item {
  background-color:white;
  height:240px; /* Same with `.slider-rotator` height */
  padding:0 0;
}

.slider-rotator h4 {margin-top:0}
.slider-rotator p {margin:2px 0 0}

/* Slider details as caption */
.slider-rotator .detail-wrapper {
  position:absolute;
  top:auto;
  right:0;
  bottom:0;
  left:0;
  background-color:black;
  background-color:rgba(0,0,0,.9);
  padding:.5em 1em;
  z-index:4;
}

</style>

JavaScript

makeSlider({
    url: "//nama_blog.blogspot.com", // Your blog URL
    thumbWidth: 600 // Thumbnail width in pixels (same with slideshow width)
});

Lihat Demo

Memanfaatkan Fungsi Callback untuk Menganimasikan Caption

Dengan memanfaatkan parameter index pada onHide dan onShow, Anda bisa memberikan efek animasi pada caption slide yang aktif setiap kali slide berganti:

makeSlider({
    url: "//nama_blog.blogspot.com", // Your blog URL
    thumbWidth: 600, // Thumbnail width in pixels (same with slideshow width)
    containerId: "slider-rotator",
    // Hide all captions on initiation...
    onInit: function() {
        $('#' + this.containerId).find('.detail-wrapper').hide();
    },
    // Hide the caption with `.slideUp()` effect when the slide item hides
    onHide: function() {
        $('#' + this.containerId).find('.detail-wrapper').slideUp();
    },
    // Show the caption with `.slideDown()` effect when the slide item appears
    onShow: function(index) {
        $('#' + this.containerId).children().eq(index).find('.detail-wrapper').slideDown();
    }
});

Lihat Demo

Menampilkan Beberapa Slideshow Sekaligus

Karena eksekusi plugin ini dilakukan di luar, maka ini memungkinkan Anda untuk menampilkan beberapa slideshow sekaligus dalam satu halaman. Pertama-tama buatlah beberapa elemen HTML yang dibutuhkan untuk memuat slideshow:

<div id="container-1" class="slider-rotator loading"></div>
<div id="container-2" class="slider-rotator loading"></div>
<div id="container-3" class="slider-rotator loading"></div>

Kemudian jalankan fungsi makeSlider() sebanyak jumlah kontainer yang dibuat. Tentukan juga konfigurasi containerId yang berbeda-beda berdasarkan ID kontainer:

makeSlider({
    url: "//nama_blog-1.blogspot.com",
    containerId: "container-1"
});
makeSlider({
    url: "//nama_blog-2.blogspot.com",
    containerId: "container-2"
});
makeSlider({
    url: "//nama_blog-3.blogspot.com",
    containerId: "container-3"
});

Lihat Demo

Mengatur Plugin dan Melihat Demo Secara Langsung

Saya sudah menyertakan halaman konfigurasi plugin yang bisa Anda gunakan untuk melakukan pengaturan dan melihat hasilnya secara langsung di sini:

Kunjungi Halaman

Daftar Contoh

  1. Demo 1: Basic
  2. Demo 2: Show Posts under Category “Widget”
  3. Demo 3: About Thumbnails
  4. Demo 4: Thumbnail Only
  5. Demo 5: Text Only
  6. Demo 6: Multiple Feed Loading
  7. Demo 7: Casual Slideshow
  8. Demo 8: Example Callback Function to Animate the Slideshow Caption (1)
  9. Demo 9: Example Callback Function to Animate the Slideshow Caption (2)

Labels: , , ,

Sunday, March 10, 2013

Mendapatkan Tinggi dan Lebar Layar Monitor

Versi jQuery

var x = $(window).width(),
    y = $(window).height();

// Tampilkan lebar dan tinggi layar dalam kotak pesan
alert('Lebar layar: ' + x + '; Tinggi layar: ' + y);

Versi JavaScript Murni

var w = window,
    d = document,
    e = d.documentElement,
    g = d.body,
    x = w.innerWidth || e.clientWidth || g.clientWidth, // x = Lebar layar
    y = w.innerHeight || e.clientHeight || g.clientHeight; // y = Tinggi layar

// Tampilkan lebar dan tinggi layar dalam kotak pesan
alert('Lebar layar: ' + x + '; Tinggi layar: ' + y);

Labels: , ,

Kapan Harus Menggunakan px, % dan em?

Meskipun, kebanyakan dari kita masih bertahan dengan satuan piksel saat menentukan ukuran-ukuran elemen HTML, namun di sini Saya ingin mencoba untuk membuka mata Anda lebih lebar lagi agar Anda bisa mengerti betul mengapa satuan-satuan relatif seperti em dan % dalam banyak kasus lebih efisien dan logis dibandingkan dengan satuan piksel (px) yang selama ini paling sering dipakai karena ukuran mereka yang sangat akurat.

Ketika % Menjadi Lebih Baik

Persentase merupakan satuan yang tidak dihitung berdasarkan ukuran elemen itu sendiri, melainkan dihitung berdasarkan perbandingan ukuran elemen tersebut terhadap ukuran induknya.

Satuan % Dalam Sistem Grid

Dimulai dari kasus sistem grid, atau katakanlah kolom-kolom web Anda. Di sini kita memiliki tiga elemen HTML untuk merancang sebuah susunan/layout situs sederhana. Terdiri dari pembungkus utama dan dua buah kolom. Salah satu kolom merupakan area artikel, dan satunya lagi merupakan area sidebar:

<div class="col-group">
    <div class="left-col">Artikel...</div>
    <div class="right-col">Sidebar...</div>
</div>

Seseorang dengan sudut pandang piksel akan membuat layout dua kolom dengan pengukuran seperti ini:

.col-group {
  width:600px;
  overflow:hidden;
}

.left-col {
  width:400px;
  float:left;
}

.right-col {
  width:200px; /* 600 - 400 */
  float:right;
}

CSS di atas akan menghasilkan layout dua kolom dengan ukuran pembungkus utama selebar 600 piksel. Kolom kiri selebar 400 piksel dan kolom kanan selebar 200 piksel. Ukuran layout yang sangat tepat dan tidak mungkin bisa diragukan akurasinya. Tapi sayangnya, layout piksel seperti ini hanya akan menimbulkan kendala saat Anda mencoba untuk memodifikasi atau memperbaharui lebar layout tersebut di masa depan. Misalnya, suatu saat Anda ingin mengubah lebar layout menjadi 1000 piksel seperti ini:

.col-group {
  width:1000px;
  overflow:hidden;
}

Pada saat yang sama Anda tentu harus memperbaharui lebar kolom kiri dan kolom kanan:

.left-col {
  width:600px; /* 400 + ((1000 - 600) / 2) */
  float:left;
}

.right-col {
  width:400px; /* 1000 - 600 */
  float:right;
}

Tidak praktis, tidak hemat waktu dan membutuhkan perhitungan baru setiap kali ukuran layout diperbaharui. Jika susunan halaman hanya terdiri dari dua buah kolom sederhana seperti contoh di atas mungkin tidak begitu menjadi masalah, tapi bagaimana jika jumlah kolomnya banyak?

Bandingkan dengan saat Anda mengatur lebar kolom menggunakan satuan persentase:

.col-group {
  width:600px; /* lebar pembungkus utama */
  overflow:hidden;
}

.left-col {
  width:66.6%; /* (400/600) x 100 */
  float:left;
}

.right-col {
  width:33.4%; /* 100 - 66.6 */
  float:right;
}

Meskipun beberapa orang (termasuk Saya) masih merasa sedikit kesulitan ketika mencoba mengubah sudut pandang satuan piksel ke persen, tapi hasil akhirnya nanti Saya jamin akan lebih stabil dan lebih mudah diperbaiki/diperbaharui (maintainable) saat kita menggunakan satuan persen. Karena yang menjadi standar ukuran di sini hanya ada satu, yaitu pada elemen terluar saja. Sedangkan ukuran lebar anak-anak kolom di dalamnya yang menggunakan satuan persen akan secara otomatis mengikuti ukuran berdasarkan perbandingan lebar induknya, betapapun kita mengubah lebar pembungkus luar kolom-kolom tersebut.

Demonstrasi di halaman ini mungkin bisa sedikit menjelaskan bagaimana persen dan piksel bekerja pada sistem grid:

Lihat Demo

Satuan % Dalam Elemen Heading/Judul Artikel

Elemen-elemen heading h1, h2, h3, h4, h5 dan h6 akan lebih baik jika diatur menggunakan satuan persen. Walaupun beberapa ada juga yang menggunakan satuan em. Sebenarnya itu tidak masalah, karena baik em maupun % keduanya sama-sama merupakan satuan relatif. Yang penting cobalah untuk menghilangkan kebiasaan menggunakan satuan piksel dalam menentukan ukuran elemen heading. Ini berhubungan dengan pengaplikasian media queries yang lebih efisien dan juga kemudahan di dalam pengaturan ukuran judul berdasarkan ukuran teks utama. Sebuah contoh sederhana, di sini Anda mencoba menentukan ukuran elemen-elemen heading dengan satuan piksel:

body {
  font-size:13px;
  font-family:Arial,Sans-Serif;
}

h1 {font-size:28px}
h2 {font-size:25px}
h3 {font-size:22px}
h4 {font-size:19px}
h5 {font-size:16px}
h6 {font-size:13px}

Mengapa satuan piksel buruk dalam hal ini? Itu karena satuan piksel hanya akan membuat Anda melakukan ekstra perubahan ukuran teks dalam media queries perangkat seluler. Dimulai dari ukuran teks dasar yang dideklarasikan di dalam selektor body sampai ke ukuran teks pada elemen heading level 6:

@media (max-width:360px) {
  body {font-size:11px}
  h1 {font-size:26px}
  h2 {font-size:23px}
  h3 {font-size:20px}
  h4 {font-size:17px}
  h5 {font-size:14px}
  h6 {font-size:11px}
}

Pola penyusutan teks akan berbeda jika Anda menggunakan satuan persentase saat menentukan ukuran judul artikel. Saat menggunakan satuan persentase, maka ukuran judul-judul artikel akan menyesuaikan diri berdasarkan perbandingan ukuran teks dasar saat itu, yaitu 13px (Sebagai contoh: 200% dari 13 piksel adalah 26 piksel):

body {
  font-size:13px;
  font-family:Arial,Sans-Serif;
}

h1 {font-size:200%}
h2 {font-size:180%}
h3 {font-size:160%}
h4 {font-size:140%}
h5 {font-size:120%}
h6 {font-size:100%}

Karena Anda menggunakan satuan persentase pada semua judul artikel, maka saat Anda memperkecil ukuran teks pada perangkat seluler, yang perlu Anda lakukan hanya memperkecil ukuran teks dasarnya saja, yaitu pada elemen <body>. Ukuran teks pada semua judul artikel nantinya akan menyusut menyesuaikan diri berdasarkan persentase terhadap ukuran teks utama yang sudah mengecil:

@media (max-width:360px) {
  body {font-size:11px}
}

Menggunakan satuan persentase untuk elemen heading juga akan mempermudah Anda di dalam memperbaharui ukuran teks artikel. Anda tidak perlu memperbaharui semua ukuran judul artikel. Cukup perbaharui ukuran teks dasarnya saja. Selebihnya akan secara otomatis mengikuti skala yang diterapkan.

Ketika em Menjadi Lebih Baik

em adalah satuan yang dihitung berdasarkan ukuran teks di sekitarnya. Pada dasarnya 1em sama dengan 16 piksel. Itu jika Anda tidak menentukan ukuran teks pada elemen manapun. Tapi jika —misalnya— Anda menentukan ukuran teks sebesar 30 piksel pada <body>, maka 1em di area <body> akan setara dengan 30px (1em = Ukuran Teks di Sekitarnya).

Satuan em dalam line-height dan margin Paragraf

Satuan em sangat bermanfaat untuk menentukan ukuran dan jarak elemen yang terkait erat dengan ukuran teks. Misalnya margin paragraf dan jarak antar baris teks.

Contoh Kasus: Dua buah kolom dengan elemen paragraf di dalamnya mendapatkan ukuran teks sebesar 13 piksel yang diturunkan dari <body>. Paragraf di dalam kolom pertama menggunakan satuan piksel untuk mengatur margin dan line-height, sedangkan paragraf yang berada di dalam kolom ke dua akan menggunakan satuan em:

HTML

<div class="one">
    <p>Lorem ipsum dolor sit amet...</p>
    <p>Lorem ipsum dolor sit amet...</p>
</div>
<div class="two">
    <p>Lorem ipsum dolor sit amet...</p>
    <p>Lorem ipsum dolor sit amet...</p>
</div>

CSS

body {font-size:13px} /* 1em = 13px */

.one p {
  line-height:18px;
  margin:13px 0;
}

.two p {
  line-height:1.384615384615385em; /* 18 / 13 */
  margin:1em 0;
}

Hasil akhirnya, ukuran dan jarak antar baris paragraf akan tampak sama:

PX & EM
Sebelah kiri: Menggunakan piksel. Sebelah kanan: Menggunakan em.

Masalah akan muncul ketika Anda mencoba untuk memperbesar/memperkecil ukuran teks:

PX & EM
Sebelah kiri: Menggunakan piksel. Sebelah kanan: Menggunakan em.

Kolom sebelah kiri: Karena kita menggunakan satuan piksel, maka ketika ukuran teks berubah (dalam kasus ini: bertambah besar) jarak antar baris dan margin paragraf tetap sempit dan tidak berubah, bertahan pada ukuran 18px dan 13px. Membuat tulisan menjadi semakin sulit untuk dibaca.

Kolom sebelah kanan: Karena kita menggunakan satuan em, maka skala ukuran tinggi baris dan margin antarparagraf akan menyesuaikan diri berdasarkan ukuran teks.

Dalam Semua Elemen yang Terkait dengan Ukuran Teks

Pada intinya satuan em cocok untuk diterapkan pada semua hal yang berhubungan dengan ukuran teks. Semua hal yang membutuhkan ukuran dengan perbandingan yang tepat terhadap teks. Contoh paling sederhana ada pada desain tombol:

CSS3 Buttons
Desain tombol dengan satuan em pada padding dan border-radius akan menciptakan skala tombol yang lebih ideal dibandingkan px.

Ketika px Menjadi Lebih Baik

Satuan piksel dihitung berdasarkan ukuran lebar dan tinggi satu unit piksel pada layar. Oleh karena itu satuan piksel akan sesuai jika diterapkan pada elemen-elemen yang membutuhkan ukuran yang akurat dan tidak terpengaruh dengan ukuran elemen di sekitarnya. Misalnya lebar dan tinggi ikon, tebal border, blur bayangan, posisi latar dan ukuran teks utama. Ukuran teks utama biasanya dideklarasikan pada elemen <body> atau <html>.


Masalah Akurasi Ukuran pada Satuan Non-Piksel

Tidak bisa dipungkiri bahwa ukuran persentase dan relatif teks tidak akan bisa seakurat ukuran piksel. Tapi memangnya siapa yang peduli dengan itu? Kita, para penikmat desain dan tipografi pada dasarnya tidak pernah peduli mengenai seberapa besar tepatnya, ukuran huruf dan judul artikel yang sedang kita baca. Kita tidak peduli berapa piksel ukuran judul dan teks yang sedang kita baca. Karena yang kita pedulikan selama ini adalah proporsi yang ideal. Tipografi tidak begitu mementingkan akurasi, tipografi lebih mementingkan proporsi. Saya pikir kita tidak perlu khawatir untuk memulai beralih dari piksel dalam kasus-kasus tertentu menuju satuan-satuan relatif yang lebih mudah dipelihara dan responsif terhadap skala di sekitarnya.

Labels: , ,

Friday, March 8, 2013

Menampilkan Total Waktu Memuat Halaman

<div id="load-time">Calculating page load time...</div>
<script>
var showTime = document.getElementById('load-time'),
    startTime = (new Date()).getTime(); // Get the time before `window.onload`

window.onload = function() {
    // Get the current time in `window.onload`
    var endTime = (new Date()).getTime();
    // Now use the `startTime` and `endTime` to calculate the seconds
    // And show the result inside `#load-time`
    showTime.innerHTML = "Page load time = " + ((endTime-startTime)/1000) + " sec(s).";
};
</script>

Labels: ,

Wednesday, March 6, 2013

JavaScript Custom Vertical Scrollbar

Cara kerja manipulasi scrollbar ini bukan dengan cara menghilangkan scrollbar yang asli dan menggantinya dengan yang baru, melainkan hanya menyembunyikan scrollbar asli tersebut di balik/di belakang scrollbar palsu yang kita ciptakan di atasnya. Jika Anda menghilangkan warna latar pada scrollbar buatan ini, maka elemen scrollbar yang asli akan dengan mudah terlihat:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript Custom Vertical Scrollbar</title>
<style>
.scroll-area-wrapper {
  width:80%;
  margin:50px auto;
}
.scroll-area {
  overflow:auto;
  padding-right:1em;
  position:relative;
}
.scrollbar-track,
.scrollbar-arrow-up,
.scrollbar-arrow-down,
.scrollbar-thumb {position:absolute}
/* scrollbar track */
.scrollbar-track {
  background-color:#ccc;
  top:0;
  right:0;
  bottom:0;
}
/* scrollbar thumb */
.scrollbar-thumb {
  background-color:#eee;
  cursor:pointer;
  position:absolute;
  right:0;
}
/* up & down arrow */
.scrollbar-arrow-up,
.scrollbar-arrow-down {
  background-color:#eee;
  cursor:pointer;
  right:0;
}
.scrollbar-arrow-up {top:0}
.scrollbar-arrow-down {bottom:0}
.scrollbar-arrow-up:before,
.scrollbar-arrow-down:before {
  content:"";
  display:block;
  position:absolute;
  border:4px solid transparent;
  left:50%;
  margin-left:-4px;
}
.scrollbar-arrow-up:before {
  border-bottom-color:#aaa;
  top:50%;
  margin-top:-6px;
}
.scrollbar-arrow-down:before {
  border-top-color:#aaa;
  bottom:50%;
  margin-bottom:-6px;
}
/* hover state */
.scrollbar-arrow-up:hover,
.scrollbar-arrow-down:hover,
.scrollbar-thumb:hover {background-color:#ddd}
</style>
<script>
var ssb = {
    aConts: [],
    mouseY: 0,
    N: 0,
    asd: 0, /* active scrollbar element */
    sc: 0,
    sp: 0,
    to: 0,

    // constructor
    scrollbar: function (cont_id) {
        var cont = document.getElementById(cont_id);

        // perform initialization
        if (! ssb.init()) return false;

        var cont_outer = document.createElement('div');
        cont_outer.style.overflow = 'hidden';
        cont_outer.style.position = 'relative';
        cont.parentNode.appendChild(cont_outer);
        cont_outer.appendChild(cont);
        cont_outer.style.height = cont.offsetHeight + 'px';
        cont.style.position = 'relative';
        cont.style.top = '0px';
        cont.style.height = '100%';

        // adding new container into array
        ssb.aConts[ssb.N++] = cont;

        cont.sg = false;

        //creating scrollbar child elements
        cont.st = this.create_div('scrollbar-track', cont, cont_outer);
        cont.sb = this.create_div('scrollbar-thumb', cont, cont_outer);
        cont.su = this.create_div('scrollbar-arrow-up', cont, cont_outer);
        cont.sd = this.create_div('scrollbar-arrow-down', cont, cont_outer);

        // on mouse down processing
        cont.sb.onmousedown = function (e) {
            if (! this.cont.sg) {
                if (! e) e = window.event;

                ssb.asd = this.cont;
                this.cont.yZ = e.screenY;
                this.cont.sZ = cont.scrollTop;
                this.cont.sg = true;

            }
            return false;
        };

        // on mouse down on free track area - move our scroll element too
        cont.st.onmousedown = function (e) {
            if (! e) e = window.event;
            ssb.asd = this.cont;

            ssb.mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
            for (var o = this.cont, y = 0; o !== null; o = o.offsetParent) y += o.offsetTop;
            this.cont.scrollTop = (ssb.mouseY - y - (this.cont.ratio * this.cont.offsetHeight / 2) - this.cont.sw) / this.cont.ratio;
            this.cont.sb.onmousedown(e);
        };

        // onmousedown events
        cont.su.onmousedown = cont.su.ondblclick = function (e) { ssb.mousedown(this, -1); return false; };
        cont.sd.onmousedown = cont.sd.ondblclick = function (e) { ssb.mousedown(this,  1); return false; };

        // onmouseout events
        cont.su.onmouseout = cont.su.onmouseup = ssb.clear;
        cont.sd.onmouseout = cont.sd.onmouseup = ssb.clear;

        // onscroll - change positions of scroll element
        cont.ssb_onscroll = function () {
            this.ratio = (this.offsetHeight - 2 * this.sw) / this.scrollHeight;
            this.sb.style.top = Math.floor(this.sw + this.scrollTop * this.ratio) + 'px';
        };

        // scrollbar width
        cont.sw = 18;

        // start scrolling
        cont.ssb_onscroll();
        ssb.refresh();
        
        // binding own onscroll event
        cont.onscroll = cont.ssb_onscroll;
        return cont;
    },

    // initialization
    init: function () {
        if (window.opera || (! window.addEventListener && ! window.attachEvent)) { return false; }

        // temp inner function for event registration
        function addEvent (o, e, f) {
            if (window.addEventListener) { o.addEventListener(e, f, false); ssb.w3c = true; return true; }
            if (window.attachEvent) return o.attachEvent('on' + e, f);
            return false;
        }

        // binding events
        addEvent(window.document, 'mousemove', ssb.onmousemove);
        addEvent(window.document, 'mouseup', ssb.onmouseup);
        addEvent(window, 'resize', ssb.refresh);
        return true;
    },

    // create and append div finc
    create_div: function(c, cont, cont_outer) {
        var o = document.createElement('div');
        o.cont = cont;
        o.className = c;
        cont_outer.appendChild(o);
        return o;
    },

    // do clear of controls
    clear: function () {
        clearTimeout(ssb.to);
        ssb.sc = 0;
        return false;
    },

    // refresh scrollbar
    refresh: function () {
        for (var i = 0, N = ssb.N; i < N; i++) {
            var o = ssb.aConts[i];
            o.ssb_onscroll();
            o.sb.style.width = o.st.style.width = o.su.style.width = o.su.style.height = o.sd.style.width = o.sd.style.height = o.sw + 'px';
            o.sb.style.height = Math.ceil(Math.max(o.sw * 0.5, o.ratio * o.offsetHeight) + 1) + 'px';
        }
    },

    // arrow scrolling
    arrow_scroll: function () {
        if (ssb.sc !== 0) {
            ssb.asd.scrollTop += 6 * ssb.sc / ssb.asd.ratio;
            ssb.to = setTimeout(ssb.arrow_scroll, ssb.sp);
            ssb.sp = 32;
        }
    },

    /* event binded functions: */
    // scroll on mouse down
    mousedown: function (o, s) {
        if (ssb.sc === 0) {
            ssb.asd = o.cont;
            ssb.sc = s;
            ssb.sp = 400;
            ssb.arrow_scroll();
        }
    },

    // on mouseMove binded event
    onmousemove: function(e) {
        if (! e) e = window.event;
        // get vertical mouse position
        ssb.mouseY = e.screenY;
        if (ssb.asd.sg) ssb.asd.scrollTop = ssb.asd.sZ + (ssb.mouseY - ssb.asd.yZ) / ssb.asd.ratio;
    },

    // on mouseUp binded event
    onmouseup: function (e) {
        if (! e) e = window.event;
        var tg = (e.target) ? e.target: e.srcElement;
        if (ssb.asd && document.releaseCapture) ssb.asd.releaseCapture();

        document.onselectstart = '';
        ssb.clear();
        ssb.asd.sg = false;
    }

};
</script>
</head>
<body>

<div class="scroll-area-wrapper">
    <div class="scroll-area" id="scroll-area-1" style="height:400px;">
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.</p>
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.</p>
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.</p>
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.</p>
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.</p>
    </div>
</div>
<script>
ssb.scrollbar('scroll-area-1'); // scrollbar initialization with element ID
</script>

</body>
</html>

Lihat Demo


Referensi: Script Tutorials – Custom Scrollbars (dengan beberapa perubahan dan peniadaan fitur yang tidak terlalu penting).

Labels: ,

Saturday, March 2, 2013

Eksperimen Infinite Scroll dengan JSON Blogger

Blogger Infinite Scroll Experiment
Blogger Infinite Scroll Experiment

Eksperimen membuat infinite scroll dengan JSON Blogger. Sebuah sistem yang akan memperbaharui jumlah item posting setiap kali pengguna mencapai batas akhir layar ketika pengguna sedang menggulung halaman. Metode ini sebenarnya sudah pernah Saya tuliskan di sini. Saya mengganti kondisional batas akhir yang tadinya berupa perbandingan antara tinggi kontainer dengan batas akhir gulungan area seperti ini:

container.onscroll = function() {
    if ((this.scrollTop + this.offsetHeight) == inner.offsetHeight) {
        myFunction();
    }
};

Menjadi berdasarkan perbandingan antara tinggi layar dengan batas akhir gulungan layar seperti ini:

window.onscroll = function() {
    if (navigator.userAgent.toLowerCase().indexOf("chrome") > -1 || navigator.userAgent.toLowerCase().indexOf("safari") > -1) {
        if (document.documentElement.scrollHeight == (document.body.scrollTop + document.documentElement.clientHeight)) {
            myFunction();
        }
    } else {
        if (document.documentElement.scrollHeight == (document.documentElement.scrollTop + document.documentElement.clientHeight)) {
            myFunction();
        }
    }
};

Lihat Demo

Selengkapnya mengenai potongan kode untuk mengecek batas akhir gulungan layar bisa Anda baca di sini.

Silakan dipelajari dan dimodifikasi sesuka hati Anda dengan mengikuti persetujuan yang Saya tuliskan di dalam kode sumbernya. Eksperimen ini akan diperbaharui jika memang ada yang perlu diperbaharui. Begitu.

Labels: , , ,