Memperbaharui Pemuatan JSON berdasarkan Event Scroll

Metode ini masih sama dengan metode-metode penundaan pemuatan JSON yang biasa Saya lakukan untuk widget-widget Saya yaitu dengan cara menyisipkan script callback secara tidak langsung ke dalam area <head>
dengan ID tertentu. Kemudian, jika Saya ingin memperbaharui muatan JSON yang sudah ada, Saya tinggal menyingkirkan script callback yang lama kemudian menggantinya dengan duplikat baru dengan parameter yang sudah diperbaharui.
Bayangkan saja bahwa sudah terdapat sebuah script callback dengan ID foo
di dalam area <head>
seperti ini:
...
...
<script id="foo" src="../feeds/posts/summary?alt=json-in-script&callback=functionName"></script>
</head>
Kemudian Saya akan menyingkirkannya dengan cara menangkap ID elemen tersebut sebagai awalan untuk menyeleksi node induknya:
var a = document.getElementById('foo');
var parent = a.parentNode; // Mendapatkan elemen induk dari `foo`
Kemudian, dari induk tersebut Saya akan menyingkirkan elemen itu sendiri:
var a = document.getElementById('foo');
var parent = a.parentNode; // Mendapatkan elemen induk dari `foo`
parent.removeChild(a); // Singkirkan `foo` dari `parent`
Di sini, kita akan melakukan pekerjaan di atas berdasarkan event onscroll
dengan batasan akhir berupa jarak gulungan maksimal kontainer. Kode di bawah ini akan menjalankan fungsi bernama myFunction()
berdasarkan event onscroll
dengan syarat jarak gulungan telah mencapai titk maksimal:
elem.onscroll = function() {
if ((this.scrollTop + this.offsetHeight) == inner.offsetHeight) {
myFunction();
}
};
Dimana elem
adalah objek berupa kontainer.
Memulai Pekerjaan
Markup HTML
Kita mulai dengan pembuatan markup HTML sederhana seperti ini:
<div id="result-container" style="width:400px;height:400px;overflow:auto;">
<ol></ol>
<span class="loading">Memuat...</span>
</div>
Elemen #result-container
digunakan sebagai area scroll, elemen ol
digunakan sebagai kontainer data yang nantinya akan dihasilkan dari JSON, dan elemen span.loading
digunakan sebagai indikator sedang memuat.
Membangun JavaScript
Pertama-tama kita buat script untuk memparse data JSON menjadi elemen HTML. Sederhana, seperti script recent post biasa yang Saya beri nama grabList()
, dan hanya akan menghasilkan elemen <li>
dengan tautan dan judul posting di dalamnya:
var elem = document.getElementById('result-container'), // Mendapatkan elemen `#result-container`
inner = elem.getElementsByTagName('ol')[0], // Mendapatkan elemen `ol` pertama
loading = elem.getElementsByTagName('span')[0]; // Mendapatkan elemen `span` pertama (dalam hal ini adalah elemen indikator sedang memuat)
// Bangun sebuah script untuk menampilkan daftar posting
function grabList(json) {
var list = json.feed.entry, link, skeleton = "";
// Jalankan loop hanya jika data JSON masih ada/dapat didefinisikan
if (typeof list !== "undefined") {
for (var i = 0; i < list.length; i++) {
for (var j = 0; j < list[i].link.length; j++) {
if (list[i].link[j].rel == "alternate") {
link = list[i].link[j].href; // Mendapatkan URL posting
break;
}
}
// Bangun beberapa elemen `<li>` yang berisi tautan dan judul posting...
skeleton += '<li><a href="' + link + '">' + list[i].title.$t + '</a></li>';
}
// ... kemudian sisipkan elemen tersebut ke dalam elemen `<ol>`
inner.innerHTML += skeleton;
// dan sembunyikan indikator sedang memuat.
loading.style.display = "none";
} else {
// Jika data JSON sudah tidak ada (list === "undefined"), tambahkan kelas baru kepada elemen indikator sedang memuat dengan nilai `the-end`
loading.className += ' the-end';
// kemudian ganti teks indikator sedang memuat dengan kata `Habis`
loading.textContent = 'Habis';
}
}
Setelah itu buat sebuah fungsi untuk memuat script callback secara tidak langsung. Tambahkan dua buah parameter untuk menangani start-index
dan max-results
:
function updateScript(i, max) {
var head = document.getElementsByTagName('head')[0],
script = document.createElement('script');
script.type = 'text/javascript';
script.id = 'load-on-scroll-end';
script.src = 'http://nama_blog.blogspot.com/feeds/posts/summary?alt=json-in-script&start-index=' + i + '&max-results=' + max + '&callback=grabList';
head.appendChild(script);
}
// Jalankan fungsi!
updateScript(1, 25);
Fungsi di atas akan menyisipkan sebuah script callback JSON Blogger dengan nilai parameter start-index
berupa 1
dan max-results
berupa 25
, sehingga sebuah elemen <script>
dengan parameter yang sudah diatur akan disipkan ke dalam area <head>
secara tidak langsung seperti ini:
...
...
...
<script id="load-on-scroll-end" src="//nama_blog.blogspot.com/feeds/posts/summary?alt=json-in-script&start-index=1&max-results=25&callback=grabList"></script>
</head>
Memperbaharui JSON Berdasarkan Jarak Maksimal Gulungan Area
Setelah itu kita tambahkan sebuah kondisional untuk menyingkirkan script callback lama jika script tersebut ada. Tidak perlu membuat fungsi baru, cukup gunakan fungsi tadi agar kita bisa menggunakannya untuk dua hal sekaligus, yaitu menyisipkan script baru dan/atau menyingkirkan script lama (jika ada):
function updateScript(i, max) {
var head = document.getElementsByTagName('head')[0],
script = document.createElement('script');
script.type = 'text/javascript';
script.id = 'load-on-scroll-end';
script.src = 'http://nama_blog.blogspot.com/feeds/posts/summary?alt=json-in-script&start-index=' + i + '&max-results=' + max + '&callback=grabList';if (document.getElementById('load-on-scroll-end')) {
var oldScript = document.getElementById('load-on-scroll-end');
oldScript.parentNode.removeScript(oldScript);
} head.appendChild(script);
}
updateScript(1, 25); // Jalankan fungsi!
Karena kita juga akan menjalankan fungsi updateScript()
berdasarkan event onscroll
, maka kita juga harus memasukkan updateScript()
ke dalam event yang Saya tuliskan pertama kali:
elem.onscroll = function() {
if ((this.scrollTop + this.offsetHeight) == inner.offsetHeight) {
// Muat ulang JSON Blogger dengan `start-index` yang baru melalui parameter `i`
updateScript(i, 25);
// Kemudian tampilkan indikator sedang memuat
loading.style.display = "block";
}
};
Parameter i
haru dinamis, dan harus bisa bertambah setiap kali gulungan kontainer berakhir. Untuk membuatnya menjadi dinamis, kita akan menggunakan variabel awalan dengan nilai 0
, kemudian kita tingkatkan nilainya di dalam event onscroll
setiap kali jarak gulungan telah mencapai titik maksimal:
var start = 0;elem.onscroll = function() {
if ((this.scrollTop + this.offsetHeight) == inner.offsetHeight) {
// Tingkatkan nilai `start` dengan 1 (dari `start = 0` menjadi `start = 1`, `start = 2`, dst...)start++; // Muat ulang JSON Blogger dengan `start-index` yang telah diperbaharui...
// ... melalui `start` yang nilainya dikalikan dengan 25
updateScript(start*25, 25); // => dari `(1, 25)` menjadi `(25, 25)`, `(50, 25)`, `(75, 25)`, dst...
// Kemudian tampilkan indikator sedang memuat
loading.style.display = "block";
}
};
Produk Final
HTML
<div id="result-container">
<ol></ol>
<span class="loading">Memuat...</span>
</div>
CSS
#result-container {
height:400px;
width:400px;
overflow:auto;
margin:50px auto;
font:normal normal 12px 'Trebuchet MS',Trebuchet,Geneva,Arial,Sans-Serif;
}
#result-container ol {
margin:0 0;
padding:0 0;
background-color:#B5D68C;
}
#result-container li {
margin:0 0;
padding:0 0;
list-style:none;
}
#result-container li:nth-child(even) {background-color:#A2C179}
#result-container li a {
display:block;
padding:5px 10px;
font-weight:bold;
color:#396B18;
text-decoration:none;
}
#result-container li a:hover {
background-color:#396B18;
color:white;
text-decoration:none;
}
#result-container .loading {
display:block;
height:26px;
font:normal bold 11px/26px Arial,Sans-Serif;
color:white;
text-align:center;
background-color:#B75A6F;
border-top:2px solid #222;
}
#result-container .loading.the-end {background-color:#666}
JavaScript
var widget_config = {
home_page: 'http://nama_blog.blogspot.com', // Your blog homepage
container_id: 'result-container', // ID of the result container
script_id: 'load-on-scroll-end-script', // ID of the asynchronous script
max_result: 25, // Max result post at once script loading
end_text: 'Habis' // End text if all posts has been loaded
};
var elem = document.getElementById(widget_config.container_id),
inner = elem.getElementsByTagName('ol')[0],
loading = elem.getElementsByTagName('span')[0],
start = 0, // Dynamic start-index
max = widget_config.max_result;
function grabList(json) {
var list = json.feed.entry, link, skeleton = "";
if (typeof list !== "undefined") {
for (var i = 0; i < list.length; i++) {
for (var j = 0; j < list[i].link.length; j++) {
if (list[i].link[j].rel == "alternate") {
link = list[i].link[j].href;
break;
}
}
skeleton += '<li><a href="' + link + '">' + list[i].title.$t + '</a></li>';
}
inner.innerHTML += skeleton; // Insert the list to the container
loading.style.display = "none"; // Hide the loading indicator
} else {
// If the JSON is empty (list === "undefined"),
// add a new class to the loading indicator called `the-end`
loading.className += ' the-end';
// Replace the loading indicator text into `fully loaded!` for the example
loading.textContent = widget_config.end_text;
}
}
// Make an indirect script loader with two parameters: start-index and max-result post
function updateScript(a, b) {
var head = document.getElementsByTagName('head')[0],
script = document.createElement('script');
script.type = 'text/javascript';
script.id = widget_config.script_id;
script.src = widget_config.home_page + '/feeds/posts/summary?alt=json-in-script&start-index=' + a + '&max-results=' + b + '&callback=grabList';
// If there is an old script in the document...
if (document.getElementById(widget_config.script_id)) {
var oldScript = document.getElementById(widget_config.script_id);
// Remove the old script, and replace with the new one that has an updated start-index value
oldScript.parentNode.removeChild(oldScript);
}
head.appendChild(script);
}
// Start loading the callback script with start-index of 1
updateScript(1, max);
// When the container is being scrolled...
elem.onscroll = function() {
// ... check the scroll distance
if ((this.scrollTop + this.offsetHeight) == inner.offsetHeight) {
// If the distance equal to the height of the inner container...
start++; // Increase the start value by one
// then load the new script with an updated start-index
updateScript(start*max, max);
// and show the loading indicator
loading.style.display = "block";
}
};
Labels: Blogger, JavaScript, JSON, Lanjutan, Widget
17 Comments:
Yang JavaScript untuk Mengecek Batas Akhir Gulungan Layar aku masih bingung apalagi ini pengembangannya kak, tapi aku coba untuk memahami dan pelajarinya kak, mudah-mudahan bisa.
By
IRIL SAGITA, at Tuesday, November 13, 2012 at 8:31:00 AM GMT+7
Euumh... :yaya:
berarti ini yaah yang seperti sebagian blog wordpress ituhh... ??
By
Sixrone 609 Community, at Tuesday, November 13, 2012 at 12:27:00 PM GMT+7
:-Bd gracias.
By
yoestoy22, at Tuesday, November 13, 2012 at 12:27:00 PM GMT+7
WOW keYen :-bd
By
Beben Koben, at Tuesday, November 13, 2012 at 11:11:00 PM GMT+7
ini fungsinya sama kaya di Facebook ya, setelah kita scroll ke bawah akan termuat lagi :D
:bd
By
Rosyd Aqbar, at Saturday, November 17, 2012 at 4:57:00 PM GMT+7
Mas Taufik, postingan tentang "Memperbaharui Pemuatan JSON berdasarkan tombol yang di klik" judulnya apa ya? Saya cari-cari dari tadi kok gak nemu2 :'(
Terima kasih :)
By
Yopi Hasopa, at Monday, February 25, 2013 at 6:04:00 PM GMT+7
dulu saya pernah baca postingan nya di blog Mas Taufik ini, tapi lupa :(
By
Yopi Hasopa, at Monday, February 25, 2013 at 6:06:00 PM GMT+7
Tidak ada. Kalau untuk kasus memuat JSON dengan event klik, dengan fungsi di atas bisa dibuat seperti ini:
var btn = document.getElementById('btn');
btn.onclick = function() {
updateScript(1, 25);
};
Tombolnya seperti ini:
<button id="btn">Load Feed</button>
By
Taufik Nurrohman, at Tuesday, February 26, 2013 at 8:21:00 AM GMT+7
Saya juga masih agak sedikiti bingung dengan penjelasan Bang Taufiq
By
hanggarps, at Tuesday, March 5, 2013 at 3:17:00 PM GMT+7
cara memasang di blogger gimana mas...??
By
Wiro Sableng, at Wednesday, July 3, 2013 at 12:40:00 PM GMT+7
mas, gimana mahu memasukkan post date pada json event scroll diatas?
By
Unknown, at Tuesday, August 13, 2013 at 9:00:00 AM GMT+7
From the final code above, replace this line:
for (var i = 0; i < list.length; i++) {
with this:
for (var i = 0; i < list.length; i++) {
var date = list[i].published.$t.substring(0, 10).replace(/\-/g, "/");
Then, replace this line:
skeleton += '<li><a href="' + link + '">' + list[i].title.$t + '</a></li>';
with this, to show the post date right after the post title:
skeleton += '<li><a href="' + link + '">' + list[i].title.$t + ' - ' + date + '</a></li>';
By
Taufik Nurrohman, at Tuesday, August 13, 2013 at 9:13:00 PM GMT+7
mas, gimana mahu memperbaharui pemuatan json pada body dan bukannya pada #result-container
By
On9Shop2u, at Saturday, December 7, 2013 at 8:41:00 PM GMT+7
⇒ /2013/04/membuat-navigasi-halaman-ajax-pada.html
⇒ /2013/03/infinite-scroll-experiment-with-blogger.html
By
Taufik Nurrohman, at Sunday, December 8, 2013 at 6:16:00 AM GMT+7
Hi,
First of all I want to thank you for this great tutorial because you took blogger to a hole new level.
I wrote this comment to tell you that there is a bug in the widget which is the plugin is repeat the last post (see the image) http://goo.gl/l02b58 I hope you fix it :).
Thank you
By
Abdelghafour, at Monday, November 10, 2014 at 4:04:00 AM GMT+7
I have experienced that before, sometimes it is due to the number of posts.
You can change this conditional with something more specific, which mean “if there is more posts in the feed”:
if (list !== undefined) {
Example:
if (typeof list != "undefined") {
if (typeof list != "undefined" && list.length > 0) {
By
Taufik Nurrohman, at Wednesday, November 12, 2014 at 8:17:00 AM GMT+7
Mas Taufik, postingan tentang "Memperbaharui Pemuatan JSON berdasarkan tombol yang di klik" DEMO?
By
Unknown, at Thursday, April 2, 2015 at 12:46:00 PM GMT+7
Post a Comment
<< Home