So, I have this script that allows the infinite scrolling:
$(document).ready(function() {
function last_id_funtion() {
var ID = $(".elemento:last").attr("id");
$.post("2HB.php?action=get&id=" + ID,
function(data) {
if (data != "") {
var $boxes = $(data);
//$(".elemento:last").after(data);
$("#corpo").append($boxes).masonry('appended', $boxes, 'reloadItems');
}
});
};
$(window).scroll(function() {
if ($(window).scrollTop() == $(document).height() - $(window).height()) {
last_id_funtion();
}
});
It is based on 2 queries, one for the first 10 results and another for the rest.
The problem is that Masonry overlaps the images until a page refresh is done... When the images are stored in the cache, it works perfectly, but not otherwise...
How can I fix this?
Try wrapping your masonry call in .imagesLoaded()
$("#corpo").imagesLoaded(function(){
$("#corpo").append($boxes).masonry('appended', $boxes, 'reloadItems');
});
EDIT
According to the Masonry Appendix "imagesLoaded works by triggering a callback after all child images have been loaded.". So if you run you trigger Masonry inside this callback everything it needs to do it's thing should be already loaded.
Related
Hi I am writing a chat website and I have a problem with the div containing the messages. In the CSS the div containing the messages has overflow: auto; to allow scroll bars. Now the problem is when ajax is fetching the messages through a PHP script that fetches the messages from the database, you cannot scroll up. The AJAX refreshMessages() function is set to update every second using window.setInterval(refreshMessages(), 1000);. This is what I want but when I scroll up to see previous messages, the scroll bar hits straight back down to the end of the chat due to the AJAX fetch function.
Any ideas of what the issue is?
AJAX Code:
//Fetch All Messages
var refreshMessages = function() {
$.ajax({
url: 'includes/messages.inc.php',
type: 'GET',
dataType: 'html'
})
.done(function( data ) {
$('#messages').html( data );
$('#messages').stop().animate({
scrollTop: $("#messages")[0].scrollHeight
}, 800);
})
.fail(function() {
$('#messages').prepend('Error retrieving new messages..');
});
}
EDIT:
I'm using this code but it isn't quite working, it pauses the function but then the function doesn't restart when the scroll bar goes back to the bottom. Help?
//Check If Last Message Is In Focus
var restarted = 0;
var checkFocus = function() {
var container = $('.messages');
var height = container.height();
var scrollHeight = container[0].scrollHeight;
var st = container.scrollTop();
var sum = scrollHeight - height - 32;
if(st >= sum) {
console.log('focused'); //Testing Purposes
if(restarted = 0) {
window.setTimeout(refreshMessages(), 2000);
restarted = 1;
}
} else {
window.clearInterval(refreshMessages());
restarted = 0;
}
}
You need to replace the checkFocus() function to return true or false and then get AJAX to check if it need's to send the scroll bar down after adding in the new message or not. Replace the checkFocus() function with this:
//Check If Last Message Is In Focus
var checkFocus = function() {
var container = $('.messages');
var height = container.height();
var scrollHeight = container[0].scrollHeight;
var st = container.scrollTop();
var sum = scrollHeight - height - 32;
if(st >= sum) {
return true;
} else {
return false;
}
}
Change AJAX .done to this:
.done(function( data ) {
if(checkFocus()) {
$('#messages').html( data );
scrollDownChat();
} else {
$('#messages').html( data );
}
})
To answer your question of what's happening: the interval runs every second, and when you have scrolled up during that waiting period, it'll run again and move you down 800 pixels. You can remove this from your function to do this.
Since you're using overflow: auto, your chat box will grow and create a scrollbar when necessary. Have you tried removing the scroll functionality? Does it not move to the latest text at the bottom?
If not, then you can check if user has scrolled or not, when user has scrolled, you should not scroll using jQuery. To do this, you can add a variable outside this function which gets updated if user scrolls at all.
Detecting between user scrolling and your javascript scrolling is not easy, so you can use which message(s) is(are) being viewed. If the message in focus is the last message, you should keep scrolling to the bottom, but when the last message goes out of view, you can assume user has scrolled.
See this question for more info on detecting scroll: Detect whether scroll event was created by user
I have a php script that I call that returns html in a way that it can be directly inserted into a container or the body and just work (E.X. '<image id="trolleyLogoEdge" class="pictureFrame party" src="tipsyTrixy.png" >'). After appending this text to a div the selector $('#pictureFrame > img:first') won't work. I'm not using event handlers or anything so I don't know why I'm having an issue. My code worked fine when I just had the image tags in the div without any manipulation so I'm assuming it must be a selector issue. I have tested my php output and it is exactly matching the html that was in the div before I decided to dynamically populate the div.
var classType = '';
var classTypePrev = '';
var width = $(window).width();
var height = $(window).height();
var size = (height + width)/2;
var time = 0;
$( document ).ready(function()
{
$.post( "pictureDirectory.php", function( data )
{
$('#picureFrame').append(data);
startSlideshow($('#pictureFrame > img:first'));
});
});
window.onresize = function()
{
width = $(window).width();
};
function startSlideshow(myobj)
{
classType = $(myobj).attr('class').split(' ')[1];
if(classTypePrev != classType)
{
$('.picDescription').animate({'opacity': "0"},{duration: 2000,complete: function() {}});
$('.picDescription.' + classType).animate({'opacity': "1"},{duration: 3000,complete: function() {}});
}
classTypePrev = classType;
myobj.animate({left: "-=" + ((width/2)+ ($(myobj).width()/2) - 150), opacity: '1'},{
duration: 5000,
'easing': 'easeInOutCubic',
complete: function() {}}).delay(2000).animate({left: "-=" + ((width/2)+ ($(myobj).width()/2) + 150), opacity: '0'},{
duration: 5000,
'easing': 'easeInOutCubic',
complete: function()
{
$(myobj).css("left", "100%");
}
});
setTimeout(function()
{
var next = $(myobj).next();
if (!next.length)
{
next = myobj.siblings().first();
}
startSlideshow(next)},9000);
}
Your code that appends the data to the frame has a typo in the ID selector.
$.post( "pictureDirectory.php", function( data )
{
$('#picureFrame').append(data);
^^here
startSlideshow($('#pictureFrame > img:first'));
});
It should probably be
$('#pictureFrame').append(data);
.find() gets the descendants of each element in the current set of matched elements.
> selects all direct child elements specified by "child" of elements specified by "parent".
Try:
startSlideshow($("#pictureFrame").find("img:first"));
If img is not direct child of #pictureFrame, .find() should work.
You should know the difference between
Delegated Event
Direct Event
check this for the difference between direct and delegated events.
If we were to click our newly added item, nothing would happen. This is because of the directly bound event handler that we attached previously. Direct events are only attached to elements at the time the .on() method is called. In this case, since our new anchor did not exist when .on() was called, it does not get the event handler.
check this link to official JQuery Document for further clarification.
I need to be able to replace a php file with another php file based on screen resolution. This is what I have so far:
<script type="text/javascript">
function adjustStyle(width) {
width = parseInt(width);
if (width = 1920) {
$('book.php').replaceWith('book2.php');
}
}
$(function() {
adjustStyle($(this).width());
$(window).resize(function() {
adjustStyle($(this).width());
});
});
</script>
which obviously isn't working-- any ideas? Thank you in advance for any help received.
UPDATE
Is this at all close (to replace the book.php line)?
{ $("a[href*='book.php']").replaceWith('href', 'book2.php'); };
Second Update to reflect input gathered here
function adjustStyle(width) {
width = parseInt(width);
if (width == 1920) {
$('#bookinfo').replaceWith(['book2.php']);
$.ajax({
url: "book2.php",
}).success(function ( data ) {
$('#bookinfo').replaceWith(data);
});
$(function() {
adjustStyle($(this).width());
$(window).resize(function() {
adjustStyle($(this).width());
});
});
}
}
I have not seen the use of replaceWith in the context you put it in. Interpreting that you want to exchange the content, you may want to do so my using the load() function of jQuery.
if(width == 1920){
$("#myDiv").load("book1.php");
} else {
$("#myDiv").load("book2.php");
}
Clicking on the button replaces the content of the div to book2.php.
The first problem is I don't think that you are using the correct selectors. If you have the following container:
<div id="bookContainer">Contents of book1.php</div>
The code to replace the contents of that container should be
$('#bookContainer').replaceWith([contents of book2.php]);
In order to get [contents of book2.php] you will need to pull it in by ajax using the following code I have also included the line above so that the data from book2.php will be placed into the container:
$.ajax({
url: "http://yoururl.com/book2.php",
}).success(function ( data ) {
$('#bookContainer').replaceWith(data);
});.
I haven't tested this so there might be an issue but this is the concept you need to accomplish this.
First off... using a conditional with a single = (equal sign) will cause the condition to always be true while setting the value of variable your checking to the value your checking against.
Your condition should look like the following...
if (width == 1920) { // do something }
Second, please refer to the jQuery documentation for how to replace the entire tag with a jquery object using replaceWith()... http://api.jquery.com/replaceWith/
I would use a shorthand POST with http://api.jquery.com/jQuery.post/ since you don't have the object loaded yet...
In short, my code would look like the following using $.post instead of $.ajax assuming I had a tag with the id of "book" that originally has the contents of book.php and I wanted to replace it with the contents of book2.php...
HTML
<div id="book">*Contents of book.php*</div>
jQuery
function onResize(width) {
if (parseInt(width) >= 1920) {
$.post('book2.php',function(html){
$('#book').html(html).width(width);
});
}
else {
$.post('book.php',function(html){
$('#book').html(html).width(width);
});
}
}
Hope this helps.
I'm using Twitter Bootstrap's Popover feature on a sidebar. The sidebar is fetched and reloads the content every 30 seconds. I'm suing XMLHttpRequest to reload the content of the sidebar by fetching a file called stats.php.
The following code is the "refresh" code which resides in the header of the page.
function onIndexLoad()
{
setInterval(onTimerCallback, 30000);
}
function onTimerCallback()
{
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (request.readyState == 4 && request.status == 200)
{
document.getElementById("stats").style.opacity = 0;
setTimeout(function() {
document.getElementById("stats").innerHTML = request.responseText;
document.getElementById("stats").style.opacity = 100;
}, 1000);
}
}
request.open("GET", "stats.php", true);
request.send();
}
The above code works flawlessly, however, after it reloads the #stats div, the popover no long does what it's supposed to - popup.
The popover code is in the stats.php in a foreach() loop because I have multiple popover scripts I need because there are multiple popovers on the sidebar.
Here's my popover code:
$(document).ready(function() {
$('a[rel=popover_$id]').popover({
placement:'right',
title:'$title',
content: $('#popover_content_$id').html()
});
});
The $id and $title are dynamic as they are pulled from the foreach() loop.
How can I fix it so after the div reloads, the popover function will reinitialize?
$("a[rel=popover_controller_$cid]").on({
mouseenter: function () {
$('a[rel=popover_$id]').popover({
placement:'right',
title:'$title',
content: $('#popover_content_$id').html()
});
}
});
I have also tried:
$("a[rel=popover_controller_$cid]").on("mouseover", function () {
$('a[rel=popover_$id]').popover({
placement:'right',
title:'$title',
content: $('#popover_content_$id').html()
});
});
.live is depreciated. use .on delegation
try something like this:
$('#stats').on("mouseenter", "a[rel=popover_controller_$cid]",function () {
$('a[rel=popover_$id]').popover({
placement:'right',
title:'$title',
content: $('#popover_content_$id').html()
});
});
This delegates the mouseenter event from #stats to a[rel=popover_controller_$cid] and because the event is delegated it will still fire when #stats contents are replaced.
be careful - you will keep initializing popover on each mouseover. that might be bad.
while you are at it - you should use jquery's ajax instead of native xhr. its easier and more cross browser.
$.get('stats.php', function(d){
$('#stats').html(d);
};
--
setInterval(function(){
$.get('stats.php', function(data) {
$('#stats').html(data);
});
}, 30000);
I have a pinterest style site and made a jquery script that spaces the cubes evenly no matter how big the browser is. For some reason on page load it has some overlapping cubes which didn't exist before. I talked with the guy that helped me make it and he said it's probly because of the code before the code that creates the blocks and positions them. It crashes the javascript.
I think it's because of the $(window).scroll ajax loading code but I can't seem to pinpoint the problem. I tried moving positionBlocks(); around and nothing changes. If you load the page in your browser and then change your browser size then it positions them correctly but obviously I want it to look right when the user first gets there.
function setupBlocks() {
windowWidth = $(window).width();
blocks = [];
// Calculate the margin so the blocks are evenly spaced within the window
colCount = Math.floor(windowWidth/(colWidth+margin*2));
spaceLeft = (windowWidth - ((colWidth*colCount)+margin*2)) / 2;
spaceLeft -= margin;
for(var i=0;i<colCount;i++){
blocks.push(margin);
}
positionBlocks();
}
function positionBlocks() {
$('.block').each(function(i){
var min = Array.min(blocks);
var index = $.inArray(min, blocks);
var leftPos = margin+(index*(colWidth+margin));
$(this).css({
'left':(leftPos+spaceLeft)+'px',
'top':min+'px'
});
blocks[index] = min+$(this).outerHeight()+margin;
});
}
// Function to get the Min value in Array
Array.min = function(array) {
return Math.min.apply(Math, array);
};
var curlimit=<?php echo $curlimit; ?>;
var totalnum=<?php echo $num_rws; ?>;
var perpage=<?Php echo $perpage ?>;
var working_already=false;
$(document).ready(function() {
//($(window).scrollTop() + $(window).height() )> $(document).height()*0.8
// old ($(window).scrollTop() + $(window).height() == $(document).height())
$(window).resize(setupBlocks);
$(window).scroll(function() {
if(($(window).scrollTop() + $(window).height() )> $(document).height()*0.90 && totalnum>0 && working_already==false ) {
} else return false;
working_already=true;
$("div#loading_bar").fadeIn("slow");
curlimit=curlimit+perpage;
$("div#loading_data_location").html("");
$.get('get_cubes.php?page=<?php echo $_GET['page'] ?>&curlimit='+curlimit, function(response) {
$("div#loading_data_location").html(response);
$("div#ColumnContainer").append($("div#loading_data_location").html());
$("a#bigpic").fancybox({
'onComplete' : imageLoadComplete,
'onClosed' : imageClosed,
'type': 'ajax' });
if ($("div#loading_data_location").text()=="")
totalnum=0;
else
totalnum=<?php echo $num_rws; ?>;
$('.like:not(.liked)').click(like_box);
$('.save:not(.saved)').click(save_box);
$('.follow:not(.following)').click(follow);
$("div#loading_bar").fadeOut("fast");
$("div#loading_data_location").html('');
setupBlocks();
working_already=false;
});
});
I had to add this to the end of my script:
<script language="javascript">
$(window).bind("load", function() {
setupBlocks();
});
</script>
and then this to the end of the on scroll ajax load. Sometimes jquery just needs a little kick in the face haha:
setTimeout(function(){setupBlocks();},100);