How to load more data on scrolling [duplicate] - javascript

This question already has answers here:
Load ajax when scroll reaches 80%
(2 answers)
Closed 8 years ago.
I have a container like this:
<div class="row row-sm padder-lg ">
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2">
...
</div></div>
The content is generated by this loop on a php page:
<?php
foreach ($top->feed->entry as $key => $value)
{
$value->title->label = str_ireplace( "- ".$value->artist->label, "", $value->title->label);
if($key >= $this->config->item("items_top"))
return false;
$image = $value->image[2]->label;
if($image == '')
$image = base_url()."assets/images/no-cover.png";
$image = str_ireplace("170x170", "200x200", $image);
?>
"items_top" is the number of array for max. images to display, how could I make a load more on scrolling?
So when user scroll at the bottom of the page are automatically loaded new contents
UPDATE
Ok I need to use Ajax but how to do? Is it correct to use this code in my php?
<script>
$(document).scroll(function(e){
// grab the scroll amount and the window height
var scrollAmount = $(window).scrollTop();
var documentHeight = $(document).height();
// calculate the percentage the user has scrolled down the page
var scrollPercent = (scrollAmount / documentHeight) * 100;
if(scrollPercent > 50) {
// run a function called doSomething
doSomething();
}
function doSomething() {
// do something when a user gets 50% of the way down my page
}
});
</script>

Short answer: You can't, at least not with PHP.
Since PHP is processed on the server side before the page is given to the client, there is no way to edit a page with PHP after it is received. That is the job of JavaScript or rather AJAX.
If you move your PHP script onto a separate page (php only preferably) that you include in your website, you can make an AJAX call to replace a part of the HTML code with the content returned by the script after the user scrolls.
This link might help you with that:
Loading DIV content via ajax as HTML

Related

div content on scrolled bottom html javascript

i want to ask about div content scroll listener (not page).
so I have an html code where the appearance of the web design resembles a native application. what I want to do is how do I detect if the user has scrolled down the content div? not a page because my web page for him is only silent, but the one that moves in the div. my div code is something like this
<div class="product-list-item">
//product card
//product card
</div>
and when i scroll like this
I want to see other products using ajax when it reaches the bottom of the div, for now I
still using the manual button to load other products.
I've used this code but it's not working.
<script>
$(window).scroll(function() {
if($(window).scrollTop() == $(document).height() - $(window).height()) {
// ajax call get data from server and append to the div
}
});
</script>
does anyone have a solution for this? Thank you in advance.
Assuming you have this:
<div class="product-list-item" id="target">
//product card
//product card
</div>
You can use this script to check if you reached your target div:
<script>
$(window).scroll(function() {
if ($(this).scrollTop()+$(this).height() >= $('#target').position().top) {
console.log('Target Reached');
}
});
</script>
You can use this approach to only execute the code once , once it has reached the target div
<script>
let isReached = false;
$(window).scroll(function() {
if ($(this).scrollTop()+$(this).height() >= $('#ftr').position().top && isReached == false) {
isReached = true;
//ajax call
}
});
</script>

jQuery .load to bring data is working only the first time

I am trying to load more data from a database with a jQuery .load, and it works perfectly, but after the first load, it ist'n bringing more data.
Also, for bringing the first content, which is brought on the first page load, i use a PHP foreach() loop, like this as a basic example:
<div class="grid-products">
<?php foreach($products as $product): ?>
<div class="grid-product">
<?php echo $product['name']; ?>
</div>
<?php endforeach; ?>
</div>
I am trying to load more data from my database on scroll, so the user don't have to click on a button. I am loading information from my database based on the method of this question, like this:
$(window).scroll(function() {
if($(window).scrollTop() == $(document).height() - $(window).height()) {
//do an ajax call
}
});
But as I don't know how to do the ajax call mentioned on the answer above I found, I decided to use a jquery .load passing also some POST method variables, which in this case would be productNewCount. First I set its value to 6, and when user reaches bottom of page, we sum plus six to its value, like this:
$(window).scroll(function() {
var productCount = 6;
if($(window).scrollTop() == $(document).height() - $(window).height()) {
productCount = productCount + 6;
$(".grid-products").load("load-products.php", {
productNewCount: productCount
});
}
});
This works great on first load, and so when this is executed, it loads on the <div class="grid-products"> the load-products.php file. Here, the variable $connection is calling my function to connect to the database, don't give too much importance to it.
This is load-products.php:
<?php
$connection = connect();
$product_new_count = $_POST['productNewCount'];
$sentence = $connection->prepare("
SELECT * FROM all_products ORDER BY date DESC LIMIT $product_new_count
");
$sentence->execute();
$products = $sentence;
?>
<?php foreach($products as $product): ?>
<div class="grid-product">
<?php echo $product['name']; ?>
</div>
<?php endforeach; ?>
In the sentence, we are calling to bring all the rows from the all_products table ordered through its date column, and limiting to bring only the rows product_new_count says, which its value is the productCount JS variable we brought on the main file, before its load.
I made sure there are still rows available to bring, so the reason why other rows arent being shown after first load isn't because there are no rows left. Also, terminal isnt showing any errors or warnings and there is also still available space to make scroll so the function can be called.
Can I bring more data through this .load method or should I use the AJAX call mentioned on the answer I found? If so how?
Every time you scroll productCount is set to 6, hence all your load request will be the same.
You can define productCount outside the event handler to increase the number of elements loaded each time.
var productCount = 6;
$(window).scroll(function() {
if($(window).scrollTop() == $(document).height() - $(window).height()) {
productCount = productCount + 6;
$(".grid-products").load("load-products.php", {
productNewCount: productCount
});
}
});
If you are trying to add to the existing content (not replace all of it) use $.post instead of load() and append the results.
load() replaces whatever is already existing inside the matching selector
$.post("load-products.php", {productNewCount: productCount}, function(html){
$(".grid-products").append(html)
})

Loading images dynamically slow, jquery, php

I am developing a website that has some photos to display, divided in albums.
Each photo's path is stored in a database.
I want to display the photos using a jquery gallery plugin. The problem is that the photos are taking forever to load, which sometimes causes the browser to crash.
I have tried lazy loading with galleria, lazyload and jpreloader, but so far the problem remains.
For the development of the site i use CodeIgniter. So far i have tried two methods for loading the photos.
1) By passing them from the controller to the view.
2) By using jquery and ajax.
Which method is better from a performance perspective?
The number of the photos isn't really big, just 17 with total size about 5mb.
If anyone could help me, i would be extremely gratefull.
you need to compress/resize your images on the server side, preferably one thumb at size of your gallery & one between 720 & 960 for the full size,
thumbs will be really lightweight, full size maybe 850kb for the 17
i give you an easy to use php class dealing with all image format :
<?php
class scratch_utils_imgresize
{
static function resize($file_path
,$new_file_path
,$img_width
,$img_height
,$scale) {
$new_width = $img_width * $scale;
$new_height = $img_height * $scale;
$new_img = #imagecreatetruecolor($new_width, $new_height);
switch (strtolower(substr(strrchr($file_path, '.'), 1))) {
case 'jpg':
case 'jpeg':
$src_img = #imagecreatefromjpeg($file_path);
$write_image = 'imagejpeg';
$image_quality = isset($options['jpeg_quality']) ?
$options['jpeg_quality'] : 75;
break;
case 'gif':
#imagecolortransparent($new_img, #imagecolorallocate($new_img, 0, 0, 0));
$src_img = #imagecreatefromgif($file_path);
$write_image = 'imagegif';
$image_quality = null;
break;
case 'png':
#imagecolortransparent($new_img, #imagecolorallocate($new_img, 0, 0, 0));
#imagealphablending($new_img, false);
#imagesavealpha($new_img, true);
$src_img = #imagecreatefrompng($file_path);
$write_image = 'imagepng';
$image_quality = isset($options['png_quality']) ?
$options['png_quality'] : 9;
break;
default:
$src_img = null;
}
$success = $src_img && #imagecopyresampled(
$new_img,
$src_img,
0, 0, 0, 0,
$new_width,
$new_height,
$img_width,
$img_height
) && $write_image($new_img, $new_file_path, $image_quality);
// Free up memory (imagedestroy does not delete files):
#imagedestroy($src_img);
#imagedestroy($new_img);
return $success;
}
}
?>
First of all, you need to define your performance bottleneck.
Is it your database query response?
Is it your PHP script?
Is it your javascript?
Is it your browser?
Is it your image server's upload speed?
If you know it's the server's upload speed, which is usually the case, then you should not output into HTML all of the images at once. This can be solved in many ways, of which I'll only cover 2...
The "long page" format
The "paginated/tabbed" format
1) Use the jQuery plugin LazyLoad properly like so:
// include jQuery and lazyload plugin
<script>
// Make sure $ is still short for jQuery (no conflict exists with other libraries)
$(function() {
$("img.lazy").lazyload();
});
</script>
<body>
<img class="lazy" data-original="img/example.jpg">
2) jQuery UI tabbed method (documentation here)...
<?php
// json_encode the albums you get from your db
$jsonEncoded = json_encode($returned_array_from_db_of_albums);
?>
<!-- include jQuery and jQuery UI -->
<script>
$(function() {
var albums = <?php echo $jsonEncoded; ?>;
// iterate through albums to find the album names and build our tab menu (expressed in HTML already below) and the associated <div>s where the images will ultimately go
// e.g. $('#album-names').html(album_names_html);
// then $('#albums').append(album_names_divs_html);
function displayAlbum (id) {
// id parameter will be the id of the <a> tag you clicked below
// fetch the images from the albums array you defined above associated with the album id
// build the <img> tags and set the associated $('div#'+id).html() to your output
}
$('#albums').tabs();
displayAlbum('first-album'); // first-album should be the id of the first album in your albums array
$('#albums ul li a').click(function() {
displayAlbum($(this).attr('id'));
});
});
</script>
<body>
<div id="albums">
<ul id="album-names">
<!-- following 2 <li>s should be generated by your javascript as explained above -->
<li>Album 1</li>
<li>Album 2</li>
</ul>
<!-- like my comment above, so should these -->
<div id="album-1"></div>
<div id="album-2"></div>
</div>
Also make sure your images are as compressed as possible as one of the other answers suggested. However, I don't recommend compressing the images every time someone hits the page, like in a PHP script. Be sure to compress the images beforehand.

