This is a simple load more plugin, built for teaching purposes. For this reason, it's not pretty in terms of output.
I'd like to know if this can be improved, or if anyone can spot any major problems with this. The one thing I'm concerned about is the 'templating', whereby it gets the template from the initial markup and duplicates it.
loadmore.js
/*jslint unparam: true, white: true */
(function($) {
"use strict";
$.fn.loadmore = function(options) {
var self = this,
settings = $.extend({
source: '',
step: 2
}, options),
stepped = 1,
item = self.find('.item'),
finished = function() {
self.find('.items-load').remove();
},
append = function(value) {
var name,
part;
item.remove();
for(name in value) {
if(value.hasOwnProperty(name)) {
part = item.find('*[data-field="' + name + '"]');
if(part.length) {
part.text(value[name]);
}
}
}
item.clone().appendTo(self.find('.items'));
},
load = function(start, count) {
$.ajax({
url: settings.source,
type: 'get',
dataType: 'json',
data: {start: start, count: count},
success: function(data) {
var items = data.items;
if(items.length) {
$(items).each(function(index, value) {
append(value);
});
stepped = stepped + count;
}
if(data.last === true) {
finished();
}
}
});
};
if(settings.source.length) {
// Event handler for load more button
self.find('.items-load').on('click', function() {
load(stepped, settings.step);
return false;
});
load(1, settings.step);
} else {
console.log('Source required for loadmore.');
}
};
}(jQuery));
Example usage
<!DOCTYPE html>
<html>
<head>
<title>Load more</title>
<meta charset="UTF-8">
</head>
<body>
<h4>Articles</h4>
<div class="articles">
<div class="items">
<div class="item">
<h3><span data-field="title"></span> (<span data-field="id"></span>)</h3>
<p data-field="description"></p>
</div>
</div>
<a href="#" class="items-load">Load more</a>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="js/loadmore.js"></script>
<script>
$('.articles').loadmore({
source: 'articles.php',
step: 2
});
</script>
</body>
</html>
Example JSON generated with PHP
<?php
header('Content-Type: application/json');
$pdo = new PDO("mysql:host=127.0.0.1;dbname=loadmore", "root", "");
$articles = [];
$start = isset($_GET['start']) ? (int)$_GET['start'] - 1 : 0;
$count = isset($_GET['count']) ? (int)$_GET['count'] : 1;
$article = $pdo->query("SELECT SQL_CALC_FOUND_ROWS * FROM articles LIMIT {$start}, {$count}");
$articlesTotal = $pdo->query("SELECT FOUND_ROWS() as count")->fetch(PDO::FETCH_ASSOC)['count'];
if($articlesCount = $article->rowCount()) {
$articles = $article->fetchAll(PDO::FETCH_OBJ);
}
echo json_encode(array(
'items' => $articles,
'last' => ($start + $count) >= $articlesTotal ? true : false,
'start' => $start,
'count' => $count
));
-
\$\begingroup\$ May be you help jquery plugin makenskiy.com/demo/jquery.spoiler-list/documentation/… \$\endgroup\$user108421– user1084212016年06月08日 05:02:53 +00:00Commented Jun 8, 2016 at 5:02
1 Answer 1
From some staring at your code
- There are no comments, at all
- You
$.ajax({
call should handle failure by implementingerror
The
items
treatment insuccess
seems little clumsy, first I would not put the function inside the ajax call, secondly I would probably go with something like this:success: function(data) { $(data.items).each(function(index, value) { append(value); }); if(data.last === true) { finished(); } }
- I do not understand the value of
stepped
, what does it bring to your plugin ? It would have been far better to keep the stepping logic out of the plugin, and let the caller pass adata
object that will be passed to the ajax call. '.items-load'
is a magic, repeated constant, you should use a properly named variableitem.find('*[data-field="' + name + '"]');
<- I don't like this, why would you not simply search byid
, it performs better, and it is more standard."use strict";
on the top level, good stuff- Passes perfectly on JsHint.com
if(value.hasOwnProperty(name)) {
<- good defensive codingjQuery handles empty/undefined gracefully, so that you can write nicer code, this:
part = item.find('*[data-field="' + name + '"]'); if(part.length) { part.text(value[name]); }
could be this:
item.find('#'+name).text(value[name]);
The CSS names you use are very generic, you might want to consider adding a small prefix to avoid name clashes
loadmore
->loadMore
because lowerCamelCaseconsole.log
in production is a no-no
Explore related questions
See similar questions with these tags.