EDIT: This question was initially too general, I think. So What I really need is a very good tutorial on how to implement the Load More function on Safari for iPhone just like the Twitter website(mobile.twitter.com) does. Just a wordpress plugin won't really help. But if the plugin is well explained, like if it is wptouch, home(that also has this function) that can also do.
I know that it doesn't really matter that it is being displayed on a mobile device, but the point I am stressing is that if such a function is well explained, then it will be up to me to know how to customize it to suit me.
I am using a javascript function to load entries that come from the database dynamically, so that content opens in the same page (like with twitter(tweets feed) and facebook(news feed)).
The php/html version(That opens a page in a new tab) is
echo 'Load more entries› ';
The javascript/ajax version:
<div id="call_hv<?php echo md5($_SERVER['REQUEST_URI']); ?>" class="ajax-load-more">
<img id="spinner<?php echo md5($_SERVER['REQUEST_URI']); ?>" class="spin" src="<?php bloginfo('template_directory'); ?>/images/main-ajax-loader.gif" style="display:none" alt="" />
<a class="ajax" href="javascript:$ajax_hv('#spinner<?php echo md5($_SERVER['REQUEST_URI']); ?>').fadeIn(200);
$ajax_hv('#ajaxentries_hv<?php echo md5($_SERVER['REQUEST_URI']); ?>').load('form='<? echo $form_id; ?>&page=<?php echo $page+1;?>', {},
function(){ $ajax_hv('#call_hv<?php echo md5($_SERVER['REQUEST_URI']); ?>').fadeOut();})">Load more entries...
</a>
The basic idea is to listen to scroll events, and implement paging on the server side.
A scroll event is fired whenever the document or a contained HTML element scrolls. I'll use this sketch for reference keeping the following things in mind:
Let's say the height of the browser window is 800px, and the initial height of the content is 2500px. The threshold for loading AJAX content is when the user scrolls to the bottom 100px of our content (after the first 2400px).
We will need to keep track of the following 2 items:
Items/Pages loaded so far.
How far are we from the bottom of
the page.
The code references are in MooTools, but the concept is the same. Converting it to jQuery is a trivial task once you understand it.
var maxPage = 1;
var threshold = 100;
We need to know whenever the page scrolls, so add a handler for scroll events. Find the scroll distance to the bottom of the page. If it's less than the defined threshold (100px), then fire off an AJAX request loading the next page. When the response comes (if successful), append it to the page and increment maxPage number.
Another thing to keep in mind is to only fire an AJAX request if content is not already being loaded. Have a flag that indicates whether the page request is still pending.
var isLoading = false;
window.addEvent('scroll', function() {
// the height of the entire content (including overflow)
var contentHeight = window.getScrollSize().y;
// current scroll is height of content that's above the viewport plus
// height of the viewport.
var contentScrolled = window.getScroll().y + window.getSize().y;
var distanceToBottom = contentHeight - contentScrolled;
var closeToBottomOfPage = distanceToBottom < threshold;
var shouldLoadMoreContent = !isLoading && closeToBottomOfPage;
if(shouldLoadMoreContent) {
// create an ajax request
var request = new Request({
url: 'http://www.example.com/more',
onSuccess: function(responseText) {
$('page').append(responseText);
maxPage++;
},
onRequest: function() {
isLoading = true;
},
onComplete: function() {
isLoading = false;
}
});
// fire off ajax request with the page # as a querystring param
request.send({page: maxPage});
}
}
Commonly called an Infinite scroll. There are plugins for jQuery and Wordpress:
http://www.infinite-scroll.com/
Related
I've spent hours reading javascript books, patterns and looking on stackoverflow questions but I'm stuck on loading something dynamically into an iframe
Goal Click on a button, (1) ajax post to temp.php with data (ex. src, height, width, id).
(2) temp.php sets up the iframe and returns the respective html. (3) Javascript prepends the data.
Here is the respective code I have so far
(1)
$.ajax({
type:"POST",
data:{
'src':"target.php",
'frame_height':$(".mydiv").height(),
'frame_width':$(".mydiv").width()
},
url:"temp.php",
success:function (inHtml) {
loadConversation(inHtml,
I've loaded the POST variables into the respective php variables already.
(2)
<iframe id="myTestFrame" src="<?php echo $src; ?>" width="<?php echo $width; ?>"
height="<?php echo $height; ?>" frameborder="0">
<p>Your browser does not support iframes.</p>
(3)
$('.mydiv').prepend(inHtml);
Please assume that the syntax is done correctly.
the target.php does run a simple javascript code initializing a scroll plugin:
$(function () {
var Scroll = (function () {
var init = function () {
$("#content-1").mCustomScrollbar({});
$(".inner_content").mCustomScrollbar({autoDraggerLength:true});
$(".output a[rel~='_mCS_1_scrollTo']").click(function (e) {
e.preventDefault();
$("#content-1").mCustomScrollbar("scrollTo", $(this).attr("href"));
});
};
return { init:init };
})();
Scroll.init();
});
What's happening now is that I can call temp.php directly from the webserver and it will load properly.
expected
But once it's called from the main site - it breaks (and an 'undefined' to boot)
broken in main site
I've done the same iframe post and then update src dynamically with another php page with a plugin and it works fine (same on click, ajax post, prepend(html) , I'm completely lost). The main site is running it inside a tabbed interface from jquery UI, but I don't think that makes any difference - what I've found so far is that if I insert a simple 'alert(document.height)' into the init function, the alert box will contain 0, so I think the javascript runs before the iframe has finished loading - but Firebug shows that the Response HTML in NET is perfectly fine and the code is rather short. (The script is placed last right before the close brace)
I'm pretty new to jQuery, AJAX, and web dev in general, so this is driving me crazy.
I've got an AJAX request that pulls in page content into the current one, and I'm trying to coerce jQuery into displaying it like so:
Fade out current content
Smoothly resize the div to the new content
Fade in new content
So far, I've got it written up something like this. I've changed it a round a bunch, so this might not be the closest I've gotten, but the same problem still persists.
$("#page-data").fadeOut(600).html(data);
$("#page-data").ready(function() {
var newHeight = $('#' + divname).height();
$("#page-data").animate({
height: newHeight,
}, 600, function() {
$("#page-data").fadeIn(100);
});
});
Where page data's got this simple style:
#page-data { position: relative; overflow: hidden; }
My problem is that $('#' + divname).height() doesn't account for images and other things that could occur in the div. I tried using .load() instead of .ready(), but then the callback isn't called at all.
Since there isn't any HTML included in the question, I'm assuming that you have your container <div id="pageData"> that holds another <div> (identified by divname), into which you are loading your dynamic content.
Firstly, $(..).ready() can only be used used on the document object, so using applying it to a <div> goes against jQuery's documentation.
The best way I can think to acheive your goal is to keep track of any images in the HTML that you have dynamically loaded via AJAX and monitor them until they have all been loaded. Then you can apply your logic for setting the height of your container <div>.
The problem is that if we apply a load event handler to an image that has already loaded, then it won't fire. Working out whether an image has been already loaded can be tricky, but the received wisdom seems to be to check the complete property (if it exists) or check whether the the height of the image is greater than 0:
function imageLoaded(img) {
if(typeof img.complete != 'undefined') {
return img.complete;
}
else {
return(img.height > 0);
}
}
Now we can take the following steps:
Fade out the <div> (e.g. #pageContent) that will contain your AJAX
content
Load the AJAX content
Search through the new content for all
images, count how many there are, add a load event handler to each
one, then cycle through each image checking if it's already loaded
and manually firing the load event if so.
In the load event we decrement the counter. When the counter reaches zero, then calculate the height of the container <div> and fade in the content
For example (see here for a working jsfiddle):
$pageData = $('#pageData');
$pageContent = $('#pageContent');
$pageData.height($pageData.height());
$pageContent.fadeOut(function() {
$pageContent.load('http://your.dynamic.content', contentLoaded);
});
function contentLoaded() {
var $loadables = $(this).find('img');
var loadableCount = $loadables.length;
// Attach onLoad event handlers to each image
$loadables.load(function() {
loadableCount--;
checkAllLoaded(loadableCount);
});
// Trigger the onLoad events manually for any images that have already loaded
$loadables.each(function() {
if(imageLoaded(this)) {
$(this).trigger('load');
}
});
}
function checkAllLoaded(loadCount) {
if (loadCount <= 0) {
$('#pageData').animate({
height: $('#pageContent').height()
}, 600, function() {
$('#pageContent').fadeIn();
});
}
}
This is probably a simple question but I am stumped and just don't know where to start.
I have a PHP script (image_feed.php) that returns a URL to an image. Every time this URl is called it returns the latest image available (the image changes every couple of seconds).
What I want to happen is that when the page loads, there is an AJAX call to image_feed.php, which returns the latest url. This URl is then inserted into the HTMl replacing the appropriate image src.
After 5 seconds, I want the process to repeat, and for the image to update. However, I don't want the image to be swapped until it has finished loading, and I want to avoid a white space appearing before the new image loads.
At the moment I have the following jQuery, which simply loads the return value of image_feed.php directly into a div called #image1. image_feed.php is correctly formatted to provide a html image tag.
$(document).ready(function(){
var $container = $("#image1");
$container.load('image_feed.php?CAMERA_URI=<?=$camera_uri;?>')
var refreshId = setInterval(function()
{
$container.load('image_feed.php?CAMERA_URI=<?=$camera_uri;?>');
}, 5000);
});
This works, but there is a problem. I get a white space the size of the image in IE and Firefox every time the image refreshes, because the image takes a while to download.
I know what I need to is for image_feed.php to return the plain URL to the image. I then use some jQuery to request this URL, pre-load it and then swap it with the existing image.
However, I'm still struggling to get anywhere. Could someone be so kind as to give me some pointers / help?
$(document).ready(function() {
var $img = $('#image1');
setInterval(function() {
$.get('image_feed.php?CAMERA_URI=<?=$camera_uri;?>', function(data) {
var $loader = $(document.createElement('img'));
$loader.one('load', function() {
$img.attr('src', $loader.attr('src'));
});
$loader.attr('src', data);
if($loader.complete) {
$loader.trigger('load');
}
});
}, 5000);
});
Untested. Code above should load the new image in the background and then set the src attribute of the old image on load.
The event handler for load will be executed only once. The .complete check is necessary for browsers that may have cached the image to be loaded. In such cases, these browsers may or may not trigger the load event.
You can. When you want to reload something, you can just append a search query, so that it refreshes the source.
For Eg., when there is a frequently changing image (say captcha) and you wanna load it again, without refreshing the browser, you can do this way:
Initial Code:
<img src="captcha.png" alt="captcha" />
Refreshed Code:
<img src="captcha.png?1" alt="captcha" />
The script used here would be just:
var d = new Date();
$('img').attr('src', $('img').attr('src') + '?_=' + d.getMilliseconds());
Hope this helps! :)
Consider, if you have to fetch the URL again from the server, for a new image URL, you can do this way:
$.ajax({
url: 'getnewimageurl.php',
success: function(data) {
$('img').attr('src', data);
}
});
The server should return only a new image name in it. For eg., the PHP code should be this way:
<?php
$images = array("jifhdfg", "jklduou", "yuerkgh", "uirthjk", "xcjhrii");
die($images[date('u') % count($images)] . ".png"); // Get the random milliseconds mod by length of images.
?>
I suggest you use jQuery 'onImagesLoad' Plugin
This provides you with a callback when an image has finished loading.
When you receive new image URL from server, you create a new <img object with src="new_url_from_server" and attach 'onImagesLoad' callback to it. When your callback is called, your image has finished downloading.
Now you can just replace the 'src' attribute of old img object with new_url_from_server.
Since new image is already avaiable in cache, it will not be downloaded again and will be immediately displayed!
Aletrnatively, you can hide the old image and add this new image to DOM (not required if above works correctly)
Some bare bones sample could be like this:
<!DOCTYPE html>
<html>
<body>
<img id='bla' src="10.jpg" />
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.onImagesLoad.js"></script>
<script type="text/javascript">
$(function(){
var img = $('<div><img src="http://myserverbla/images/verybig.jpg"></img></div>');
img.onImagesLoad({
all : allImgsLoaded
});
function allImgsLoaded($selector){
var allLoaded = ""; //build a string of all items within the selector
$selector.each(function(){
$('#bla').attr('src','http://myserverbla/images/verybig.jpg');
})
}
});
</script>
</body>
</html>
I am using the following script to display big images on mouse over the small images (example photo attached in the last). I want to show the 'loading' image (like this) while the big image is being downloaded from the server. How can this be achieved?
Note: I have asked a similar question here but I was not successful in applying the append function to the following code. Please help.
<script type="text/javascript">
function showIt(imgsrc)
{
var holder = document.getElementById('imageshow');
var newpic= new Image();
newpic.src=imgsrc;
holder.src=imgsrc;
holder.width = newpic.width;
holder.height=newpic.height;
}
</script>
<body>
/***on hover, xyz.jpg will be replaced by bigA.jpg and so on***/
<img src="smallA.jpg" onMouseOver="showIt('bigA.jpg')"/>
<img src="smallB.jpg" onMouseOver="showIt('bigB.jpg')"/>
<img src="xyz.jpg" id="imageshow" />
</body>
Images have a load event. As long as you set the load handler before the image.src is set, you should get notified when the image has successfully loaded or encounters some kind of error in loading. I do that very thing in a slideshow that I wrote so I know when the next image is ready for display and I display a wait cursor (animated gif like you're wanting) if the image has been delayed more than one second beyond it's appointed display time so the user knows what's going on.
In general, you can do something like this:
function loadImage(url, successHandler, errorHandler) {
var myImg = new Image();
myImg.onload = myLoadHandler; // universally supported
myImg.onabort = myErrorHandler; // only supported in some browsers, but no harm in listening for it
myImg.onerror = myErrorHandler;
myImg.src = url;
function myLoadHandler() {
successHandler(myImg, url);
}
function myErrorHandler() {
if (errorHandler) {
errorHandler(url);
}
}
}
Using code like this, you can display the wait cursor when you initiate the image load and hide it when the successHandler gets called.
If there were any other listeners to these events, then you should use addEventListener or attachEvent instead of onload, onabort, onerror, but if there's only one listener, you can go either way.
If the desired images are known in advance, then it's sometimes a better user experience (less waiting) to preload images that may be used later. This gets them into the browser's memory cache so they will appear instantly when needed. One can preload images either in HTML or in JS. In HTML, just insert tags into the web page for all the desired images (but hide them with CSS). In JS, just create an image array and create the image objects:
// image URLs to preload
var preloadImageURLs = [
"http://photos.smugmug.com/935492456_5tur7-M.jpg",
"http://photos.smugmug.com/835492456_968nf-M.jpg",
"http://photos.smugmug.com/735492456_3kg86-M.jpg",
];
var preloads = []; // storage for preloaded images
function preloadImages() {
var img, i;
for (i = 0; i < preloadImageURLs.length; i++) {
img = new Image();
img.src = preloadImageURLs[i];
preloads.push(img);
}
}
This will cause all the images in the preloadImageURLs array to be preloaded and available instantly later on in the life of the web page, thus preventing any user delays while waiting for images to be loaded. Obviously, there's a short amount of time for the preloaded images to actually get loaded, but for smallish images that usually happens before the user interacts with the web page so it makes for a faster feel to dynamic parts of the web page that use images.
<img id=access src=loading.gif>
<script>
window.onload=function(){
document.getElementById('access').src='access.jpg';
}
</script>
Hope this helps.
in some pages i see when you arrive at the end of the page the page automatic loads new data. For example, some blogs when you get to the end of the page (that only loads 10 articles when you get there), the page load 10 articles more without pressing anything, so the questions will be, How do i execute/triger a php/javascript commands when something is displaying or the user gets to a particular position of the page? (USING A LOADER IMAGE OF COURSE)
--edit--
IMPORTANT: Please i dont need a triger by scroll, i need to triger from a display object, like when some image is in focus. Thanks!
Here is some code that runs on .scroll() and calculates how far from the bottom the current scroll is ..
http://jsfiddle.net/hRSE8/ (in this example, i add manually some text to showcase the effect of adding content and the scroll system adjusting to it)
At a specified distance you can load content with .ajax()
in short
$(window).scroll(function(){
var $this = $(this);
var $body = $('body');
var distance = $body.outerHeight() - $this.height() - $this.scrollTop() );
});
Update
Here is an updated example that will show when an element is in view (additional update to match specs in comment)
Demo
<script type="text/javascript">
$(document).ready(function(){
$(window).scroll(function(){
var $window = $(window);
var visibleTop = $window.scrollTop();
var visibleBottom = visibleTop + $window.height();
var elementTop = $('#myloader').offset().top;
if ( elementTop > visibleTop && elementTop < visibleBottom)
{
// loader in view
// so we remove the loader from the DOM
$('#myloader').remove();
// and run the code ..
$('#tweetsFeed').jTweetsAnywhere(
{ searchParams: ['ors=patanemo+bocaina+cuyagua+todasana+parguito+%23surfVE&lang=es&geocode=8,-66,1000km'],
count: 6 });
}
});
});
</script>
And you need to put in your page the loader with <img src="loader.gif" id="myloader" />
If you're using the jQuery framework, have a look at infinite scroll:
http://www.infinite-scroll.com/infinite-scroll-jquery-plugin/
I have never had to do this before but how I would do it is like this:
I would calculate the scroll position of the page using:
$(window).scrollTop();
Then I would find the scroll position an element on the page:
$(element selector).scrollTop()
Once the first number is bigger than the second number (plus maybe a buffer) then go ahead and make your ajax call to load whatever content you want.
This is all theoretical as I have never done but it seems logical. Anyone feel free to correct me where I might be wrong.
EDIT: You could also use the answer from this post:
Check if element is visible after scrolling
to see if an element is visible on the screen and then load at that time.
Though either of these solutions would require you to add an event handler for the scroll event.