Dynamic iframe height not working in chrome

im going crazy here. i found a script here that was supposedly going to work on chrome as well but i just cant get it to work
here is the script in my header
<script type="text/javascript">
function resizeFrame() {
var t=document.getElementById("Footer");
var f = document.getElementById("mainContent");
var y = f.contentWindow;
t.innerHTML = y.document.body.offsetHeight;
f.height = y.document.body.offsetHeight;
}
</script>
and the iframe
<iframe onload="resizeFrame()" id="mainContent" src="swwbookpg1.php" scrolling=auto frameborder=0
height="100%" width="100%">Working!</iframe>
<p id="Footer"> Footer</p>
it works in firefox and IE but not in chrome.
if anyone can help that would be amazing!
here it is in use: https://www.whalewatchingsydney.com.au/payment_sww/
thanks =)
Google seem to be living up to their strapline "do no evil". While Chrome is capable of dynamic iframe height adjustment Google do not make it very easy. After two days of struggling with the problem and trying tons of javascript snippets which worked perfectly in every other Browser but Chrome I finally managed to get something that would work. I will share this to hopefully save other website developers the 48 hours pain I had to go through.
Inside external SetiFrameHeight.js file which can then be added to any iframe child document with html.
<script type="text/javascript" src="SetiFrameHeigh.js"></script>
setIframeHeight.js
window.onload=setIframeHeight(window.top.document.getElementById('iFrame_ID'));
//note this code only runs serverside when using Google Chrome, very helpful
function setIframeHeight(ifrm){
var doc = ifrm.contentDocument? ifrm.contentDocument:
ifrm.contentWindow.document;
var RestHeight=ifrm.style.height; //Capture original height see why below.
ifrm.style.visibility = "hidden";
ifrm.style.height = "10px"; //Necessary to work properly in some browser eg IE
var NewHeight = getDocHeight( doc ) + 10;
if (NewHeight>20){
ifrm.style.height=NewHeight + "px";
} else { //if dom returns silly height value put back old height see above.
ifrm.style.height=RestHeight + "px";
}
ifrm.style.visibility = "visible";
}
function getDocHeight(doc) {
doc = doc || document;
var body = doc.body, html = doc.documentElement;
var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight,
html.scrollHeight, html.offsetHeight );
return height;
}
The real magic of this code snippet is the function getDocHeight which basically tries every conceivable dom combination and selects the one that gives the maximum height. I cannot take credit for this got it from http://www.christersvensson.com/html-tool/iframe.htm.
Chrome:
I found that when I create an iFrame with document.createElement and assign it a name ("myIframe"), the new iFrame does not load content when I set its location. But if I assign a url to the element's src, it worked fine. Now then, when instead I manually inserted the iframe tags in the html text (static -- as opposed to using document.createElement) it would load the document when setting its location (and also the tag's src). Strange.
Assuming you are intending to display the iframe's content directly, I wonder why? I like to use iframes but really only to dynamically load content to a container in my top window. The last part of the html loaded into the iframe includes a script that moves the output into the desired location of the top frame.
Example of a php script that loads new content via an iFrame.
// top Frame calls the php script like this:
<div id="myContainerDiv">
<p>old content - please replace me with fresh content</p>
</div>
<iframe name="hiddenFrame" style="display:none;"></iframe>
<script>
hiddenFrame.location = 'index.php?getNewContent=125';
</script>
// the following script would be at the top of index.php
<?php //
if( isset($_GET['getNewContent']) ):
echo '<div id="myIframeHtml">';
// the html that I want to load to the top frame..
echo '</div>';
?>
<script>
newContent = document.getElementById('myIframeHtml').innerHTML; // from this iFrame
topContainer = top.document.getElementById('myContainerDiv'); // in top frame
topContainer.innerHTML = newContent; // no fuss-no muss --> no encoding or parsing
</script>
<?php
exit;
endif;

