isotope append method removes current elements - javascript

I am attempting to append elements to a list using the .load() method to retrieve elements from another page.
But when I use this method it is removing the current DOM elements and replacing them, rather than appending them to the list.
Any help would be much appreciated.
Code below:
var $container = $('#container');
$('#insert a').click(function () {
var newEls;
$container.load('../pages/2.html .element', function () {
newEls = $(this);
});
$container.isotope('insert', $(newEls));
return false;
});

Surely you should be telling isotope to insert after they have been loaded.
e.g.
$container.load('../pages/2.html .element', function () {
newEls = $(this);
$container.isotope('insert', $(newEls));
});
otherwise you are inserting the current contents (or an empty div) before loading them.
Your $container.isotope('insert', $(newEls)); is executing before the load even starts (the load is asynchronous so you can only trust something to run against the loaded data if it is in the callback/function).
In addition to this, you are reloading the entire contents of the '#container' so it simply erases the previous children. You need to append the content, e.g. by loading into a dummy element then appending to your container.
maybe something like this (untested):
var $container = $('#container');
$('#insert a').click(function () {
var $newEls;
$container.append('<div id="#loadme"></div>');
var $loadme = $('#loadme');
$('#loadme').load('../pages/2.html .element', function () {
$newEls = $loadme.children();
$loadme.children().unwrap();
$container.isotope('insert', $newEls);
});
return false;
});
Normally I would not use load in this situation, but an AJAX get call and append the returned elements. Much simpler.

Related

jQuery .append() with wait for render

I'm getting some html from a webservice that I'm appending to a div. This is my success function:
function SucceededCallback(result) {
// get the div element
var RsltElem = $(".placeholder");
// update div inner Html
RsltElem.append(result);
$('.loading-gif').hide();
}
Is there any way I can get .append() not to display until the browser is finished loading and painting it?
I'd rather not use .append(result).slideDown(n) as n could be anything, depending on what the webservice sends me.
Thanks in advance
Consider using
$( document ).ready(function() {
...
});
like so:
$( document ).ready(function() {
//get the div element
var RsltElem = $(".placeholder");
//update div inner Html
RsltElem.append(result);
$('.loading-gif').hide();
});
I don't know what you are painting and when it will complete, so you could also use this:
$(window).bind("load", function() {
// code goes here
});
Code inside the function only runs when the entire page has loaded.
$(window).on('load', function() {
//everything is loaded
});

jQuery element somehow cached in setInterval

