Advertisement
  1. Code
  2. Web Development

Erstellen Sie ein Twitter-ähnliches Widget "Mehr laden"

Scroll to top
Read Time: 13 min

German (Deutsch) translation by Katharina Grigorovich-Nevolina (you can also view the original English article)

Sowohl Twitter als auch der Apple App Store verwenden eine brillante Technik zum Laden weiterer Informationen. Wenn Sie auf den Link klicken, erscheinen neue Elemente auf dem Bildschirm. In diesem Tutorial lernen Sie, wie Sie AJAX, CSS, Javascript, JSON, PHP und HTML verwenden, um diese Magie zu erzeugen. Dieses Tutorial enthält auch die jQuery- und MooTools-Versionen des Skripts.


Annahmen

Es gibt einige Annahmen und Anmerkungen, die wir in dieses System einführen:

  • Der Server muss PHP5 ausführen, damit wir die JSON-Funktionen von PHP5 verwenden können.
  • Wir werden Datenbankeinträge aus einer WordPress-MySQL-Tabelle "posten". Der Vorteil des bereitgestellten Codes besteht darin, dass Sie ihn mit jedem Datenbanksystem verwenden können. Sie müssen lediglich die MySQL-Abfrage und die von jQuery oder MooTools verwendeten JSON-Eigenschaften ändern.
  • Der Client muss Javascript unterstützen.
  • Wir verwenden Moo-Werkzeuge (MooTools) 1.2.3 Core and More 1.2.3.1. Wenn jQuery das bevorzugte Framework ist, jQuery 1.3.2 und das ScrollTo-Plugin von Ariel Flesler.

Dieses Tutorial enthält eine Erläuterung des MooTools-Javascript. Während jQuery
Die Syntax unterscheidet sich von Moo-Werkzeuge, die Schönheit moderner JavaScript-Frameworks ist das
Sie unterscheiden sich hauptsächlich in der Syntax, nicht in der Logik. Das jQuery-Javascript wird unten bereitgestellt.

Die Handlung

Hier ist die Reihenfolge der Ereignisse, die in unserem Slick-Widget stattfinden werden:

  • Die Seite wird normalerweise mit einer anfänglichen Anzahl an Beiträgen geladen
  • Der Benutzer klickt auf das Element "Mehr laden" am unteren Rand der Liste
  • Eine AJAX/JSON-Anfrage wird ausgelöst und eine bestimmte Anzahl neuer Posts abgerufen
  • Unser jQuery/MooTools-Javascript empfängt das Ergebnis und erstellt eine Reihe neuer HTML-Elemente, die die JSON-Informationen enthalten
  • Jedes Element wird in das Containerelement des Widgets verschoben
  • Nachdem alle Elemente in die Seite geladen wurden, blättert das Fenster zum ersten neuen Element
  • Spülen und wiederholen.

Load More WidgetLoad More WidgetLoad More Widget

Erster Schritt: Das PHP/MySQL

Der erste Schritt besteht darin zu entscheiden, wie viele Posts während des ersten Seitenladens geladen werden müssen. Da unser Widget sich daran erinnert, wie viele Posts während des letzten Ladens geladen wurden (falls ein Benutzer eine andere Seite besucht und zurückkommt), müssen wir die Sitzung verwenden.

1
	/* settings */
2
	session_start();
3
	$number_of_posts = 5; //5 posts will load at a time

4
	$_SESSION['posts_start'] = $_SESSION['posts_start'] ? $_SESSION['posts_start'] : $number_of_posts; //where we should start

Das obige Code-Snippet enthält alle Inhalte, die wir benötigen. Als Nächstes müssen wir eine PHP-Funktion erstellen, die eine Verbindung zu unserer Datenbank herstellt, weitere Datensätze abruft und deren Inhalt im JSON-Format zurückgibt:

1
	/* grab stuff */
2
	function get_posts($start = 0, $number_of_posts = 5) {
3
		/* connect to and select the db */
4
		$connection = mysql_connect('localhost','username','password'); //hostname, username, password

5
		mysql_select_db('davidwalsh83_blog',$connection);
6
		/* create the posts array */
7
		$posts = array();
8
		/* get the posts */
9
		$query = "SELECT post_title, post_content, post_name, ID FROM wp_posts WHERE post_status = 'publish' ORDER BY post_date DESC LIMIT $start,$number_of_posts";
10
		$result = mysql_query($query);
11
		/* for every post... */
12
		while($row = mysql_fetch_assoc($result)) {
13
			/* set the post content equal to the first paragraph...a "preview" regular expression */
14
			preg_match("/<p>(.*)<\/p>/",$row['post_content'],$matches);
15
			$row['post_content'] = strip_tags($matches[1]);
16
			/* add this record to the posts array */
17
			$posts[] = $row;
18
		}
19
		/* return the posts in the JSON format */
20
		return json_encode($posts);
21
	}

