so im making this web app with api from https://www.football-data.org/
so i make the template for the api content with the dom. but there's one part that are not being shown
function showStanding(data) {
let standings = ``;
const standingElement = document.getElementById("standings");
/* Jika dilihat melalui console.log, seharusnya kakak me looping data.standings[0].table, karena
disitulah object team berada
*/
data.standings[0].table.forEach((standing) => {
console.log(standing);
standings += `
<div class="standing__team">
<div class="favtim">
<img src="${standing.team.crestUrl.replace(
/^http:\/\//i, 'https://')}" alt="Logo team" />
<h3><a class="link" href="#team?id=${standing.team.id}">${standing.team.name}</a></h3>
<h3 class="point">Point: <span>${standing.points}</span></h3>
</div>
</div>
`;
});
// di line ke 23 dan 24 seharusnya competition, bukan competitions
standingElement.innerHTML = `
<div class="standing__header blue lighten-3">
<h1>${data.competition.name}</h1>
<p class="standing__header--place">${data.competition.area.name}</p>
<p class="standing__header--time">${data.season.startDate} - ${data.season.endDate}</p>
</div>
`;
document.querySelectorAll(".link").forEach(function (link) {
link.addEventListener("click", function (e) {
urlTeamParam = e.target.getAttribute("href").substr(9);
loadpage();
});
});
}
so this is the code for the templating the api
the result
so in the result there are a element which is base on the url. but there's one part that are not showing
so i tried to console.log() it and it appear on the console. how can i show it in the browser window?
the console
can you help me how to solve this problem?
Related
Please help a little bit.
I have a list of 7 events displayed already with Angularjs. I'd like when I click on the <h2> (the event name) of some event, to open an ovelay that displays the same data from the database but only for this event which is clicked.
I'm sure that 'filter' will do the work but it seems I'm doing something wrong.
Here is my code. The ng-app and ng-controller are in the <main> tag.
Angularjs version: 1.7.9
My Html:
<main ng-app="eventsApp" ng-controller="eventsCtrl">
<!-- Overlay that holds and displays a single event -->
<div>
<div ng-repeat="x in singlePageEvent | filter:hasName(x.eventName)">
<div>
<img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
<h2 class="event-name">{{x.eventName}}</h2>
<p>{{x.eventTime}}</p>
<p>{{x.eventPlace}}</p>
</div>
</div>
</div>
<!-- A list with all the events -->
<div ng-repeat="x in events">
<div>
<img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
<h2 ng-click="singleEventOpen(x)" class="event-name">{{x.eventName}}</h2>
<p>{{x.eventTime}}</p>
<p>{{x.eventPlace}}</p>
</div>
</div>
</main>
My script:
let eventsApp = angular.module('eventsApp', []);
this filter below is not working at all. It continues to show all the events.
eventsApp.filter('hasName', function() {
return function(events, evName) {
var filtered = [];
angular.forEach(events, function(ev) {
if (ev.eventName && ev.eventName.indexOf(evName) >-1) {
filtered.push(ev);
}
});
return filtered;
}
});
eventsApp.controller('eventsCtrl', function($scope, $http) {
let x = window.matchMedia("(max-width: 450px)");
let singleEventOverlay = angular.element(document.querySelector('div.single-event.overlay'));
let singleEvent = singleEventOverlay;
function responsiveEventImages(x) { //this displays the list with events
if (x.matches) {
$http.get('./includes/events_res.inc.php').then(function(response) {
$scope.events = response.data.events_data;
});
} else {
$http.get('./includes/events.inc.php').then(function(response) {
$scope.events = response.data.events_data;
});
}
}
...and then by invoking singleEventOpen() the overlay appears, but it displays all the data, not just the clicked event
$scope.singleEventOpen = function(singleEvent) {
let clickedEvent = singleEvent.eventName; //I got the value of each h2 click thanx to #georgeawg but now what?
console.log("Fetching info for ", singleEvent.eventName);
$http.get('./includes/single_event.inc.php').then(function(response) {
$scope.singlePageEvent = response.data.events_data;
});
singleEventOverlay.removeClass('single-event-close').addClass('single-event-open');
}
});
The php file with the database extraction is working fine so I won't display it here.
What should I do to make the overlay display only the event which <h2> is clicked?
Here is a pic of the list with events
Here is a pic of the overlay
Thanx in advance.
EDITED
I got the value of each h2 click thanx to #georgeawg but now what?
UPDATE
Hey, thanx a lot #georgeawg . After many attempts I finally did this:
$scope.singleEventOpen = function(singleEvent) {
$http.get('./includes/single_event.inc.php').then(function(response) {
let allEvents = response.data.events_data;
for (var i = 0; i < allEvents.length; i++) {
singleEvent = allEvents[i];
}
});
console.log('Fetching data for', singleEvent);
$scope.ex = singleEvent;
});
And it works well.
Change the ng-click to pass an argument to the singleEventOpen function:
<div ng-repeat="x in events">
<div>
<img ng-src="{{x.eventImgSrc}}" alt="{{x.eventImgName}}"/>
<h2 ng-click="singleEventOpen(x)" class="event-name">{{x.eventName}}</h2>
<p>{{x.eventTime}}</p>
<p>{{x.eventPlace}}</p>
</div>
</div>
Then use that argument:
$scope.singleEventOpen = function(singleEvent) {
console.log("Fetching info for ", singleEvent.eventName);
//...
//Fetch and filter the data
$scope.ex = "single item data";
}
Adding an argument is the key to knowing which <h2> element was clicked.
Update
Don't use ng-repeat in the overlay, just display the single item:
<!-- Overlay that holds and displays a single event -->
̶<̶d̶i̶v̶ ̶n̶g̶-̶r̶e̶p̶e̶a̶t̶=̶"̶x̶ ̶i̶n̶ ̶s̶i̶n̶g̶l̶e̶P̶a̶g̶e̶E̶v̶e̶n̶t̶ ̶|̶ ̶f̶i̶l̶t̶e̶r̶:̶h̶a̶s̶N̶a̶m̶e̶(̶x̶.̶e̶v̶e̶n̶t̶N̶a̶m̶e̶)̶"̶>̶
<div ng-if="ex"">
<div>
<img ng-src="{{ex.eventImgSrc}}" alt="{{ex.eventImgName}}"/>
<h2 class="event-name">{{ex.eventName}}</h2>
<p>{{ex.eventTime}}</p>
<p>{{ex.eventPlace}}</p>
</div>
</div>
I am new in Unit Test JS. I want create test in jasmine. I dynamically create element HTML in JS.
data.map((channel) => {
const { url, width, height } = channel.thumbnails.medium;
const { title, customUrl } = channel;
const { subscriberCount, videoCount, viewCount } = channel.statistics;
output += `
<li class="channel-wrraper">
<a href='${customUrl}' target="_blank">
<img src='${url}' alt="img-channel" height='${width}' width='${height}' class="channel-img">
</a>
<p class="channel-title">${title}</p>
<div class="channel-statistic">
<div class="statistic-wrraper">
<span class="statistic-name">subscribers:</span>
<span class="subscirber-count">${formatNumber(subscriberCount)}</span>
</div>
<div class="statistic-wrraper">
<span class="statistic-name">videos:</span>
<span class="video-count">${formatNumber(videoCount)}</span>
</div>
<div class="statistic-wrraper">
<span class="statistic-name">views:</span>
<span class="veiw-count">${formatNumber(viewCount)}</span>
</div>
</div>
</li>`
});
channelsList.innerHTML = output;
Then some element will be ordered. This is sort function:
const list = document.querySelector('.channels-list');
const sortNumber = (selector) => {
[...list.children]
.sort((a,b) => a.querySelector(selector).innerText.replace(/,/g, '') - b.querySelector(selector).innerText.replace(/,/g, ''))
.map(node => list.appendChild(node))
}
I read about JSDOM and I watched the tutorials in which they tested the DOM, however, these elements were in the html file...
I want test function sortNumber
But I don`t know how start this task..
You can try using jsdom-global, then you will have document.body setup for you:
require('jsdom-global')()
// you can now use the DOM
document.body.innerHTML = 'put your html here'
An alternative will be to use jest, which comes with JSDOM configured as default
I'm trying to wrap my head around this PubNub ChatEngine example using Angular for first time https://github.com/pubnub/chat-engine-examples/tree/master/angular/simple
In demo when you click on user from the list new channel with random name is generated and user invited to it. So if you leave chat click on user again you connect to new channel.
I'm trying to do 1-1 chat rooms, that you could leave than join back, so changed channel name to be clicked user uuid. Now if I leave the channel, join back to it and try to send message it's not being shown in list, though it's being sent and user you are chatting with receives it.
In console I'm getting "Uncaught (in promise) TypeError: Converting circular structure to JSON" when starting to type (as have chat engine typing indicator running) and after submit.
I guess that's something to do with removing chat from global scope using splice() method and after joining back new chat being added. It works in demo because there are getting new channel each time and removing it, but not if using same channel now.
I tried to use splice() instead to see what happens. If I close chat and join back to it, it stays in DOM, and new one is added to scope, so have two same chat elements in DOM. If I type and send message on second one, it's not being displayed at it, but instead on first one that tried to close.
How could I get this working properly, can splice() be used in my case and I'm missing something else that is causing the error?
$scope.leave = (index) => {
$scope.chat.leave();
$scope.chats.splice(index, 1);
//$scope.chats.slice(index, 1);
//$scope.chats.splice( $scope.chats.indexOf($scope.chat), 1 );
}
angular.module('chatApp', ['open-chat-framework'])
.run(['$rootScope', 'ngChatEngine', function($rootScope, ngChatEngine) {
$rootScope.ChatEngine = ChatEngineCore.create({
publishKey: 'pub-c-d8599c43-cecf-42ba-a72f-aa3b24653c2b',
subscribeKey: 'sub-c-6c6c021c-c4e2-11e7-9628-f616d8b03518'
}, {
debug: true,
globalChannel: 'chat-engine-angular-simple'
});
// bind open chat framework angular plugin
ngChatEngine.bind($rootScope.ChatEngine);
// set a global array of chatrooms
$rootScope.chats = [];
}])
.controller('Chat', function($scope) {
$scope.chat.plugin(ChatEngineCore.plugin['chat-engine-typing-indicator']({
timeout: 5000
}));
// every chat has a list of messages
$scope.messages = [];
// we store the id of the lastSender
$scope.lastSender = null;
// leave a chatroom and remove from global chat list
$scope.leave = (index) => {
$scope.chat.leave();
$scope.chats.splice(index, 1);
}
// send a message using the messageDraft input
$scope.sendMessage = () => {
$scope.chat.emit('message', {
text: $scope.messageDraft
});
$scope.messageDraft = '';
}
// when we get notified of a user typing
$scope.chat.on('$typingIndicator.startTyping', (event) => {
event.sender.isTyping = true;
});
// when we get notified a user stops typing
$scope.chat.on('$typingIndicator.stopTyping', (event) => {
event.sender.isTyping = false;
});
// function to add a message to messages array
let addMessage = (payload, isHistory) => {
// if this message was from a history call
payload.isHistory = isHistory;
// if the last message was sent from the same user
payload.sameUser = $scope.messages.length > 0 && payload.sender.uuid == $scope.messages[$scope.messages.length - 1].sender.uuid;
// if this message was sent by this client
payload.isSelf = payload.sender.uuid == $scope.me.uuid;
// add the message to the array
$scope.messages.push(payload);
}
// if this chat receives a message that's not from this sessions
$scope.chat.search({
event: 'message'
}).on('message', function(payload) {
// render it in the DOM with a special class
addMessage(payload, true);
})
// when this chat gets a message
$scope.chat.on('message', function(payload) {
// render it in the DOM
addMessage(payload, false);
});
})
.controller('OnlineUser', function($scope) {
// create a new chat
$scope.newChat = function(user) {
// define a channel
let chan = user.uuid;
// create a new chat with that channel
let newChat = new $scope.ChatEngine.Chat(chan);
// we need to auth ourselves before we can invite others
newChat.on('$.connected', () => {
// this fires a private invite to the user
newChat.invite(user);
// add the chat to the list
$scope.chats.push(newChat);
});
};
})
.controller('ChatAppController', function($scope) {
// create a user for myself and store as ```me```
$scope.ChatEngine.connect(new Date().getTime(), {}, 'auth-key');
$scope.ChatEngine.on('$.ready', (data) => {
$scope.me = data.me;
$scope.me.plugin(ChatEngineCore.plugin['chat-engine-random-username']($scope.ChatEngine.global));
$scope.ChatEngine.global.plugin(ChatEngineCore.plugin['chat-engine-online-user-search']());
// when I get a private invit
$scope.me.direct.on('$.invite', (payload) => {
let chat = new $scope.ChatEngine.Chat(payload.data.channel);
chat.onAny((a,b) => {
console.log(a)
});
// create a new chat and render it in DOM
$scope.chats.push(chat);
});
// bind chat to updates
$scope.chat = $scope.ChatEngine.global;
// hide / show usernames based on input
$scope.userSearch = {
input: '',
fire: () => {
// get a list of our matching users
let found = $scope.ChatEngine.global.onlineUserSearch.search($scope.userSearch.input);
// hide every user
for(let uuid in $scope.chat.users) {
$scope.chat.users[uuid].hideWhileSearch = true;
}
// show all found users
for(let i in found) {
$scope.chat.users[found[i].uuid].hideWhileSearch = false;
}
}
};
$scope.userAdd = {
input: '',
users: $scope.userAdd,
fire: () => {
if($scope.userAdd.input.length) {
$scope.userAdd.users = $scope.ChatEngine.global.onlineUserSearch.search($scope.userAdd.input);
} else {
$scope.userAdd.users = [];
}
}
};
});
});
<div class="container-fluid" ng-controller="ChatAppController">
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-block">
<h4 class="card-title">ChatEngine</h4>
<p class="card-text">Your are {{me.state.username}} with uuid {{me.uuid}}</p>
</div>
<ul id="online-list" class="list-group list-group-flush">
<li class="list-group-item" ng-repeat="(uuid, user) in chat.users" ng-hide="user.hideWhileSearch" ng-controller="OnlineUser">
{{user.state.username}}
<span class="show-typing" ng-show="user.isTyping">is typing...</span>
</li>
</ul>
<div class="card-block">
<form class="send-message" ng-submit="userSearch.fire()">
<div class="input-group">
<input id="usernameSearch" type="text" class="form-control message" placeholder="Search for Username" ng-change="userSearch.fire()" ng-model="userSearch.input">
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">Search</button>
</span>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<div id="chats" class="row" ng-repeat="chat in chats" ng-controller="Chat">
<div class="chat col-xs-12">
<div class="card">
<div class="card-header">
<div class="col-sm-6">
{{chat.channel}}
</div>
<div class="col-sm-6 text-right">
x
</div>
</div>
<ul class="list-group list-group-flush online-list-sub">
<li class="list-group-item" ng-repeat="(uuid, user) in chat.users" ng-hide="user.hideWhileSearch" ng-controller="OnlineUser">
{{user.state.username}}
<span class="show-typing" ng-show="user.isTyping">is typing...</span>
</li>
</ul>
<div class="card-block">
<div class="log">
<div ng-repeat="message in messages" ng-class="{'hide-username': message.sameUser, 'text-muted': message.isHistory, 'text-xs-right': !message.isSelf}">
<p class="text-muted username">{{message.sender.state.username}}</p>
<p>{{message.data.text}}</p>
</div>
</div>
<p class="typing text-muted"></p>
<form class="send-message" ng-submit="sendMessage(chat)">
<div class="input-group">
<input ng-model="messageDraft" ng-change="chat.typingIndicator.startTyping()" type="text" class="form-control message" placeholder="Your Message...">
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">Send</button>
</span>
</div>
</form>
</div>
<hr />
<div class="card-block">
<h6>Add a user to this chat</h6>
<fom ng-submit="userAdd.fire()">
<div class="input-group">
<input id="usernameSearch" type="text" class="form-control message" placeholder="Add User" ng-change="userAdd.fire()" ng-model="userAdd.input">
</div>
</form>
<ul class="list-group list-group-flush online-list-sub">
<li class="list-group-item" ng-repeat="(uuid, user) in userAdd.users" ng-controller="OnlineUser">
{{user.state.username}}
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Issue is resolved by upgrading to the latest ChatEngine version. As per the ChatEngine github repo issue:
it's working correctly with chat-engine#0.9.5, I was using chat-engine#0.8.4
I am working on a browser game. I have lots of upgrades, crafting, planets, etc that I generate with jS (1 box (or square?) PER EACH item). Here is a mini snippet from my game, displaying my current method of generating HTML
JSFiddle example
I do a simple loop and insert as many boxes as there are upgrades
for(i = 0; i < 9; i ++)
Then, I put a gigantic HTML code block in a function, and use arrays to identify upgrades ID, name, info...
Is this a good practice to generate loads of HTML content? If not, what can I do to improve it?
Also, I started "coding" a game with one main goal to learn JS. If you have better solutions, but they include a lib (jQuery, etc) then you can post it, but I'm going pure jS here. Thanks!
-- Update --
I've been learning lots of JS in the past year. #DoXicK provided a great example a while ago but I didn't understand it then. This is the final rendering method I come up with, thanks to his examples, and I guess I'll stick with it:
JS:
const game = {};
// make our life easier
const $ = key => document.getElementById(key);
const render = (key, str) => $(key).insertAdjacentHTML("beforeend", str);
// a function that returns upgrades html content
const html = self => `
<div class="some-class" id="${self.id}">
<h2>${self.name}</h2>
<p>${self.damage}</p>
</div>
`;
// object containing each upgrades template
const template = {
laserGun: {
id: "laserGun",
name: "Laser Gun",
damage: 10
},
plasmaGun: {
id: "plasmaGun",
name: "Plasma Gun",
damage: 30
}
};
// Upgrade class
class Upgrade {
constructor(upg) {
this._id = upg.id;
this._name = upg.name;
this._damage = upg.damage;
}
get id() {return this._id;}
get name() {return this._name;}
get damage() {return this._damage;}
generate() {
// find div with upgrade id, and inject it's html content inside
render("upgrade", html(this));
}
static make(key) {
game.upgrade[key] = new Upgrade(template[key]);
game.upgrade[key].generate();
}
}
let laserGun = Upgrade.make("laserGun");
HTML:
<div class="upgrade-container" id="upgrade">
I hope you find it helpful!
As i already explained in comments, your code will become quite unmaintainable if you keep it as spaghetti code like that.
I've made an updated example which does the exact same thing as you did, just with a bit of updated javascript and by making a javascript-component out of your "template".
https://jsfiddle.net/7L8e5kmg/3/
class UpgradeBlock {
constructor(props) {
this.props = props;
}
render() {
let { Id, Name, Info, Res } = this.props;
// basically:
// let Id = this.props.Id;
// let Name = this.props.Name;
// etc
return (`
<div class="hud-item" id="${Id}">
<img src="client/img/${Id}.png" id="${Id}Img" />
<div class="hud-tooltip f16 fwhite">
<div class="hud-tt-header-container">
<div class="hud-tt-info-container">
<div class="col-full">${Name}</div>
<div class="col-half">
<img style="vertical-align: text-bottom;" src="img/${Res}16.png" />
<span id="${Id}Cost"></span>
</div>
<div class="col-half">
+<span id="${Id}dmgPerLv"></span>
<img style="vertical-align: text-bottom;" src="client/img/character/dps16.png" />
</div>
</div>
<div class="hud-tt-lv-container">
<canvas id="${Id}Bar" width="64px" height="64px"></canvas>
</div>
</div>
<hr/>
<div class="hud-tt-info-container">
<div class="col-half fwhite f16">
<img style="vertical-align: text-bottom" src="client/img/character/dps16.png" />
<span id="${Id}Dmg"></span>
</div>
<div class="col-half fgrey f10"><span class="fwhite f16" id="${Id}ofTotal"></span> of total</div>
<div class="col-full fgrey f10">${Info}</div>
<div class="col-full f10" id="${Id}click"></div>
</div>
</div>
</div>
`)
}
}
You use it by doing:
let upgrade = {
Id: 'id',
Name: 'name',
Info: 'info',
Res: 'res'
};
let html = new UpgradeBlock(upgrade).Render()
For people that do react: yes, it is intended to steer that way.
There's a page with some HTML as follows:
<dd id="fc-gtag-VARIABLENAMEONE" class="fc-content-panel fc-friend">
Then further down the page, the code will repeat with, for example:
<dd id="fc-gtag-VARIABLENAMETWO" class="fc-content-panel fc-friend">
How do I access these elements using an external script?
I can't seem to use document.getElementByID correctly in this instance. Basically, I want to search the whole page using oIE (InternetExplorer.Application Object) created with VBScript and pull through every line (specifically VARIABLENAME(one/two/etc)) that looks like the above two into an array.
I've researched the Javascript and through trial and error haven't gotten anywhere with this specific page, mainly because there's no tag name, and the tag ID always changes at the end. Can someone help? :)
EDIT: I've attempted to use the Javascript provided as an answer to get results, however nothing seems to happen when applied to my page. I think the tag is ALSO in a tag so it's getting complicated - here's a major part of the code from the webpage I will be scanning.
<dd id="fc-gtag-INDIAN701" class="fc-content-panel fc-friend">
<div class="fc-pic">
<img src="http://image.xboxlive.com/global/t.58570942/tile/0/20400" alt="INDIAN701"/>
</div>
<div class="fc-stats">
<div class="fc-gtag">
<a class="fc-gtag-link" href='/en-US/MyXbox/Profile?gamertag=INDIAN701'>INDIAN701</a>
<div class="fc-gscore-icon">3690</div>
</div>
<div class="fc-presence-text">Last seen 9 hours ago playing Halo 3</div>
</div>
<div class="fc-actions">
<div class="fc-icon-actions">
<div class="fc-block">
<span class="fc-buttonlabel">Block User</span>
</div>
</div>
<div class="fc-text-actions">
<div class="fc-action"> </div>
<span class="fc-action">
View Profile
</span>
<span class="separator-icon">|</span>
<span class="fc-action">
Compare Games
</span>
<span class="separator-icon">|</span>
<span class="fc-action">
Send Message
</span>
<span class="separator-icon">|</span>
<span class="fc-action">
Send Friend Request
</span>
</div>
</div>
</dd>
This then REPEATS, with a different username (the above username is INDIAN701).
I tried the following but clicking the button doesn't yield any results:
<script language="vbscript">
Sub window_onLoad
Set oIE = CreateObject("InternetExplorer.Application")
oIE.visible = True
oIE.navigate "http://live.xbox.com/en-US/friendcenter/RecentPlayers?Length=12"
End Sub
</script>
<script type="text/javascript">
var getem = function () {
var nodes = oIE.document.getElementsByTagName('dd'),
a = [];
for (i in nodes) {
(nodes[i].id) && (nodes[i].id.match(/fc\-gtag\-/)) && (a.push(nodes[i]));
}
alert(a[0].id);
alert(a[1].id);
}
</script>
<body>
<input type="BUTTON" value="Try" onClick="getem()">
</body>
Basically I'm trying to get a list of usernames from the recent players list (I was hoping I wouldn't have to explain this though :) ).
var getem = function () {
var nodes = document.getElementsByTagName('dd'),
a = [];
for (var i in nodes) if (nodes[i].id) {
(nodes[i].id.match(/fc\-gtag\-/)) && (a.push(nodes[i].id.split('-')[2]));
}
alert(a[0]);
};
please try it by clicking here!
var getem = function () {
var nodes = document.getElementsByTagName('dd'),
a = [];
for (var i in nodes) if (nodes[i].id) {
(nodes[i].id.match(/fc\-gtag\-/)) && (a.push(nodes[i]));
}
alert(a[0].id);
alert(a[1].id);
};
try it out on jsbin
<body>
<script type="text/javascript">
window.onload = function () {
var outputSpan = document.getElementById('outputSpan'),
iFrame = frames['subjectIFrame'];
iFrame.document.location.href = 'http://live.xbox.com/en-US/friendcenter/RecentPlayers?Length=1';
(function () {
var nodes = iFrame.document.getElementsByTagName('dd'),
a = [];
for (var i in nodes) if (nodes[i].id) {
(nodes[i].id.match(/fc\-gtag\-/)) && (a.push(nodes[i].id.split('-')[2]));
}
for (var j in a) if (a.hasOwnProperty(j)) {
outputSpan.innerHTML += (a[j] + '<br />');
}
})();
};
</script>
<span id="outputSpan"></span>
<iframe id="subjectIFrame" frameborder="0" height="100" width="100" />
</body>
What does "I can't seem to use document.getElementsByID correctly in this instance" mean? Are you referring to the fact that you are misspelling getElementByID?
So...something like this (jQuery)?
var els = [];
$('.fc-content-panel.fc-friend').each(function() {
els.push(this));
});
Now you have an array of all the elements that have both of those classes.