I'm trying to trigger a click on an element every x seconds. It's not the exact same element every time (depending on which tab a user has selected, it should click that tab), but they are all in the same container (with id #container. The selected element has the class .selected and gets that class when it has been clicked on by a user.
This is the code I have:
var feedContainer = $('#container');
window.setInterval(function () {
var selectedTab = feedContainer.find('.selected');
selectedTab.trigger('click');
}, 10000);
The problem is that between the timeouts, if a user clicks on another tab, this part doesn't pick up on that: var selectedTab = feedContainer.find('.selected');. It just gets the one that was selected before, not the new one that has the class. How do I avoid that?
It works fine if I do the entire selection in the timer each time (var selectedTab = $('#container .selected');). It seems to be somehow caching the results from the last run.
Why is this and how do I force it to fetch the correct element?
You are already caching the element yourself by doing this:
var feedContainer = $('#container');
If the contents change after you assign it to the variable then that variable won't get updated with the new contents automagically.
Just use it like this $('#container'); directly whenever you want to do operations on it.
What you're doing is that in the beginning, you gather some elements that match the selection (using $('#container')) but later on, you change the content of #container which is not reflected in the jQuery object in feedContainer. Simply get the container on each iteration.
window.setInterval(function () {
var feedContainer = $('#container');
var selectedTab = feedContainer.find('.selected');
selectedTab.trigger('click');
}, 10000);
window.setInterval(function () {
var selectedTab = $('#container').find('.selected');
selectedTab.trigger('click');
}, 10000);
As container is not changed above is proposed.
First of all, an ID should ideally be used to identify a "single" element, not multiple elements. Changing that would help you out by spreading the elements with the same name using a "class" identifier. Changing that might help you out a lot.
I'd do it like this. Short, to the point and no variable assigning thus no caching.
window.setInterval(function () {
$('#container .selected').trigger('click');
}, 10000);

Binding setTimeOut to some function with specific element

I am trying to do a notification pop up, each pop up is dynamically generated after ajax fetched the data.
The pop up each will have a time limit of 10 seconds before it fade out. Something like you see on Facebook's notifications on the left bottom corner.
Each pop up will be hidden according to the time it is added and the timelimit.
Here's an example of my code:
function hidePop(obj){
$(obj).hide();
}
function newpopup(data){
$('#notifications').prepend('<li class="new" style="display:none;">'+data+'</li>');
$('.new').fadeIn(200, function(){
var $this = $(this);
$(this).removeClass('new');
setTimeout(function(){
hidePop($this)
}, 10000);
});
}
As you can see above, my AJAX call will call for newpopup with the data. Once it fades in completely the setTimeout function will run.
This works, however, after a few more li is appended, those new lis will keep hiding itself once its showed.
Note: I remove class new once everything is done since new will then be used for the latest incoming popups.
I think the setTimeOut is either not stopped or targeting all of the lis.
Is my method a problem or is there any better solutions?
Instead of simply prepending an <li> tag as a string that states a class, then selecting the class with jQuery, I would suggest using the DOM to create the <li> element and hold a reference to it like so:
function hidePop(obj){
obj.hide(); //obj parameter already wrapped by jquery, no need to do it again
}
function newpopup(data){
var newLi = $(document.createElement("li")); //createElement then wrap jQuery around it
newLi.html(data).css("display", "none"); //jQuery set innerHTML and CSS
$('#notifications').prepend(newLi); //Prepend to list
newLi.fadeIn(200, function() { //Select this and only this li element
setTimeout(function(){
hidePop(newLi); //Closure; reference to the same "this and only this li"
}, 10000); //10s
});
}
In the body of the anonymous function in setTimeout, $this is overwritten. Try this:
function newpopup(data){
$('#notifications').prepend('<li class="new" style="display:none;">'+data+'</li>');
$('.new').fadeIn(200, function(){
var $this = $(this);
$(this).removeClass('new');
var thatPopup = $this;
setTimeout(function(){
hidePop(thatPopup)
}, 5000);
});
}

Is there a Javascript event that triggers when an HTML element scrolls into view?

I want to load elements as they scroll into view to reduce server load e.g. thumbnails, but would like their placeholder divs to exist from when the page loads. To do this, I think I need a trigger of some kind when the div becomes visible.
jquery-appear was suggested but I cannot seem to get a copy of it from anywhere (Google gives me a 403 error)
Does anyone know how else to do this?
I think jQuery way points is the plugin you might need:
http://imakewebthings.com/jquery-waypoints/
Below is how you can call a waypoint plugin:
$(document).ready(function() {
var $loading = $("<div class='loading'><p>Loading more items…</p></div>"),
$footer = $('footer'),
opts = {
offset: '100%'
};
$footer.waypoint(function(event, direction) {
$footer.waypoint('remove');
$('body').append($loading);
$.get($('.more a').attr('href'), function(data) {
var $data = $(data);
$('#container').append($data.find('.article'));
$loading.detach();
$('.more').replaceWith($data.find('.more'));
$footer.waypoint(opts);
});
}, opts);
});

AJAX - load all div elements

I have a webpage with a number of div elements such as this one:
<div id='ahFyb2JpdGFpbGxlc2FuZGJveHIKCxIA'>
</div>
I would like each div element to call a javascript function when it has loaded, to fill in the div. Ideally I would have liked to do
<div id='ahFyb2JpdGFpbGxlc2FuZGJveHIKCxIA'
onload=getcontent('ahFyb2JpdGFpbGxlc2FuZGJveHIKCxIA');>
</div>
but of course, onloads are not allowed for div elements. Is there a way to do this? I have read in a number of places that jQuery can help for this, but I can't figure out how to code it up. Any help would be very much appreciated!
To do it without jquery, you just need to set the onload for the window, and tell it what to do with each div. But jquery makes this much simpler.
So without:
window.document.onload = function() {
var divs = document.getElementsByTagName("div");
for(var i = 0; i < divs.length; i++)
divs[i].text("blah blah blah");
}
};
It might be innerHTML. I'd have to double check. But that's the gist. With jquery:
$(function(){
$("div").text("blah blah blah");
};
This of course assumes each div gets the same text. If you want it to be based on ID or class, you most certainly want jquery.
PS - Most web pages try to avoid placing javascript event handlers in the actual HTML. If yous set up the event handlers on load, there's no need and the code is cleaner. Jquery definitely helps on this.
If you're basing the content on the ID of the div, a slight modification to Anthony's code should work
document.onload = function() {
var divs = document.getElementsByTagName("div");
for(var i = 0; i<divs.length;i++){
divs[i].innerHTML = getContent(divs[i].id);
}
I would assign a class to the div's that you want to 'autoload' their own content. This makes the markup clearer and the JavaScript more concise.
$(function() {
$('.autoload').each(function() {
// Use AJAX
$.get("service.php", {id: this.id} function(response) {
// Handle server response here
});
// Or a local data island
this.innerHTML = getDataById(this.id);
});
});
With jQuery:
You should consider using $.load() to retrieve html content. It's slightly easier to use than $.get(). Altho it'll use POST semantics if you supply paramters...
In any event, do you really want to make separate calls back to server for each div? .. Perhaps you should consider a single call that sends the accumulated set of div id's awaiting content to a your web-service function, that then subsequently returns a json structure that you can walk thru at success filling divs all in one shot ..
Something like (not-tested!):
$(function() {
var ids = [];
$('div.autoload').each() { function() { ids.push($(this).attr('id')); });
$.get('service.php', {ids: ids}, function (response) {
$.each(response.perdiv, function (i, c) {
$('div#' + c.id).html(c.html);
});
});
});

Categories

Resources