Das obige PHP enthält einen sehr einfachen regulären Ausdruck, der den ersten Absatz des Inhalts meines Beitrags erfasst. Da der erste Absatz der meisten Blogbeiträge als Einführung in den Rest des Inhalts dient, können wir davon ausgehen, dass Absatz eine schöne Vorschau auf den Beitrag darstellt.

Sobald die obige Funktion fertig ist, müssen wir unseren AJAX-Anforderungslistener erstellen. Wir werden wissen, dass jemand eine AJAX-Anfrage gesendet hat, wenn die Variable $_GET['start'] in der Anfrage-URL festgelegt ist.
Wenn eine Anfrage erkannt wird, greifen wir über unsere get_posts()- Funktion weitere 5 Posts auf und geben deren JSON aus. Sobald wir die neuen Beiträge im JSON-Format ausgegeben haben, speichern wir die Anzahl der vom Benutzer angeforderten Elemente und beenden das Skript (sehen Sie unten).

1
/* loading of stuff */
2
if(isset($_GET['start'])) {
3
	/* spit out the posts within the desired range */
4
	echo get_posts($_GET['start'],$_GET['desiredPosts']);
5
	/* save the user's "spot", so to speak */
6
	$_SESSION['posts_start']+= $_GET['desiredPosts'];
7
	/* kill the page */
8
	die();
9
}

Damit ist der serverseitige Code für unser Widget abgeschlossen. Einfach, nein?

Load More WidgetLoad More WidgetLoad More Widget

Schritt 2: Das HTML

Anfangs gibt es nicht viel HTML-Code für dieses Widget. Wir erstellen einen Haupt-Widget-Container. Im Widget-Container befindet sich ein Posts-Wrapper und unser Element "Mehr laden", das als virtueller Server dienen soll, um das Laden weiterer Inhalte auszulösen.

1
<!-- Widget HTML Starts Here -->
2
<div id="posts-container">
3
	<!-- Posts go inside this DIV -->
4
	<div id="posts"></div>
5
	<!-- Load More "Link" -->
6
	<div id="load-more">Load More</div>
7
</div>
8
<!-- Widget HTML Ends Here -->

Obwohl wir noch keine einzelnen Post-Elemente einfügen, ist es wichtig, die HTML-Struktur von Post-DIV-Elementen zu kennen, die in den Posts-Wrapper eingefügt werden:

1
<div class="post">
2
	<a href="{postURL}" class="post-title">{post_title}</a>
3
	<p class="post-content">
4
		{post_content}
5
		<br />
6
		<a href="{postURL}" class="post-more">Read more...</a>
7
	</p>
8
</div>

Sample ItemSample ItemSample Item

Schritt 3: Das CSS

Zeit, um unserem Widget Flare hinzuzufügen. Sie können die Elemente des Widgets beliebig formatieren. Ich habe mich dazu entschlossen, meine Karikatur auf der linken Seite und den Titel, den Inhalt und den Link auf der rechten Seite hinzuzufügen. Wir müssen CSS für die statischen HTML-Elemente und die von Javascript generierten Elemente hinzufügen (sehen Sie unten).

