javascript div children do not work - javascript

With the yrss library, I am loading a RSS feed into my HTML document. This works.
But then I want to access the divs from my JavaScript.
I can lookup the parent node (var test) and put it in the console. But when I want to get the number of child elements, it returns 0.
I'm using the following code:
var test = document.querySelector('#History_0');
console.log("test:");
console.log(test); //Returns <div class="item_trackHistory rss-feed" id="History_0">
console.log("test.childElementCount:");
console.log(test.childElementCount); //Returns 0
However, I can see the child elements I want to access in the inspector.
Why is it that I can see the children of the #History_0-div in Developer Tools, but the attribute childElementCount returns 0?
How can I access an element's children in JavaScript?
Sorry for making mistakes in the way I edited my question the first time.
here is the entire function call. I also entered the suggested solution from below. Unfortunately, it didn't work out.
code
for (var i = 0; i < obj.results.length ; i++ ){
var div = "History_" + i
getRSS(div ,obj.results[i].feedUrl, i);
}
code
this.getRSS = function(div, link, iteration){
$('#'+div+'').yrss(link,{
limit: 50,
dateformat: 'localedate',
tags:'true',
logging:'false'
});
var parent = document.querySelector('#History_'+iteration+'');
var childCount = 0;
if (parent !== null){
var childElements = parent.getElementsByClassName('entry-wrapper');
console.log(childElements);
console.log(childElements.item(0));
if(childElements !== null){
childCount = childElements.length;
console.log(childCount);
}
}
The console.log of ChildElements Returns a HTML Collection, which appears to have 20 entries. But console logging the ChildElement.item(0), it Returns a null.
The console log of childCount Returns 0.
Does anyone have an idea, how it is possible to access the childElements?
Where in my entire js-file should I call a function to Access the divs, that the yrss function creates?

Not the best question as others have pointed out, however, some simple things we can look at. I am unsure if the page loads the RSS feed after the page has loaded or not. I presume not, and will answer it presuming exactly that.
You can see my working code example here:
https://codepen.io/vincentritter/pen/vJmBrd?editors=1010
I've added notes too. Here is the snippet that should be the most important to get you started.
// Grab 'parent' div - History_0 or by class name 'rss-feed'
var parent = document.querySelector('.rss-feed');
var childCount = 0; // Just want to spit this out on the page so you can see.
// Check if parent isn't null
if(parent !== null){
// Get child elements by class name
var childElements = parent.getElementsByClassName('entry-wrapper');
// Check if child elements isn't null...
if(childElements !== null){
// Print results, just so we can look.
childCount = childElements.length;
console.log(childCount);
}
}
I used your images as reference.
To note, I grab stuff by their class name. Just find that easier. But everyone is different, whatever works for you.
That should get you going at least.

Related

Setting data info on dynamically created html

I have a JSON response from a server, which returns me a array with 32 objects (in this case). Something like this:
[{object1},{ object2},{ object3}, etc].
Each object have some info that I use to populate an html template. For that, I just use a simple loop:
for(var i = 0; i < api_empresaListar.length; i++)
{
var item = api_empresaListar[i];
var htmls;
htmls = $('...lots of html code');
...
Then it’s just a simple matter of finding/changing the values, and append items on the DOM. Everything works fine. BUT, for some next parts of the code, I would like to access all the info from the object I used to build the html elements (I just show part of the info). So, after searching a lot, I tried to use data, like this:
var tp = htmls.find(".rl_grupo"); // the main div of each html element created in the loop
$(tp).data('key', api_empresaListar[i]); // here, I expected to just insert the object data in each created item.
But when I try it in the console, I got the object info as expected, but always from the last element in the array. Why is that happening? I believe it might be something stupid, but I can’t figure it out.
So, any ideas on how to solve this, or another method to make this work is appreciated. I made it work by setting some "display:none" placeholder html tags and populate those with the info I need later, but looks like a poor solution...
You should not set your htmls variable in the loop. I think that you crush its content every turn, that's why you only have the last item. You should do something like this:
var htmls = $('<div></div>');
for(var i = 0; i < api_empresaListar.length; i++) {
htmls.append($('...lots of html code'));
}
How about setting an index number on each element inside of your html creating code, then iterating over the $('.rl_grupo') elements, like this?
$('.rl_grupo').each(function(){
var index = $(this).data('index');
var currentData = api_empresaListar[index];
$(this).data('key', currentData);
})

Get element value inside iframe which is nested inside Frame in javascript?

I main php page in which there are 2 frames. Inside the second frame there is iframe.
I want to access value of element on iframe document from the 1st frame.
I tried like this:
var frame1 = parent.frames[1];
var frame2 = frame1.document.getElementsByTagName('iframe')[0];
var eleValue =frame2.contentWindow.document.getElementById("MyElement").value;
but I am not receiving any value though it is there.
var frame1 = parent.frames[1];
alert(frame1.name);
var frame2 = frame1.document.getElementsByTagName('iframe')[0];
alert(frame2.name);
var txtClinic = frame1.document.getElementsByTagName('iframe')[0].contentDocument.getElementById("clinicFlag");
last line of code doesnot return any control object.
Here's a modified snippet of my answer linked in a comment. Function returns the window object of an (i)frame with id passed (id), or null, if the (i)frame is not found. This method works only, if all the (i)frames are in the same domain. Also ids given to (i)frame elements must be unique throughout all documents involved in the window structure.
function searchFrame(id) { // id = the id of the wanted (i)frame
var result = null, // Stores the result
search = function (iframes) { // Recursively called function
var n; // General loop counter
for (n = 0; n < iframes.length; n++) { // Iterate through all passed windows in (i)frames
if (iframes[n].frameElement.id === id) { // Check the id of the (i)frame
result = iframes[n]; // If found the wanted id, store the window to result
}
if (!result && iframes[n].frames.length > 0) { // Check if result not found and current window has (i)frames
search(iframes[n].frames); // Call search again, pass the windows in current window
}
}
};
search(window.top.frames); // Start searching from the topmost window
return result; // Returns the wanted window if found, null otherwise
}
This function can find a frame or iframe with the passed id regardless where it is placed in the window structure. Also the function can be placed and called in any window. I'd put this to the main page (as global). If the method is needed in subwindows, just call with top.searchFrame(...).
Instead of ids, also names can be used, as long as they are also unique. In that case the id check in searchFrame() needs to be edited to name check.
In your case, first you need to give an id to the target iframe, then you can use the code for example like this:
var txtClinic = searchFrame('IFRAME_ID').document.getElementById('clinicFlag');
The method above might be a bit overkilling to get a single reference, but it's very helpful, if you have to get these cross-window references multiple times within different windows.
The specific task of yours could be done like this:
var txtClinic = parent.frames[1].frames[0].document.getElementById('clinicFlag');
names of the (i)frame are also handy to use with frames collection. Instead indices you can use names. Just always chain the reference starting from the main page, i.e. from top. For example:
var iframeWin = top.frames['frame2'].frames['iframe1'];
Useful reading:
window.top
window.frameElement
window.frames

JQuery & Javascript: Intermittant mis-matching of clicked div and returned div?

Thanks for giving this a look. I'll start with a quick image. Clicking on any of the red-boxed search results seems to return the <div> for the item directly above it.
Here I clicked on 1613 CAROUSEL CIR, but the event returned the id/content for the item representing 1612..
Sometimes it's even weirder, for example, every item following 1420 might point back to 1420. So it's not always a conflict with a <div> and it's immediate neighbor, although that's usually the case.
I've been unable to find any definite pattern in this behavior. Sometimes it's just one or two items in the list; sometimes most of the list is affected, with "a good portion" of results pointing to one particular div.
There's only one true consistency--typically the first several items work as expected, and short lists will be 100% correct. But really long lists (50+) are not necessarily worse than semi-long lists (20+).. :/
The code building the search results iterates over JSON data retrieved by a JQuery $.ajax() call, and this is the relevant code building the visible search results:
if( result.d.length > 0 )
{
var i=0;
for(i; i<result.d.length; i++)
{
// ..there's a bunch of irrelevant code here to set the map bounds..
// ..then I build the HTML using JQuery like this
//
var date = new Date();
var divID = "searchItemDiv" + date.getTime().toString();
var $searchItemDiv = $( "<div id='" + divID + "' class='searchItemDiv'>"+result.d[i].Description+"</div>" );
$searchItemDiv.data('itemData', result.d[i]);
$searchItemDiv.bind('click', onSearchItemClick);
$( "#searchResults" ).append($searchItemDiv);
}
}
While I don't suspect the event handler is the issue, the relevant code there looks like this:
function onSearchItemClick(event)
{
if( event.target.id.toString() !== '' )
{
// I clicked 1613, but event returned DIV with text of "1612"??
//
var item = $('#'+event.target.id.toString()).data('itemData');
alert( event.target.id.toString()+"\n"+
$('#'+event.target.id.toString()).text() );
// ..more irrelevant stuff to show a popup of property data..
}
}
FireFox, Chrome, and IE all demonstrate the same behavior, so it's not browser-specific.
I'm relatively sure this is not the product of a race condition during the render phase, but I'm not comfortable-enough with JavaScript to know that for certain.
I'm pretty baffled by this. FWIW, I'm a former Flex & C# developer and relatively new to JavaScript/JQuery development, so there may be a gotcha related JavaScript contexts and/or JQuery that I'm stepping into.
I would say, instead of binding the click function within a for-loop, just select all of the searchItemDiv's after the for-loop binds the data to them, and register a click function on all of them at once. You don't need a separate line to define variable i, just do it in the for statement. I also wouldn't try to generate random IDs with new Dates, that just seems unnecessary. Registering all click functionality at once will also make your click handler much simpler:
if( result.d.length > 0 )
{
for(var i = 0; i<result.d.length; i++)
{
// ..there's a bunch of irrelevant code here to set the map bounds..
// ..then I build the HTML using JQuery like this
// select the i'th searchItemDiv
$searchItemDiv = $($('.searchItemDiv')[i])
// give it the data
$searchItemDiv.data('itemData', result.d[i]);
$( "#searchResults" ).append($searchItemDiv);
}
// then register all the click handlers at once, very simple
$('.searchItemDiv').bind('click', function() {
var item = $(this);
alert(item.text());
});
}
--EDIT--
also, do the searchItemDivs already exist or are you trying to create them?
if you're trying to create them, you might want this in the for-loop instead:
for(var i = 0; i<result.d.length; i++)
{
// ..there's a bunch of irrelevant code here to set the map bounds..
// ..then I build the HTML using JQuery like this
// create a searchItemDiv
$searchItemDiv = $('<div class="searchItemDiv"></div>')
// give it the data
$searchItemDiv.data('itemData', result.d[i]);
$( "#searchResults" ).append($searchItemDiv);
}
I'm guessing that is what you want to do.
I think your problem depends on your searchItemDiv id.
Using the date doesn't ensure ids are unique so when you retrieve the object by id it will return an element (probably the first) with the same id.
Make sure to assign unique id on your elements.

JavaScript Conflict with Canvas font element and Local Storage display

I have a function that runs with windows onload to display a list of scores that are stored in local storage. Even if the list is empty it will display as it would when loading in a new browser.
function scoresListDisplay(){
storedEntries = [];
storedEntries = JSON.parse(localStorage.getItem("localstoragekey"));
highScoreList = game.querySelector("section#game ol.high-scores");
for(var i = 0; i < 10; i++){
var st = storedEntries[i];
gamescorelist = document.createElement('li');
gamescorelist.innerHTML = (typeof(st) != "undefined" ? st : "--" );
highScoreList.appendChild(gamescorelist);
}
}
I also have other div tags such as one containing a canvas tag for the font of the page heading or title and other div tags which are used to display a countdown timer and current score.
The list above works fine but the thing is when the list is empty the canvas element with the title at the top of the page disappears and when the list is populated by one or more values (st) the canvas element reappears and is displayed as normal. All other div elements display ok.
I'm not sure but I think the problem may have something to do with the getItem return. Although the console reports this:
TypeError: storedEntries is null
Am I missing something within the function?
If anybody could help with this I would greatly appreciate it.
Well, you see ...
storedEntries = [];
storedEntries = JSON.parse(localStorage.getItem("localstoragekey"));
You are redefining storedEntries, so the first line is useless. When localStorage is empty, JSON.parse will return null, and later you're accessing it as if it were an array.
Do it this way:
storedEntries = JSON.parse(localStorage.getItem("localstoragekey")) || [];
This means, get the value of JSON.parse and, if it is not null, 0, NaN, undefined, false or '' initialise storedEntries with it; otherwise, initialise storedEntries with [].

How to test if CSS file is linked in head

I want to test if there is a link to "css/iframeMobile.css" in an iframe on my page. Something like:
var isThere = frames['frameName'].document.head.link[href='css/iframeMobile.css'];
But I know my syntax is off. Thanks.
You can use:
var isThere = frames['frameName'].document.head.querySelectorAll("link[href='css/iframeMobile.css']").length > 0;
to get a boolean.
querySelectorAll returns an array of all the elements that you queried for, so if its length is larger than 0, such an element exists.

Categories

Resources