Printing viewable contents of browser window

I have a website I am currently developing and the client has a very unique request. They would like the user to be able to hit a button and print the contents of the browser window. I wanted to know if anyone has implemented similar functionality or knows any strategy to develop something like this as I do not have the first clue.
Example: I have 30 images on a page but only 4 fit in the viewable area or browser window. I would like to only print the exact content of the browser window / or elements that are viewable area.
Thanks in advance,
JN
This method requires jQuery, but might be able to be rewritten in plain javascript.
With a bookmarklet app of mine I found that the popup window was the most reliable way to print dynamic content and allowed the user to see the content before printing it. I also found that reducing the font size allowed fitting all the content on the page while sill be readable. You might try shrinking the images as well if that is an option. I had tried targeting media types with CSS and some jQuery print plugins but found them unreliable at best.
Here's the function I use to pass a jQuery object to be printed. I maximized the window on open and changed the title/font size. If you have more than images you'll need to clone your CSS as well, mine just happened to be stored in a variable from the bookmarklet loading.
function printElement(oElement) {
var oPopupWindow = window.open('', 'newwin', 'width=500,height=500');
oPopupWindow.moveTo(0,0);
oPopupWindow.resizeTo(screen.availWidth,screen.availHeight);
oPopupWindow.document.open();
var sHTML = '<html><head><title>TBA Enhanced User Interace</title>' +
_EUI.sCSS + '<style>img {display:none!important}table{font-size:8pt!important}</style></head><body>'
+ $('<div />').append(oElement.clone()).html() + '</body></html>';
oPopupWindow.document.write(sHTML);
oPopupWindow.document.close();
oPopupWindow.print();
oPopupWindow.close();
}
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom));
}
function printVisibleImages() {
var oImageElement = $('<div />');
$('img').each(function() {
if (isScrolledIntoView(this)) {
oImageElement.append(this);
}
});
printElement(oImageElement);
}
Using the isScrolledIntoView function from this question: Check if element is visible after scrolling, something like the code above might work with some tweaking. Call printVisibleImages(), you might need to add some CSS for padding or pass the style sheets from the main page.
You could - in the same or a new window - wrap a DIV around all of the BODYs content and restrict the display area to currently visible . If there's a root-container-DIV for example...
<body>
<div id="theWholeDocument">
... content
</div>
</body>
... it can easily be done by jQuery:
$('#theWholeDocument').wrap( function() {
// get coordinates and dimensions of visible area first
// assing to var prLeft, prTop, prWidth, prHeight
return '<div style="position:absolute;left:"+prLeft+"px; top:"+prTop+"px; width:"+prWidth+"px; height:"+prHeight+"px; overflow:hidden"/>');
}
Should result in a Document that shows nothing else than what has been visible before. Printout schould look the same, like a screenshot - with propably cropped images at the bottom.
Make a jQuery function that loads a page on the click of a button via Ajax. (sending the page name as a post parameter). In that page, you do this:
$file = file_get_contents($_POST['file']);
echo $file;
and you style accordingly.
Maybe you can play around with Javascript (take a look at how to get window dimensions and scroll positions), but I don't realize how to print only that part of the document...
Maybe this can help you: snapshot from browser with flash or javascript
I have 30 images on a page but only 4 fit in the viewable area or
browser window.
I don't think you can say with certainty that the above works in all situations.
It is quite possible that many other browsers/resolutions will produce man different configurations, including some where the images are chopped off, etc.
The better solution, I think, is to offer X number of images per printed page and style accordingly.
One of the web apps needed something similar to what you are asking for. It is an FAQ link which produced an FAQ page and the user wanted the ability to print it, if they so chose.
I did this by simply adding a button to the html:
<input type="button" value="Print" onClick='window.print();' />
<input type="button" value="Close" onClick='window.close();' />
Because I popped this into its own little browser window, I stripped off all the other controls from the parent page via:
function popFaq() {
window.open('faq.html', '',
'left=10, top=10, width=550, height=700, resizable=1, ' +
'location=0, personalbar=0, scrollbars=1, statusbar=0, toolbar=0, menubar=0');
}
... and ...
<div id='hLink'>
<a title='Click Here for (F)requently (A)sked (Q)uestions' href='' onclick='popFaq(); return false;'>FAQ</a>
</div>
Hope that helps!

Categories