jQuery scroll to bottom of div is very tempremental - javascript

I am developing an instant messaging page for my website and I consequently want the div to be scrolled to the bottom so the newest message can be seen. The page is saved as a php file and uses jQuery to do the scrolling.
The code:
$(function() {
var wtf = $('#chat');
var height = wtf[0].scrollHeight;
wtf.scrollTop(height);
});
Currently I use the following code however it is very temperamental and only works about 1 in 4 times, I have not added the webpage code as it it several hundred lines however I can if necessary. Is there a better solution which works more consistently?

Alex, I would try to load this function with
$(window).load(functiion() {
//your code here
var wtf = $('#chat');
var height = wtf[0].scrollHeight;
wtf.scrollTop(height);
}
The difference between that and document.ready is document.ready fires when the document is loaded which is before the whole page loads in some instances. It will be a slightly slower load time if you do this but your script should at least work consistently. I have faced similar troubles. Give it a try and let me know how it works for you.

Add an anchor right after the div... then when you refresh... yourpage#bottomofdiv

Related

How to display a gif of preload while loading comments facebook?

I have a javascript code customized so that when scroll down the page to where is the facebook comment box not loaded. At the time the scroll reaches the site comments are loaded and appear.
But it takes about two seconds and I would like to appear while charging a lively until comments are fully charged gif.
I tried to add but does not disappear when displaying the comments. Probably because javascript really do not know when they have been fully charged comments.
Is there any way to fix it?
function loadAPI() {
var js = document.createElement('script');
js.src = '//connect.facebook.net/en_US/sdk.js#xfbml=1&appId=73773988950&version=v2.0';
document.body.appendChild(js);
}
window.onscroll = function () {
if (document.getElementById("coments")) {
var rect = document.getElementById('coments').getBoundingClientRect();
if (rect.top < window.innerHeight) {
loadAPI();
window.onscroll = null;
}
}
Actually if dynamic content itself place a gif you know that javascript knows what he is charging and shows once loaded, removing the gif.
Put the loading gif in a <div> where you later want your facebook comments to appear and load the facebook comments into that div instead of appending them to the <body>.
Have the following tag:
<body onload=" myFunction()">
With a javascript function myFunction() to display an image only.
Just had a quick look , and apparently you can't use onload with div, however there is a full discussion here:
Onload-in-div-whynot

How can I resize the iframe without page refresh?

I have some swf embedded in iframe but only if the page is refreshed the iframe is resized, then if I select other one then will show as all swf not only the animation the background as well. This is what I am using
if ( 'resizeIframe' === $('#onPlayAction').val() ) {
var ifrEl = $('div.player-container iframe.page-iframe')[0];
$(ifrEl).show();
ifrEl.src = htmlPageBrowserUri;
ifrEl.onload = function() {
ifrEl.width = ifrEl.contentWindow.document.body.scrollWidth;
ifrEl.height = ifrEl.contentWindow.document.body.scrollHeight;
}
}
There are three ways to do this.
You can change the size on every window resize
$(window).on('resize', function (){
ifrEl.width = ... ;
ifrEl.height = ... ;
})
You can use some jQuery plugins like iFrame Resizer
You can use some nifty css tricks. Go search for responsive iframes using css and you will find a ton of good answers.
I hope this all helps you.
I suspect the issue with your code might be thses two lines :
ifrEl.src = htmlPageBrowserUri;
ifrEl.onload = function() {
The problem being that the first line set s the frame address, but second line sets the onload event immediately, probably before the page has loaded ? So when the page does load, the line setting onload event has already run & so doens't get set.
I don't quite understand the text in your question (sorry!) but the code below successfully resizes an iframe - it's run 'onload' in the frame's page:
<body onload="setParent()">
In case it's relevant, the iframe itself has attributes:
<iframe id="neckfinishframe" style="width:100%;overflow-x:hidden" src=".. etc">
In my case I'm only concerned about height. Width is 100%.
In the iFrame page, this code runs from the onload event to amend the iframe height to be whatever the height of the page is, plus a bit. This is intended to avoid showing a set of scroll bars within the iframe.
function setParent() {
// runs onload in iframe page
// in my case I have to run it from the frame page because I need to know the page rendered height in order to set the iframe height
var f;
try {f = parent.getElementById("neckfinishframe")} catch (e) {};
if (f != null) f.style.height=(this.document.body.scrollHeight+30)+"px";
}
Note - I haven't tried this cross- browser but I know it works in IE.

How to properly scroll IFrame to bottom in javascript

For a mockup-webpage used for research on interaction on websites, I created a mockup message-stream using JavaScript. This message stream is loaded in an IFrame and should show images at pre-set intervals and scroll to the bottom of the page after placing a new image at the bottom of the page. Getting the images to appear is working quite well with the provided script. However, both Chrome and IE seem to have trouble scrolling the page to the bottom. I would like to scroll to the bottom of the page as soon as the image is attached, but have for now added a 5 ms delay because that seemed to work sometimes. My questions are:
Is it okay to use document.body.scrollHeight for this purpose?
Can I make the scroll occur directly, or do I need a small interval before scrolling?
How to make the code scroll to the bottom of the IFrame directly after adding an image?
The following functions are used and trypost() is started onLoad:
function scrollToBottom(){
window.scrollBy(0,document.body.scrollHeight);
}
function trypost(){
point = point + 1;
if(point < interval.length){
//create and append a new image
var newImg = document.createElement("IMG");
newImg.src = "images/"+images[point]+".png";
document.getElementById('holder').appendChild(newImg);
//create and append a return
var br = document.createElement("br");
document.getElementById('holder').appendChild(br);
//time scroll to bottom (after an arbitrary 5 seconds)
var stb = window.setTimeout(scrollToBottom, 5);
//time next post
var nextupdate = interval[point]*400;
var tp = window.setTimeout(trypost, nextupdate);
}
}
My script section contains at least the following variables:
var point = -1;
var interval = [10, 10, 15];
var images = ["r1", "a1", "r2"];
This questions is a continuation of the project described in How to proper use setTimeout with IE?
To answer one of your questions, document.body.scrollHeight is appropriate for this purpose, but not if you're actually calling for document. That'll give you the scroll height of the document the iFrame is in, not the iFrame's document. The iFrame's document can be called upon by [insert variable for iFrame here].contentDocument.
Here's how I did it (and by that, I mean I tested it out with my own stuff to make sure it worked):
let i = document.querySelector('iframe')
i.contentWindow.scrollTo(0, i.contentDocument.body.scrollHeight);
That being said, the other answer by Thomas Urban will also work most of the time. The difference is only if your page has a really long scroll height. Most pages won't be longer than 999999 (for all I know that's impossible and that's why they chose that number), but if you have a page longer than that, the method I showed here would scroll to the bottom and the 999999 would scroll to somewhere not yet at the bottom.
Also note, if you have more than one iFrame, you're gonna want to query it in a different way than I did, like by ID.
Scrolling to bottom is always like scrolling to some ridiculously large top offset, e.g. 999999.
iframe.contentWindow.scrollTo( 0, 999999 );
In addition see this post: Scrolling an iframe with javascript?
If scrolling occurs too early it's probably due to images not being loaded yet. Thus, you will have to scroll as soon as added image has been loaded rather than on having placed it. Add
newImg.onload = function() { triggerScrolling(); };
after creating newImg, but before assigning property src.
If several events are required to trigger scrolling you might need to use some "event collector".
function getEventCollector( start, trigger ) {
return function() {
if ( --start == 0 ) { trigger(); )
};
}
You can then use it like this:
var collector = getEventCollector( 2, function() { triggerScrolling(); } );
newImg.onload = collector;
window.setTimeout( collector, 100 );
This way triggerScrolling() is invoked after 100ms at least and after image has been loaded for collector has to be invoked twice for triggerScrolling() being invoked eventually.

How to make an iframe auto-resize along with the dynamic changes on its content?

I have this js code I searched on auto-resizing iframe height with its content. It does what the user who posted this says it does. However, I now have this problem with dynamic content within the iframe.
The js code I have works only with the regular content of the page but not when there are dynamic changes going on within. For example, displaying texts through ajax call.
I've tried searching for other solutions to this but others did not work as well as what this code can do.
I'm hoping that there's someone who could help me update the code to meet what I currently need. I'm not very familiar with jquery/javascript to do this on my own. Thank you in advance! :)
This is the JS code:
function setIframeHeight(iframeId) {
var ifDoc, ifRef = document.getElementById(iframeId);
try {
ifDoc = ifRef.contentWindow.document.documentElement;
} catch (e) {
try {
ifDoc = ifRef.contentDocument.documentElement;
} catch (ee) {}
}
if (ifDoc) {
ifRef.height = 1;
ifRef.height = ifDoc.scrollHeight;
/* For width resize, enable below. */
//ifRef.width = 1;
//ifRef.width = ifDoc.scrollWidth;
}
}
I found this other code which enables iframe adapting to its dynamic content but I do not know how to make the code above and this work together. Please help me.
var iframe = document.getElementById("ifr").contentWindow;
iframe.$(".toggle_div").bind("change", function () {
$("#ifr").css({
height: iframe.$("body").outerHeight()
});
});
To summarize, I need a code that autoresizes iframe with its content and will autoresize again if there are changes on the size of the content.
The problem is that your page doesn't have any trigger indicating to resize when the iframe body resizes.
There also (as far as I know) isn't anything built into javascript that lets you watch for changes in an elements height.
You have two options.
If you are the owner of the iframe content, you can put a script in that page which can call to it's parent window telling the parent to run your resize script, or you can run a function which checks for changes say every second or so.
For the first method, you can follow the answer from here Can events fired from an iframe be handled by elements in its parent?
Otherwise just do a
setTimeout(function(){
$("#ifr").css({
height: iframe.$("body").outerHeight()
});
},1000);
function adjustMyFrameHeight()
{
var frame = getElement("myFrame");
var frameDoc = getIFrameDocument("myFrame");
frame.height = frameDoc.body.offsetHeight;
}
call this method on your iframe onload event and replace mtFrame to your iframe Id

Jquery.height() returns different results using F5 or CTRL+F5

So I am trying to find the height of my images then add a top margin this enables me to impose a a vertical center.
I'm running this code, and on an F5 refresh I get correct height but on CTRL+F5 refresh it gives me a much smaller height. I kind of assume this is a loading/delay thing, but I am using document ready so not really sure whats going on. I tried using a php function but it slows the site down amazingly so have to stick with jquery.
you can see it working here. www.mzillustration.com
jQuery(document).ready(function() {
if (jQuery('.imagedisplay').length != 0) {
jQuery('.imagedisplay').each(function(){
var imgheight = jQuery(this).find('img').height();
var topmarg = ((240 - imgheight) / 2) ;
jQuery(this).find('img').css({'margin-top':topmarg+'px'});
});
});
any ideas/help/explanation much appreciated.
thanks
There is a difference between onload and onready.
ready will wait until the actual DOM-tree is done, while onload will wait until ALL of the content displayed on the page is finnished loading. So an explanation would be that when clearing the cache and refreshing, the dom tree finishes much faster than the images, hence giving the wrong heigh.
Try using the onload-event instead and see if you get a different result.
You need to insure the image has loaded before asking the browser for its height. If that image path is living in the html you will unfortunately need a jquery pluggin to handle this in a cross browser manner.
https://github.com/alexanderdickson/waitForImages
http://desandro.github.com/imagesloaded/
Or you will have to wait for the window.onload event which in jquery looks like this:
$(window).on('load', function(){....
However if you use the window load event, it will wait until ALL resources have loaded and depending on your site that can be a serious delay when compared to measuring just the image itself.
Or if you are comfortable with loading the image from javascript, simply ordering your code properly will handle this:
var loadTester = new Image(),
imgH;
$(loadTest).on('load',function(){
imgH = $('#image').attr('src',loadTester.src).height();
}
loadTester.src = "paht/to/image.jpg";
The reason you are seeing a difference in the manner you reload the page, is that a simple refresh does not clear the cache, so the image is already loaded. When you hit ctrl+f5 it clears the cache and so the image is not yet loaded when you ask the browser for the height.
For cache control durring development consider getting the firefox web-developer toolbar.
Try this approach:
jQuery(function() {
jQuery('.imagedisplay img').each(function() {
var $this = jQuery(this),
height = $this.height();
if (height) {
$this.css('margin-top', ((240 - height) / 2) + 'px');
} else {
$this.on('load', function() {
$this.css('margin-top', ((240 - $this.height()) / 2) + 'px');
});
}
});
});
images are/can be cached/loaded separately from the actual page content. the document being ready can (and in my experience usually) occurs before everything is loaded.
try adding an event listener to the actual element being loaded.
You need to make sure the image has loaded before extracting a height. You can easily check this using the complete property on the image. Try this:
var setH = function() {
$(this).css('margin-top', (240 - this.height) / 2);
}
$('.imagedisplay img').each(function() {
if( this.complete ) {
setH.call(this); // apply height straight away
return;
}
$(this).load(setH); // apply height when the image has loaded
});

Categories

Resources