Iterating Ajax load selector - javascript

I am trying to create an 'infinite scroll' using Ajax (or rather specifically using Jquery's .load function), the function fires perfectly and in the instances where it has worked it spits out a comical amount of articles, so I figured that I should create a unique, iterating div (id1,id2,id3 etc) but when using an iterating selector to load the Ajax content into unique div ids, by iterating it, it .load fails or doesn't fire.
var busy = false;
var i = 1;
var x = 0;
function content(){
if($(document).height() * 0.7 < $(document).scrollTop() && !busy) {
var offset = i++ * 6;
$("#expand").after("<section id='expand" + x++ + "' class='gridWrapper'></section>");
$("#expand" + x).load("/ajaxcontent/", {section: 'articles', category: '', limit: '6', offset: offset, form: 'grid', action: 'article'}, function(){
busy = true;
});
x++
} else {
busy = false;
}
}
window.onscroll = content;
document.ready = content;
My question is how do I get the selector $("#expand" + x) to work correctly? In the variations (for loops, while loops, .each) I have tried where it does output articles it goes utterly bananas and essentially regurgitates all articles. Any help would be hugely appreciated!
(As it is a an Ajax load, I don't think that I can create a JsFiddle)

This is working
$('#expand' + x)
try to remove the ++ in this line
$("#expand").after("<section id='expand" + x++ + "' class='gridWrapper'></section>");
to
$("#expand").after("<section id='expand" + x + "' class='gridWrapper'></section>");

Related

How to run a specific javascript code before page load (first of all)?

I have a js code that adds margin-top to a row with a specific class name (page with id=3) . I would like this code runs before page load because now it instantly displays the row without margin-top and then add it. The row should be displayed with the margin-top already be added.
My site is on wordpress and i added the js script on head.
I have tried
window.onpaint = checkMargin();
but it did not work. Any idea?
This is my js code
<script type="text/javascript">
//sets margin-top in serv-col --- IF not mobile version
function addServMargin() {
containers = document.getElementsByClassName('serv-cont');
titles = document.getElementsByClassName('serv-col-title');
texts = document.getElementsByClassName('serv-col-text');
links = document.getElementsByClassName('serv-col-link');
col_pad = '0px';
if ( window.innerHeight > 800) { col_pad = '8.3vh'; }
for (var i = 0; i < titles.length; i++) {
title_height = titles[i].offsetHeight;
text_height = texts[i].offsetHeight;
style = window.getComputedStyle(containers[i], '');
cont_height = style.getPropertyValue('height');
cont_padd = style.getPropertyValue('padding-top');
links[i].style.marginTop = 'calc(' + cont_height + ' - ' +
cont_padd + ' - ' + col_pad + ' - ' + title_height + 'px - 1.48vh - ' +
text_height + 'px - 127px - 5vh)';
}
}
function checkMargin() {
if (document.getElementsByClassName('page-id-13')[0] && window.innerWidth > 900) { addServMargin(); }
}
window.onresize = checkMargin;
</script>
I don't think making it run first will solve anything. The first thing the code does is get the containers, titles, texts, and links... which it does by searching the DOM. It then loops through the titles array and does the adjusting as needed. If the script runs before any rendering is done, the DOM elements won't exist. It 1) won't be able to find them, and 2) can't loop through them because the array will be empty.
Actually even before that, it checks for the existence of the elements it's looking for, and the screen size. I think the only way to get it to work w/o making it look like an after thought adjustment, would be to use CSS and media sizing to set the styles in the first place.
As I know JS is executed as the script tag is reached by Browser html interpreter. So putting it in the head tag on the first position may guarantee that it strats first, but can't guarantee that it ends execution before page loads, because the page loads asynchroniously.

Looping through Video Sources slows Chrome

I have two video sources that are outputted to my page via ajax (the second is hidden). I play the first one and bind an event onto it so that when it has ended the next video is played and shown whilst the first is then paused, rewinded back to 0, and the process continues.
here is my code.
function queueVideos(num, amount) {
if (num < amount) {
document.getElementById('video-element-'+num).addEventListener('ended', playNextClip, false);
function playNextClip() {
var nextVid = num + 1;
$( '#video-element-' + nextVid ).show().get(0).play();
$( '#video-element-' + num ).hide();
document.getElementById( 'video-element-' + num ).pause();
document.getElementById( 'video-element-' + num ).currentTime = 0;
queueVideos(nextVid, amount)
}
}
if (num == amount) {
document.getElementById('video-element-'+num).addEventListener('ended', playFirst, false);
function playFirst() {
$( '#video-element-1' ).show().get(0).play();
$( '#video-element-' + num ).hide();
document.getElementById( 'video-element-' + num ).pause();
document.getElementById( 'video-element-' + num ).currentTime = 0;
queueVideos(1, amount);
}
}
}
The code is called within an ajax function that feeds it the num and amount from data i get elsewhere, for arguments sake let's say i'm running it like so:
queueVideos(1, 2);
My problem is that after around 1 minute the transitions between the clips get laggy, the clips pause unexpectedly, and ultimately the browser (chrome) performs slowly.
How can I fix this?
Thanks!
I found that changing the function playFirst() to not include queueVideos(1, amount); fixed the problem! I didn't realize that i only needed to add the event listener once. Woohoo!

Having trouble getting my HTML onload to call my JS function

I have a function that should be called whenever my html page loads. The <body> tag should call the startAdPage() function. However, nothing at all happens. I am not completely sure why. Any suggestions? Here is the <body> call in my HTML page
<body onload="startAdPage();">
Next, here is my startAdPage() function, as well as the two functions it calls. Those two aren't completely finished yet. One of them is supposed to create a small image gallery slide show. The other is supposed to create a countdown from 10 - 1 before displaying a separate web page. Neither work yet, so any advice on them would also be appreciated, though they aren't my main focus yet.
function startAdPage(){
setInterval(changeAd(), 2000);
setInterval(startCountdown(), 1000);
}
Here is changeAd()
function changeAd() {
for(var i = 1; i < 4; i++){
document.images[0].src = "images/pic" + intNumber + ".jpg";
}
}
Lastly, startCountdown(). I haven't made the webpage that I said this function calls yet
function startCountdown() {
window.alert('Test');
for(var i = 10; i >= 1; i++){
document.getElementById("countdown").value = i;
}
}
Your problem is right here:
document.images[0].src = "images/pic" + intNumber + ".jpg";
You refer to intNumber but you should be using i instead. So change the above to
document.images[0].src = "images/pic" + i + ".jpg";
and your function will be called.
You should consider removing the onload in the body tag and do a
window.onload = startAdPage;
instead - to keep your html and Js logic separate.
Also, your countdown logic is wrong - you want to decrement i, not increment:
var i = 10; i>0; i--

DOM Update slow in chrome than firefox looks like chrome has some rendering issues

I have written a code which dumps large no of node in DOM . When i load it in firefox it renders in 2-3 secs but in chrome (ver:33) it freezes the UI and rendering takes long time(8-10 sec) .
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total * 100;
$("#fetchProgress").attr("value", percentComplete);
}
}, false);
return xhr;
},
type: 'GET',
url: "/GetSomething",
data: {},
success: function (data) {
///process and dump to DOM//
var fileLines = data.split('\n');
var htmlString = '';
for (var i = 0; i < fileLines.length; i++) {
htmlString += '<span>' + (i + 1) + '. ' + fileLines[i]+</span>;
if ((i % 1000) == 0) {
$("#textPlace").append(htmlString);
htmlString = '';
}
}
fileLines = null;
$("#textPlace").append(htmlString);
}
});
I learned from internet that chrome has some rendering bugs and tried hacks from this URL.
"Chrome Bug - window.scroll method intercepts DOM Rendering"
It started to work but now again it is not working .Please suggest something .
Any help is appreciated . Tank size Thanks in Advance :)
If I understand your code, you have an array which you want to tie together with spans. You can remove the for() from your code (and the modulus in it(=slow) ), saving a lot of time:
htmlString = '<span>'+ fileLines.join("</span><span>") +'</span>';
That will not display the i number, but you could switch to li's and use the numbers instead of bullets.
This might work too:
var fileLines = '<span>'+ data.replace('\n', '</span><span>') +'</span>';
This is a litte more messy (this could end in </span><span></span>, you need to trim \n's to fix that (easy to do)), but it doesnt have to turn it into an array, which should speed things up
See if you can avoid the append to html under this function
if ((i % 1000) == 0) {
$("#textPlace").append(htmlString);
htmlString = '';
}
and only have one append at the very end of your code. You want to limit the DOM manipulation - it affects the browser performance by triggering multiple browser reflow.
Google Dev: Speeding up JavaScript: Working with the DOM
Taken out from the link above, you can work with something like this instead
var anchor, fragment = document.createDocumentFragment();
for (var i = 0; i < 10; i ++) {
anchor = document.createElement('a');
anchor.innerHTML = 'test';
fragment.appendChild(anchor);
}
element.appendChild(fragment);

Can't change iframes onload listener in IE9

I have the following code within an external javascript file.
jQuery(function ($) {
//////////////////////UPCOMING EVENTS JSON SERVER START///////////////////////////
var eventList = $("#eventList"); //cache the element
$.getJSON("/JsonControl/Events.json", function (jsonObj) {
val = "";
for (var i = 0; i < jsonObj.events.length; ++i) {
val += "<p>" + jsonObj.events[i].dateMonth + "/" + jsonObj.events[i].dateNumber +
"/" + jsonObj.events[i].dateYear + " - <span id='EL" + i + "' class='link' " +
"onclick=plotEvent(" + i +")>" + jsonObj.events[i].title + "</span></p>";
}
eventList.html(val);
});
//////////////////////UPCOMING EVENTS JSON SERVER END/////////////////////////////
});
function plotEvent(index)
{
$.ajax({
url: "/JsonControl/Events.json",
dataType: 'json',
async: false,
success: function (jsonObj)
{
var eventBox = window.frameElement;
alert("This alert fires in all browsers, including IE9")
eventBox.onload = function ()
{
alert("This alert doesn't fire in IE9.")
window.frameElement.onload = null; // unset it so it only fires once
eventBox = eventBox.contentDocument || eventBox.contentWindow.document;
eventBox.getElementById("title").innerHTML = (jsonObj.events[index].title);
eventBox.getElementById("content").innerHTML = (jsonObj.events[index].explanation);
eventBox.getElementById("dateHolder").innerHTML = (jsonObj.events[index].dateMonth + "-" + jsonObj.events[index].dateNumber + "-" + jsonObj.events[index].dateYear);
};
eventBox.src="/Event htms/Event.htm";
}
});
}
The page that loads this script is in the iframe itself. A very similar function called in a different external js file, from the main page outside of the iframe (for a different but similar purpose) works in all browsers just fine. The only difference is that with this code I have to target the onload of the iframe from within the iframe, instead of just grabbing the iframe by id. I then attempt to change, the onload of said iframe, for use with the next internal iframe page (which is why I need to preserve the json array index [i] when dynamically writing the first iframe page's innerHTML.
Sorry if that was a bit wordy, and/or confusing, but suffice it to say that with using the above-pasted code, I have no problems... except with IE (tried in IE9). I have tried dozens of examples and supposed solutions, but nothing has worked. Using IE9.
Here's what I mean when I say 'it doesn't work in IE9':
This part of the code within plotEvent() doesn't fire:
eventBox.onload = function ()
{
alert("This alert doesn't fire in IE9.")
window.frameElement.onload = null; // unset it so it only fires once
eventBox = eventBox.contentDocument || eventBox.contentWindow.document;
eventBox.getElementById("title").innerHTML = (jsonObj.events[index].title);
eventBox.getElementById("content").innerHTML = (jsonObj.events[index].explanation);
eventBox.getElementById("dateHolder").innerHTML = (jsonObj.events[index].dateMonth + "-" + jsonObj.events[index].dateNumber + "-" + jsonObj.events[index].dateYear);
};
Is there any solution to this problem, or is this sort of thing why iframes aren't used more often (that is, that IE doesn't fully support them)?
Try eventBox.contentWindow.onload or maybe $(eventBox).load(function)

Categories