1
#posts-container			{ width:400px; border:1px solid #ccc; -webkit-border-radius:10px; -moz-border-radius:10px; }
2
.post						{ padding:5px 10px 5px 100px; min-height:65px; border-bottom:1px solid #ccc; background:url(dwloadmore.png) 5px 5px no-repeat; cursor:pointer;  }
3
.post:hover					{ background-color:lightblue; }
4
a.post-title 				{ font-weight:bold; font-size:12px; text-decoration:none; }
5
a.post-title:hover			{ text-decoration:underline; color:#900; }
6
a.post-more					{ color:#900; }
7
p.post-content				{ font-size:10px; line-height:17px; padding-bottom:0; }
8
#load-more					{ background-color:#eee; color:#999; font-weight:bold; text-align:center; padding:10px 0; cursor:pointer; }
9
#load-more:hover			{ color:#666; }

Eine zusätzliche CSS-Klasse, die wir erstellen, wird als "Aktivieren" bezeichnet. Diese wird bei jedem Start einer AJAX-Anfrage angezeigt und ausgeblendet, wenn die Anfrage abgeschlossen ist.

1
.activate					{ background:url(/dw-content/loadmorespinner.gif) 140px 9px no-repeat #eee; }

AJAX SpinnerAJAX SpinnerAJAX Spinner

Schritt 4: Das MooTools-Javascript

Unser MooTools-Javascript macht die Magie möglich. Wir verwenden ein Schließmuster, um den MooTools-Code als bewährte Methode zu enthalten:

1
//safety closure

2
(function($) {
3
	//when the DOM is ready...

4
	window.addEvent('domready,function() {

5
		

6
		/* ALL JAVASCRIPT WILL BE IN HERE */

7
		

8
	});

9
})(document.id);

Sobald das DOM fertig ist, stellen wir die anfänglichen Javascript-Einstellungen bereit. Beachten Sie, dass eine dieser Einstellungen, initialPosts, die JSON für den ersten Stapel von Posts enthält, der beim Laden der Seite angezeigt werden soll. Wir definieren auch Variablen für die Anzahl der ursprünglich geladenen Beiträge und die Anzahl der Beiträge, die bei jeder AJAX-Anforderung abgerufen werden sollen.

1
//settings on top

2
var domain = 'http://davidwalsh.name/'; //your domain or directory path goes here

3
var initialPosts = <?php echo get_posts(0,$_SESSION['posts_start']); ?>;
4
var start = <php echo $_SESSION['posts_start']; ?>;
5
var desiredPosts = <?php echo $number_of_posts; ?>;

Initial JSONInitial JSONInitial JSON

Sobald unsere Einstellungen festgelegt sind, definieren wir eine Funktion, um den JSON zu verarbeiten, den wir beim Laden der Seite erhalten, sowie über zukünftige AJAX-Anforderungen. Für jeden Beitrag in der JSON wir...

  • eine Post-URL-Variable erstellen, die wir später in der Schleife verwenden werden
  • ein DIV-Element "post" erstellen, das den Beitragstitel, den Inhalt und den Link (im oben gezeigten Format) enthält.
  • das neu erstellte "post" -Element in den Posts-Wrapper einfügen
  • ein Fx.Slide-Objekt für das neue "post" -Element erstellen, damit wir das Element sofort ausblenden können und es dann in die Ansicht schieben können
  • das Fenster nach unten zum ersten neu eingefügten Beitrag scrollen

Hier ist der MooTools-Javascript-Code, der es erledigt.

1
//function that creates the posts

2
var postHandler = function(postsJSON) {
3
	postsJSON.each(function(post,i) {
4
		//post url

5
		var postURL = '' + domain + post.post_name;
6
		//create the HTML "post" element

7
		var postDiv = new Element('div',{
8
			'class': 'post',
9
			events: {
10
				//click event that makes the entire DIV clickable

11
				click: function() {
12
					window.location = postURL;
13
				}
14
			},
15
			id: 'post-' + post.ID,
16
			html: '<a href="' + postURL + '" class="post-title">' + post.post_title + '</a><p class="post-content">' + post.post_content + '<br /><a href="' + postURL + '" class="post-more">Read more...</a></p>'
17
		});
18
		//inject into the container

19
		postDiv.inject($('posts'));
20
		//create the Fx Slider

21
		var fx = new Fx.Slide(postDiv).hide().slideIn();
22
		//scroll to first NEW item

23
		if(i == 0) {
24
			var scroll = function() {
25
				new Fx.Scroll(window).toElement($('post-' + post.ID));
26
			};
27
			scroll.delay(300); //give time so scrolling can happen

28
		}
29
	});
30
};

ScrollsScrollsScrolls

Jetzt, da unsere postHandler-Funktion definiert ist, ist es Zeit, die anfängliche JSON-Zeichenfolge der Elemente zu behandeln.

1
//place the initial posts in the page

2
postHandler(initialPosts);

Als Nächstes erstellen wir einige weitere Variablen, um den Wert unserer AJAX-Anfrage zu speichern und die Werte des Startwerts der PHP-Sitzung, die Anzahl der zu packenden Posts und das Element "Mehr laden" zu speichern.

1
var start = <?php echo $_SESSION['posts_start']; ?>;
2
var desiredPosts = <?php echo $number_of_posts; ?>;
3
var loadMore = $('load-more');

Um die Speichernutzung zu reduzieren, erstellen wir unser Request.JSON-Objekt außerhalb des Click-Ereignisses, das in Kürze hinzugefügt wird. Das Request.JSON-Objekt sieht zwar lang aus, ist aber sehr einfach. Brechen sie ab...

Das Anforderungsobjekt erstellen wir mit Grundeinstellungen ...

1
	var request = new Request.JSON({
2
		url: 'load-more.php', //ajax script -- same script

3
		method: 'get',
4
		link: 'cancel',
5
		noCache: true,
6
		//more settings coming...

Fügen Sie einen onRequest-Parameter hinzu, der unsere CSS-Klasse "aktivieren" zum anklickbaren Element "Mehr laden" hinzufügt, und ändern Sie den Text des Elements "Mehr laden" in "Laden..." ....

1
onRequest: function() {
2
	//add the activate class and change the message

3
	loadMore.addClass('activate').set('text','Loading...');
4
},

Fügen Sie einen onSuccess -Parameter hinzu, der den Elementtext "Mehr laden" zurücksetzt, den aktuellen Startpunkt zum Erfassen zukünftiger Elemente verfolgt und die JSON-Antwort genauso behandelt wie wir es mit den ersten Posts getan haben ...

1
onSuccess: function(responseJSON) {
2
	//reset the message

3
	loadMore.set('text','Load More');
4
	//increment the current status

5
	start += desiredPosts;
6
	//add in the new posts

7
	postHandler(responseJSON);
8
},

Fügen Sie eine onFailure-Funktion hinzu, um den Text "Mehr laden" bei einem Fehler zu aktualisieren ...

1
onFailure: function() {
2
	//reset the message

3
	loadMore.set('text','Oops! Try Again.');
4
},

Fügen Sie schließlich eine onComplete-Funktion hinzu, die den Spinner entfernt, sobald die Anforderung abgeschlossen ist, unabhängig von Erfolg oder Misserfolg.

1
onComplete: function() {
2
	//remove the spinner

3
	loadMore.removeClass('activate');
4
}

Der letzte Schritt ist das Hinzufügen des Klickereignisses zum Element "Mehr laden". Nach einem Klick stellen wir die AJAX-Anfrage und alle oben genannten Arbeiten werden ausgelöst. Erfolg!

1
//add the "Load More" click event

2
loadMore.addEvent('click',function(){
3
	//begin the ajax attempt

4
	request.send({
5
		data: {
6
			'start': start,
7
			'desiredPosts': desiredPosts
8
		},
9
	});
10
});

AJAX JSONAJAX JSONAJAX JSON

Moo-Werkzeuge Vollständiger Code (MooTools Complete Code)

1
	//safety closure

2
	(function($) {
3
		//domready event

4
		window.addEvent('domready',function() {
5
			//settings on top

6
			var domain = 'http://davidwalsh.name/';
7
			var initialPosts = <?php echo get_posts(0,$_SESSION['posts_start']);  ?>;
8
9
			//function that creates the posts

10
			var postHandler = function(postsJSON) {
11
				postsJSON.each(function(post,i) {
12
					//post url

13
					var postURL = '' + domain + post.post_name;
14
					//create the HTML

15
					var postDiv = new Element('div',{
16
						'class': 'post',
17
						events: {
18
							click: function() {
19
								window.location = postURL;
20
							}
21
						},
22
						id: 'post-' + post.ID,
23
						html: '<a href="' + postURL + '" class="post-title">' + post.post_title + '</a><p class="post-content">' + post.post_content + '<br /><a href="' + postURL + '" class="post-more">Read more...</a></p>'
24
					});
25
					//inject into the container

26
					postDiv.inject($('posts'));
27
					//create the Fx Slider

28
					var fx = new Fx.Slide(postDiv).hide().slideIn();
29
					//scroll to first NEW item

30
					if(i == 0) {
31
						var scroll = function() {
32
							new Fx.Scroll(window).toElement($('post-' + post.ID));
33
						};
34
						scroll.delay(300); //give time so scrolling can happen

35
					}
36
				});
37
			};
38
39
			//place the initial posts in the page

40
			postHandler(initialPosts);
41
42
			//a few more variables

43
			var start = <?php echo $_SESSION['posts_start']; ?>;
44
			var desiredPosts = <?php echo $number_of_posts; ?>;
45
			var loadMore = $('load-more');
46
			var request = new Request.JSON({
47
				url: 'load-more.php', //ajax script -- same page

48
				method: 'get',
49
				link: 'cancel',
50
				noCache: true,
51
				onRequest: function() {
52
					//add the activate class and change the message

53
					loadMore.addClass('activate').set('text','Loading...');
54
				},
55
				onSuccess: function(responseJSON) {
56
					//reset the message

57
					loadMore.set('text','Load More');
58
					//increment the current status

59
					start += desiredPosts;
60
					//add in the new posts

61
					postHandler(responseJSON);
62
				},
63
				onFailure: function() {
64
					//reset the message

65
					loadMore.set('text','Oops! Try Again.');
66
				},
67
				onComplete: function() {
68
					//remove the spinner

69
					loadMore.removeClass('activate');
70
				}
71
			});
72
			//add the "Load More" click event

73
			loadMore.addEvent('click',function(){
74
				//begin the ajax attempt

75
				request.send({
76
					data: {
77
						'start': start,
78
						'desiredPosts': desiredPosts
79
					},
80
				});
81
			});
82
		});
83
	})(document.id);

jQuery-Version

Wenn Sie das Javascript-Framework von jQuery bevorzugen, ist dies Ihr Glückstag. Hier ist die jQuery-Version:

1
	//when the DOM is ready

2
	$(document).ready(function(){
3
		//settings on top

4
		var domain = 'http://davidwalsh.name/';
5
		var initialPosts = <?php echo get_posts(0,$_SESSION['posts_start']); ?>;
6
		//function that creates posts

7
		var postHandler = function(postsJSON) {
8
			$.each(postsJSON,function(i,post) {
9
				//post url

10
				var postURL = '' + domain + post.post_name;
11
				var id = 'post-' + post.ID;
12
				//create the HTML

13
				$('<div></div>')
14
				.addClass('post')
15
				.attr('id',id)
16
				//generate the HTML

17
				.html('<a href="' + postURL + '" class="post-title">' + post.post_title + '</a><p class="post-content">' + post.post_content + '<br /><a href="' + postURL + '" class="post-more">Read more...</a></p>')
18
				.click(function() {
19
					window.location = postURL;
20
				})
21
				//inject into the container

22
				.appendTo($('#posts'))
23
				.hide()
24
				.slideDown(250,function() {
25
					if(i == 0) {
26
						$.scrollTo($('div#' + id));
27
					}
28
				});
29
			});	
30
		};
31
		//place the initial posts in the page

32
		postHandler(initialPosts);
33
		//first, take care of the "load more"

34
		//when someone clicks on the "load more" DIV

35
		var start = <?php echo $_SESSION['posts_start']; ?>;
36
		var desiredPosts = <?php echo $number_of_posts; ?>;
37
		var loadMore = $('#load-more');
38
		//load event / ajax

39
		loadMore.click(function(){
40
			//add the activate class and change the message

41
			loadMore.addClass('activate').text('Loading...');
42
			//begin the ajax attempt

43
			$.ajax({
44
				url: 'load-more.php',
45
				data: {
46
					'start': start,
47
					'desiredPosts': desiredPosts
48
				},
49
				type: 'get',
50
				dataType: 'json',
51
				cache: false,
52
				success: function(responseJSON) {
53
					//reset the message

54
					loadMore.text('Load More');
55
					//increment the current status

56
					start += desiredPosts;
57
					//add in the new posts

58
					postHandler(responseJSON);
59
				},
60
				//failure class

61
				error: function() {
62
					//reset the message

63
					loadMore.text('Oops! Try Again.');
64
				},
65
				//complete event

66
				complete: function() {
67
					//remove the spinner

68
					loadMore.removeClass('activate');
69
				}
70
			});
71
		});
72
	});

Die Moo-Werkzeuge- und jQuery-Versionen weisen dieselbe Logik mit unterschiedlicher Syntax auf!

Mission erfüllt!

Durch die Implementierung dieses Widgets auf Ihrer Website können Sie Ihrer Website mehr Dynamik und Kreativität verleihen. Ich freue mich auf dein Widget! Haben Sie Fragen zur Verbesserung? Posten Sie sie unten!

  • Folgen Sie uns auf Twitter oder abonnieren Sie den NETTUTS-RSS-Feed für mehr tägliche Webentwicklungsberichte und -artikel.


Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.