function ereja(){
var newscrollHeight2 = $("#messages")[0].scrollHeight;
return newscrollHeight2;
}
var newscrollHeight = ereja();
var oldscrollHeight = $("#messages")[0].scrollHeight;
function merrmesazhet(){
$('#messages').load(
"nxirr_mesazhet.php?room=<?php echo urlencode($dhoma24); ?>"
);
setTimeout(ereja, 1000);
if( newscrollHeight != oldscrollHeight ){
$("#messages").scrollTop($("#messages")[0].scrollHeight);
}
}
What's wrong with this code? Why it doesn't work? I am trying to scroll to bottom of the div when a user writtes a new message. Any idea?
Assuming you are actually calling merrmesazhet() and that you are testing on IE>=8 as lower versions don't support scrollHeight. Then your main issue is the use of setTimeout which is essentially calling ereja every second and doing nothing.
Indeed you do not even need the JS timer - you are using jQuery which supports a callback in it's load function (which executes once on a successful load rather than repeatedly). Your if-statement in it's current form will always evaluate to false as it isn't within the function executed on the timer anyway.
Something like this may work for you:
var oldscrollHeight = $("#messages")[0].scrollHeight;
function merrmesazhet(){
$('#messages').load(
'nxirr_mesazhet.php?room=<?php echo urlencode($dhoma24); ?>',
function(){
var newscrollHeight = $("#messages")[0].scrollHeight;
if( newscrollHeight != oldscrollHeight ){
$("#messages").scrollTop($("#messages")[0].scrollHeight);
}
}
);
}
jsFiddle
Related
I have the following script. It works fine if I reload the page but I would prefer to make it work with just reloading the div but it seems that innerHTML.indexOf doesn't pick up on changes in a div without reloading the whole page which looks a bit ugly. How can I check for the string in the logs div without using location.reload()?
<div id="logs"><?php echo nl2br( file_get_contents('/path/myfile') ); ?></div>
<script>
var myVar = setInterval(myTimer, 2000);
function myTimer() {
$("#logs").load(window.location.href + " #logs" );
location.reload();
}
if (document.getElementById("logs").innerHTML.indexOf("thisistheend") != -1) {
clearInterval(myVar);
}
</script>
edit: I also tried putting the conditional inside the myTimer function but that did not work.
You should declare if statement inside of myTimer. Otherwise, the if statement will only be executed once on the first render.
var myVar = setInterval(myTimer, 2000);
function myTimer() {
$("#logs").load(window.location.href + " #logs" );
if (document.getElementById("logs").innerHTML.indexOf("thisistheend") != -1) {
clearInterval(myVar);
}
}
Here's the problem. I'm making a callback to the server that receives an MVC partial page. It's been working great, it calls the success function and all that. However, I'm calling a function after which iterates through specific elements:
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(...)
Inside this, I'm checking for a specific attribute (custom one using data-) which is also working great; however; the iterator never finishes. No error messages are given, the program doesn't hold up. It just quits.
Here's the function with the iterator
function HideShow() {
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(function () {
if (IsDataYesNoHide(this)) {
$(this).collapse("show");
}
else
$(this).collapse("hide");
});
alert("test");
}
Here's the function called in that, "IsDataYesNoHide":
function IsDataYesNoHide(element) {
var $element = $(element);
var datayesnohide = $element.attr("data-yes-no-hide");
if (datayesnohide !== undefined) {
var array = datayesnohide.split(";");
var returnAnswer = true;
for (var i in array) {
var answer = array[i].split("=")[1];
returnAnswer = returnAnswer && (answer.toLowerCase() === "true");
}
return returnAnswer;
}
else {
return false;
}
}
This is the way the attribute appears
data-yes-no-hide="pKanban_Val=true;pTwoBoxSystem_Val=true;"
EDIT: Per request, here is the jquery $.post
$.post(path + conPath + '/GrabDetails', $.param({ data: dataArr }, true), function (data) {
ToggleLoader(false); //Page load finished so the spinner should stop
if (data !== "") { //if we got anything back of if there wasn't a ghost record
$container.find(".container").first().append(data); //add the content
var $changes = $("#Changes"); //grab the changes
var $details = $("#details"); //grab the current
SplitPage($container, $details, $changes); //Just CSS changes
MoveApproveReject($changes); //Moves buttons to the left of the screen
MarkAsDifferent($changes, $details) //Adds the data- attribute and colors differences
}
else {
$(".Details .modal-content").removeClass("extra-wide"); //Normal page
$(".Details input[type=radio]").each(function () {
CheckOptionalFields(this);
});
}
HideShow(); //Hide or show fields by business logic
});
For a while, I thought the jquery collapse was breaking, but putting the simple alert('test') showed me what was happening. It just was never finishing.
Are there specific lengths of time a callback function can be called from a jquery postback? I'm loading everything in modal views which would indicate "oh maybe jquery is included twice", but I've already had that problem for other things and have made sure that it only ever includes once. As in the include is only once in the entire app and the layout is only applied to the main page.
I'm open to any possibilities.
Thanks!
~Brandon
Found the problem. I had a variable that was sometimes being set as undefined cause it to silently crash. I have no idea why there was no error message.
I have a plugin that tells me if an element is visible in the viewport with $('#element').visible() (set to true when visible).
Now I want to create a function that I scroll down a page and load new content with ajax. I have this so far:
window.onscroll = function() {
console.log($('#ele').visible());
if ($('#ele').visible()) {
//ajax call comes here
}
};
As soon as I see the element my log shows true:
I don't have problems implementing the ajax-request now, but shouldn't I block this function to occur only once? How could I prevent that a new element that already has been loaded to load again (prevent using ajax again)?
I thought of using a boolean-variable, but my problem is that I don't know how to implement that because if I set a variable, how would the browser know it's value? Because on every move of my mousewheel it cant remember what that variable's value was?
EDIT:
I tried the code of Ismail and it never reaches the ajax call (alert won't show).
window.onscroll = function() {
var ajaxExecuted = false;
var ele = $('#load_more').visible();
console.log(ele);
return function() {
if (ajaxExecuted) return;
if (ele) {
alert("OK");
var ajaxArray;
ajaxArray = { page: 2 }
ajaxLoadContent(ajaxArray, "load_more", "ajax_load");
ajaxExecuted = true;
}
}
};
You can use this:
window.onscroll = (function() {
var ajaxExecuted = false;
return function() {
if(ajaxExecuted) return;
if ($('#ele').visible()) {
$.ajax({...}).success(function() {
//Your code here;
ajaxExecuted = true;
});
}
}
})();
One easy solution: set a boolean to true when the element first becomes visible and set it to false when it stops being visible. Only fire the request if those states mismatch (i.e. if it's visible but the boolean is false - that means it's the first time you've seen the window. You'd then set the bool afterwards so it won't fire off anymore until it disappears and reappears again).
I need help creating a finite scroll bottom to top. Something like facebook messages.
I have checked this question but doesn't seem to work for me the way it supposed to. The problem is when I reach the top of the div and the end of the message list, it scrolls down and I can't see the the first few messages. How do I stop this from happening
And also, when new messages are prepended, the existing messages are pushed down, causing the user to lose their "viewing" place.
Here is what I have:
$(document).ready(function(){
$('#message_board').scrollTop($('#message_board')[0].scrollHeight);
});
$('#message_board').on('scroll', function() {
var scroll = $('#message_board').scrollTop();
if (scroll == 0) {
// Store eference to first message
var firstMsg = $('.bubble-left:first, .bubble-right:first');
// Prepend new message here
var content;
$.get("ajax/scripts/msg_lst.php?p=<?php echo htmlentities(isset($_GET['p']) ? $_GET['p'] : ''); ?>&f=" + ($('.bubble-left, .bubble-right').length), function(data){
content= data;
$('#message_board').prepend(content);
});
// After adding new message(s), set scroll to position of
// what was the first message
$('#message_board').scrollTop(firstMsg.offset().top);
}
});
your problem is here
$('#message_board').scrollTop(firstMsg.offset().top);
you can try this instead
$('#message_board').scrollTop(1);
or try to comment that line of code
//$('#message_board').scrollTop(firstMsg.offset().top);
but I think you should use scrollTop after prepend()
$('#message_board').prepend(content).promise().done(function(){
$(this).scrollTop(1);
});
finally .. add a specific class to the elements you want to prepend it and scrollTop the div to last element with this class name and after prepend() use removeClass() to remove this class again
$('#message_board').on('scroll', function() {
var scroll = $('#message_board').scrollTop();
if (scroll == 0) {
$(this).prepend(content).promise().done(function(){
$(this).scrollTop($('.newAppend:last').offset().top);
$('.newAppend').removeClass('newAppend');
});
}
});
Demo here
Note: wrap all your code inside $(document).ready(function(){// all of
your code here });
Make sure to scroll after the message has been prepended.
The $.get accepts a callback which is executed once you get a response from the server.
You should move .scrollTop there as well, as you want to execute that function after you've prepended the content, inside the callback. As everything outside the callback will usually be executed before that callback.
Something like this:
$(document).ready(function(){
$('#message_board').scrollTop($('#message_board')[0].scrollHeight);
});
$('#message_board').on('scroll', function() {
var scroll = $('#message_board').scrollTop();
if (scroll == 0) {
// Store eference to first message
var firstMsg = $('.bubble-left:first, .bubble-right:first');
// Prepend new message here
var content;
$.get("ajax/scripts/msg_lst.php?p=<?php echo htmlentities(isset($_GET['p']) ? $_GET['p'] : ''); ?>&f=" + ($('.bubble-left, .bubble-right').length), function(data){
content= data;
$('#message_board').prepend(content);
// After adding new message(s), set scroll to position of
// what was the first message
$('#message_board').scrollTop(firstMsg.offset().top);
});
}
});
So, I finally figured it out. Something was stopping the $('#message_board').scrollTop(firstMsg.offset().top-curOffset); event. I tried .unbind and .off, it never work. So what I did is added that line to the success attribute of ajax.
$(document).ready(function(){
$('#message_board').scrollTop($('#message_board')[0].scrollHeight);
});
$('#message_board').on('scroll', function() {
var scroll = $('#message_board').scrollTop();
if (scroll < 1) {
// Store eference to first message
var firstMsg = $('.bubble-left:first, .bubble-right:first');
var curOffset = firstMsg.offset().top - $('#message_board').scrollTop();
// Prepend new message here
var content;
$.get("ajax/scripts/msg_lst.php?p=<?php echo htmlentities(isset($_GET['p']) ? $_GET['p'] : ''); ?>&f=" + ($('.bubble-left, .bubble-right').length), function(data){
content= data;
$('#message_board').prepend(content);
$('#message_board').scrollTop(firstMsg.offset().top-curOffset);// <<---- Had to add this event to the ajax success function
});
}
});
I'm using coda slider for a website and unfortunately after the window is minimized, the content slider plays super fast. I know it has something to do with Set time out, but I could not achieve perfect result yet. Any help on this will be appreciated. My script code is:
var theInt = null;
var $crosslink, $navthumb;
var curclicked = 0;
theInterval = function(cur){
clearInterval(theInt);
if( typeof cur != 'undefined' )
curclicked = cur;
$crosslink.removeClass("active-thumb");
$navthumb.eq(curclicked).parent().addClass("active-thumb");
$(".stripNav ul li a").eq(curclicked).trigger('click');
theInt = setInterval(function(){
$crosslink.removeClass("active-thumb");
$navthumb.eq(curclicked).parent().addClass("active-thumb");
$(".stripNav ul li a").eq(curclicked).trigger('click');
curclicked++;
if( 4 == curclicked )
curclicked = 0;
}, 8000);
setTimeout( nextCycle, 2000 );
};
$(function(){
$("#main-photo-slider").codaSlider();
$navthumb = $(".nav-thumb");
$crosslink = $(".cross-link");
$navthumb
.click(function() {
var $this = $(this);
theInterval($this.parent().attr('href').slice(1) - 1);
return false;
});
theInterval();
});
I always run into problems with setTimeout. My method is to do something like the following:
var timer = setTimeout( function(){nextCycle();}, 2000 );
Looks like the library is colliding with another library I'm using. I used another function which when the browser window is minimized or tab is changed on coming back to the page to refresh the page, in this case, all the scripts will reload and the slider will start from beginning. Though it is better if I could do it without refreshing the whole page and only by refreshing the scripts, or by playing the slider from the beginning somehow, but unfortunately my javascript knowledge is not much! here is the code:
$(window).blur(function() {
//Do Nothing//
});
$(window).focus(function() {
//This refreshes the whole page //
location.reload();
});