Jquery Loading news listings into dom - javascript

I want simply to load/display my top 500 news into my DOM.
I'm not sure why doesn't display it on my <div id="hackernewsrss" ></div>
And if there's any other better way to display this? or to code it? Perhaps I can learn.
var LoadNews = $("#hackernewsrss");
LoadNews.load(function(event) {
parseTopStories('https://hacker-news.firebaseio.com/v0/topstories', '#hackernewsrss');
});
function parseTopStories(url, container) {
var hackernewsAPI = "https://hacker-news.firebaseio.com/v0/topstories.json";
$.getJSON(hackernewsAPI, function(json) {
var requests = [];
for (var i = 0; i < 10; i++) {
requests.push($.getJSON('https://hacker-news.firebaseio.com/v0/item/' + json[i] + '.json'));
}
$.when.apply($, requests)
.done(function() {
var results = []
.slice.call(arguments);
var list = results.map(function(arr) {
var thetemplate = '<li>' + arr[0].title + '</li>';
return thetemplate;
});
$(container).html('<ol>' + list.join('') + '</ol>');
console.log(container); //logs #hackernewsrss
});
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="hackernewsrss"></div>
Can anyone help please?

If you try:
$(function(){
parseTopStories('https://hacker-news.firebaseio.com/v0/topstories', '#hackernewsrss');
});
All goes well.
I am not sure why you have load event attached to the div. It is usually used to trigger when image is loaded or window:
JQuery reference

Related

jQuery UI Sortable - Load Positions

I am using this code to save the position of the sorted div's with jquery-ui.
The code works great but my question is...how can I load them again into position once saved?
Here's the code I'm using to save to positions:
<div id="sortable">
<div id="2000"></div>
<div id="1000"></div>
<div id="3000"></div>
</div>
$('#sortable').sortable({
update: function () { save_new_order() }
});
function save_new_order() {
var a = [];
$('#sortable').children().each(function (i) {
a.push($(this).attr('id') + ':' + i);
});
var s = a.join(',');
alert(s);
localStorage.setItem("positions", s);
}
How can I load?
You can retrieve the value and update the order as shown below. Note that I'm using the built in toArray method to retrieve the order:
$(function() {
var $sortable = $('#sortable');
var positions = JSON.parse(localStorage.getItem('positions'));
if (positions) {
$.each(positions, function(i, position) {
var $target = $sortable.find('#' + position);
$target.appendTo($sortable); // or prependTo for reverse
});
}
$sortable.sortable({
update: saveNewOrder
});
function saveNewOrder() {
var positions = JSON.stringify($sortable.sortable("toArray"));
localStorage.setItem('positions', positions);
}
});
JSFiddle demo

Click event on every item on populated list with jQuery

Here is how I populate my list:
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
Here is my html file:
<ul id="myList"></ul>
I want to add a click event for every item of list (without having separate ids):
$(function() {
$('#myList').click(function() {
var listItem = this.find('a').text();
console.log(listItem); // never logged
});
});
However, when I click at a list item, click event doesn't fire.
What am I doing wrong?
I can only assume there's a js error in your console.
I've created a working sample for you. We can use event delegation and then retrieve the DOM node that was clicked. You need to ensure you call the bingNetworksList [assume typo in here and meant binD ;)] function when the DOM ready event has fired.
function bingNetworksList(myList) {
var list = '';
for (i = 0; i < myList.length; i++) {
list += '<li>' + myList[i] + '</li>';
}
$('#myList').empty();
$('#myList').append(list);
}
$(function() {
var list = ["foo", "bar"]
bingNetworksList(list);
$('#myList').click(function(evt) {
var listItem = $(evt.target).text();
console.log(listItem); // never logged
});
});
You need to wrap this inside $ as like this:
$(function() {
$('#myList').click(function() {
var listItem = $(this).find('a').text();
console.log(listItem); // will always be logged
});
});

getElementsByTagName('img').length logs out to 0

I have read multiple posts on this, but still don't understand why document.getElemenstsByTagName('img').length prints out '0' but when you console log it shows you the right length.
To further explain my problem, part of my HTML looks like this
<div id="parent">
<div id="slider">
</div>
</div>
Now i am dynamically adding the elements as children to the #slider element.
In my javascript i have an object
var manualSlide = {
imageLength: document.getElementsByTagName('img').length,
//other properties
};
Why does the property 'imageLength' gets assigned '0' instead of the actual length?
Edit:
Here is my entire script
<script>
$.getJSON('data.json',function(data){
$.each(data.images, function(key){
setImages(data.images[key]);
});
});
function setImages(obj){
var imgTag = '';
imgTag += "<img src='" + obj.Url + "' style='width:800px;height:400px' alt ='"+ obj.Title +"' name='pics'/>";
$('#slider').append(imgTag);
}
$(document).ready(function(){
var slide = getManualSlide();
document.getElementsByClassName('left').onclick = function(){
slide.previousImg();
};
document.getElementsByClassName('right')[0].onclick = function(){
slide.nextImg();
};
function getManualSlide(){
var manualSlide = {
imageNum : 1,
imageLength: document.getElementsByTagName('img').length,
image: document.getElementsByTagName('img'),
previousImg: function(){
if(this.imageNum > 1){
this.imageNum --;
}
else{
this.imageNum = this.imageLength;
}
document.pics.src = this.image[this.imageLength - 1];
},
nextImg: function(){
if(this.imageNum > this.imageNum){
this.imageNum ++;
}
else{
this.imageNum = 1;
}
console.log(document.getElementsByTagName('img').length);
console.log(this.imageLength);
document.pics.src = this.image[this.imageLength - 1];
}
};
return manualSlide;
}
});
</script>
It's all about where or when your code gets executed.
You have to make sure your code gets executed after the image tags are parsed (added to the DOM tree).
To do that you could put your code either behind the img-tags in the body or you wait for the document to be loaded:
<script>
document.addEventListener("DOMContentLoaded", function(event) {
imageLength = document.getElementsByTagName('img').length;
console.log(imageLength);
});
</script>
You can read more about this event here.
If you are using jQuery you could also use
$(document).ready(function(){ /* your code goes here */ });
which does exactly the same.
Because the object was created when no img tags were in the document. The object data will not update with the document. If you want this behavior you should use events.
Instead create a function to return an updated object. See below:
function getManualSlide()
{
var imgLen = document.getElementsByTagName('img').length;
var manualSlide = {
imageLength: imgLen
};
return manualSlide;
}
http://jsfiddle.net/2akca0dg/2/

Returning from JQuery 'get' when all images have loaded

I am using jquery get to load html onto my content div. The HTML I am loading contains some images and I am finding that my custom height calculation I am doing in javascript isn't working too well because the images are fully loaded when the loadHTML has returned.
var loadHTML = function(){
return $.get("javascripts/templates/" + templateType + ".html", function(text) {
$("#content").html(text);
});
};
Is there a way I can only return from loadHTML once all images have loaded? I tried to call and return load but this doesn't work
var loadHTML = function() {
return $.get("javascripts/templates/" + templateType + ".html", function(text) {
var content = $("#content").html(text);
return $('img', content).load();
})
};
Also, I am using Q promises in other parts of my application so is it possible to fix my problem using that.
ie. loadHTML.then(loadImages).then(doOtherStuff);
You can try to use a custom deferred object like below
var loadHTML = function () {
var deferred = $.Deferred();
$.get("javascripts/templates/" + templateType + ".html", function (html) {
var $html = $(html),
$imgs = $html.find('img'),
len = $imgs.length,
counter = 0;
$imgs.load(function () {
if (++counter == len) {
deferred.resolve();
}
});
$("#content").html($html);
});
return deferred.promise();
};
TD
var list = [];
for (var i = 0; i < 5; i++) {
list.push('<span><img src="//placehold.it/64&text=' + (i + 1) + '" /></span>');
}
var html = '<div>' + list.join('') + '</div>';
var loadHTML = function() {
var deferred = $.Deferred();
//using a timer to simulate ajax request
setTimeout(function() {
var $html = $(html),
$imgs = $html.find('img'),
len = $imgs.length,
counter = 0;
$imgs.load(function() {
if (++counter == len) {
deferred.resolve();
}
});
$("#content").html($html);
}, 500);
return deferred.promise();
};
loadHTML().done(function() {
$("#content").find('img').each(function() {
$(this).after(this.complete)
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content"></div>
Demo: Fiddle
Demo: Problem(Change the size of the image to see the problem)
Deleted my other answer because it was too wordy.
The reason your code is not working is because you are making an ajax request to a server, then returning from the function immediately. The page ploughs on with its scripting and probably finishes most if its work before that request comes back with your images.
You need to move your return to a place in your function you know is not going to process until the data comes back. You can use promises to do this:
var jqxhr = $.get( "example.php", function() {
alert( "request sent, images are loading" );
// DON'T PUT YOUR RETURN HERE,
//YOU WANT TO CALL IT WHEN THE ABOVE IS DONE
})
.done(function() {
alert( "the info is loaded" );
//put your html insert here to make sure the
//data is fully loaded before you manipulate it
//you could also call htmlresize here but that would be nesting.
//That shit gets complicated. Just call it after this function returns on success.
return
})
.fail(function() {
alert( "error" );
// its good to handle errors
return
})
if you dont want to hold up your whole page load to load some images you can do facny stuff like put the html resize and other dependent code on the jqxhr.sucess callback, so that other code gets read while your images come through. But that's complicated.

use JSON variable in jQuery to display more JSON variables

This is somewhat pseudo code so EDIT away. I want to make it when the user clicks on a thumb inside #placeholder DIV thumb2 is then displayed inside #imageLoad DIV. NOTE: Thumb and thumb2 are JSON items. A lot of people are saying that this can't be done with getJSON because it's an asynchronous request. If that is the case, then how can I change my script to support the request? If I am going the wrong way, please provide alternate solutions.
$.getJSON('jsonFile.json', function (data) {
var image1 = "<ul>";
for (var i in data.items) {
image1 += "<li><img src=images/items/" + data.items[i].thumb + ".jpg></li>";
}
image1 += "</ul>";
document.getElementById("placeholder").innerHTML = output;
var image2 = "<img src=images/items/" + data.items[i].thumb2 + ".jpg>";
$('li').click(function () {
document.getElementById("imageLoad").innerHTML = output;
});
});
Here is the external JSON file below (jsonFile.json):
{"items":[
{
"id":"1",
"thumb":"01_sm",
"thumb2":"01_md"
},
{
"id":"2",
"thumb":"02_sm",
"thumb2":"02_md"
}
]}
You can try something like the following:
$.getJSON('jsonFile.json', function(data)
{
$("#placeholder").html("");
var ul = $('<ul></ul>');
$('#placeholder').append(ul);
var load = $("#imageLoad");
for(var i in data.items)
{
var li = $('<li></li>');
ul.append(li);
var img = $('<img>');
img.attr("src", "images/items/" + data.items[i].thumb + ".jpg");
img.click((function(x)
{
return function()
{
load.html("<img src=images/items/" + data.items[x].thumb2 + ".jpg>");
}
})(i));
li.append(img);
}
});
Main difference is that click-handler is assigned inside the loop, so every handler receives a closure with appropriate reference to thumb2.
I think this could do the trick:
var $placeholder = $('#placeholder'),
$imageLoad = $('#imageLoad');
$.getJSON('jsonFile.json', function(data) {
var html = '<ul>';
$.each(data.items, function(i,item){
html += '<li><img src=images/items/' + item.thumb + '.jpg></li>';
});
html += '</ul>';
$placeholder.html(html);
});
$placeholder.on('click','li',function(){
$imageLoad.html($(this).html());
});
I can't understand the use of output since you are not declaring it in anyway. The eventhandler for the click event will trigger on all current and future li elements of the $placeholder which contains the DOM object with an id of placeholder.

Categories

Resources