How to split html code from a page into nodes - javascript

I want to read the html from a site and then split it into nodes. I tried this code:
function load() {
$(document).ready(function () {
$.get("https://example.com/index.html", function (data) {
const loadpage = async function() {
var nodes = [...data.childNodes].slice(-3);
var cont = document.getElementById("container");
var msg = nodes;
});
if(cont.innerHTML='') {
cont.insertAdjacentHTML('afterbegin', msg);
} else {
cont.innerHTML=msg;
}
};
loadpage();
});
});
}
load();
html looks like this:
<main>
<div class="msg">something</div>
<div class="msg">something</div>
<div class="msg">something</div>
<div class="msg">something</div>
<div class="msg">something</div>
<div class="msg">something</div>
</main>
the expected output should be:
<div class="msg">something</div>
<div class="msg">something</div>
<div class="msg">something</div>
since I want only the last 3 nodes.
Thank you.

It is not necessary to use async await here and you are doing it wrong
Please read How to return values from async functions using async-await from function?
Your load is also wrong and too complex. You should not add a window event handler in a function and the test to insert after if cont is empty is not useful. Your test is also not a comparison (== '' or === '') but an assignment (= '').
Add the data to a partial element and slice the result
$(document).ready(function() {
const cont = document.getElementById("container");
$.get("https://example.com/index.html", function(data) {
const div = document.createElement('div')
div.innerHTML = data; // assuming HTML string?
[...div.querySelectorAll('.msg')]
.slice(-3)
.forEach(div => cont.innerHTML += div.outerHTML);
});
});

Related

use querySelectorAll on dynamically added element

I want to query newly added div having memberCard class call but queryselectorall being static , i am not able to do so .How to resolve this problem?
var elementsToShow = document.querySelectorAll('.memberCard')
function list(){
$.ajax({
url:`http://localhost:8000/members`,
type:"GET",
success:function(members){
members.forEach(member => {
// Construct card content
content = `
<div class='memberCard'>
<div style='background-image:url("${member.image}")' class='memberImage'>
</div>
<div class='memberDetails josephine-sans'>
<h5>${member.name}</h5>
<h6>${member.batch}</h6>
</div>
</div>
`;
container.innerHTML += content;
});
}
You can use some hack i guess, update elementsToShow after success;
var elementsToShow = document.querySelectorAll('.memberCard')
function list(){
$.ajax({
url:`http://localhost:8000/members`,
type:"GET",
success:function(members){
members.forEach(member => {
// Construct card content
content = `
<div class='memberCard'>
<div style='background-image:url("${member.image}")' class='memberImage'>
</div>
<div class='memberDetails josephine-sans'>
<h5>${member.name}</h5>
<h6>${member.batch}</h6>
</div>
</div>
`;
container.innerHTML += content;
elementsToShow = document.querySelectorAll('.memberCard')
});
}
Use Event delegation and set the querySelector on the parent element.
This is an example :
<div id="button-container"></div>
// event is added for the parent of #submit-button
document.querySelector("#button-container").addEventListener('click',
function(e) {
if(e.target.id == 'submit-button') {
alert('CLICKED');
}
});
// #submit-button is dynamically created
document.querySelector("#button-container").innerHTML = '<button id="submit-
button">Submit</button>';
// click on #submit-button will now work
document.querySelector("#submit-button").click();
I suggesst you try to change your code , so you can use it this way.

Replace div contents javascript (no jquery)

Every time a selection is made from a dropdown menu, specific data is pulled from facebook and added to different divs. I am trying to update the contents of the div every time a different selection is made, however at the minute, the contents are just appended on after the initial contents.
This is the code that gets data based on a selection and creates the list from the returned data
<script>
city = document.getElementById("citySelection")
city.addEventListener("change", function() {
var selected = this.value;
var eventsList = document.getElementById("events");
if (selected == "None") {
eventsList.style.display = "none";
} else {
eventsList.style.display = "block";
};
if (selected == 'Bristol') {
getBristolEvents();
};
if (selected == 'Leeds') {
getLeedsEvents();
};
if (selected == 'Manchester') {
getManchesterEvents();
};
if (selected == 'Newcastle') {
getNewcastleEvents();
};
});
function createList(response, listId) {
var list = document.createElement('UL')
for (var i = 0; i < 10; i++) {
var events = response.data[i].name
var node = document.createElement('LI');
var textNode = document.createTextNode(events);
node.appendChild(textNode);
list.appendChild(node)
listId.appendChild(list);
}};
</script
This is the div being targeted:
<html>
<div id="events" style="display: none">
<div id="eventsDiv" style="display: block">
<div id="eventsListOne">
<h3 id='headerOne'></h3>
</div>
<div id="eventsListTwo">
<h3 id='headerTwo'></h3>
</div>
<div id="eventsListThree">
<h3 id='headerThree'></h3>
</div>
</div>
</div>
</div>
</html>
I have tried resetting the innerHtml of the div every time the function to get the data from facebook is called:
<script>
function getEventsThree(fbUrl, title) {
var listId = document.getElementById('eventsListThree');
var headerThree = document.getElementById('headerThree');
listId.innerHtml = "";
headerThree.append(title)
FB.api(
fbUrl,
'GET', {
access_token
},
function(response) {
listId.innerHtml = createList(response, listId)
}
)};
</script>
However, that still doesn't reset the contents of the div.
I've looked at other response but they all use jquery which I am not using.
Can anyone advise on the best way to fix this? Thanks.
I think your Hennessy approach is fine. Generate the inner content, then set .innerHTML.
At least one of your problems, maybe the only one, appears to be that you set .innerHTML to the return value of createList, but that function does not return anything.

document.querySelector returns null

I use the querySelector in JS to select html markup that I filled in with a JS script. However, anytime I try to store the divs with a class of .card in the const questionCard, I get null.
Why can't I select the cards?
HTML:
<div class='card-container'></div>
JS:
const questionBlock = document.querySelector('.card-container');
const questionCard = document.querySelector('.card');
function build() {
let output = [];
...some unimportant code here...
output.push(
`
<div class='card'>
<div class='question'>${current.question}</div>
<div class='answers'>${answers.join('')}</div>
</div>
`
);
})
questionBlock.innerHTML = output;
}
build();
You need to call document.querySelector('.card') after calling build(). It cannot find HTML elements that do not exist yet.
const questionBlock = document.querySelector('.card-container');
function build() {
let output = [];
...some unimportant code here...
output.push(
`
<div class='card'>
<div class='question'>${current.question}</div>
<div class='answers'>${answers.join('')}</div>
</div>
`
);
})
questionBlock.innerHTML = output;
}
build();
const questionCard = document.querySelector('.card');
An alternative to the more correct answers is:
const questionCard = document.getElementsByClassName('card');
now: questionCard is a live HTMLCollection, and questionCard[0] will be the first element with class including card

container hasChildNodes() showing null value. Why

<div id="history">
<div id="histheading" class="pull-left">History</div>
<div id='hist'><canvas id="test"></canvas></div>
</div>
var left=100;
var t=-150;
function doHistory_double()
{
var data = localStorage.getItem('HTML5TTT');
data = JSON.parse(data);
data.reverse();
var container = document.getElementById('hist');
// Clear the container
while (container.hasChildNodes())
{
container.removeChild(container.firstChild);
}
// Loop through the data
canvID = 0;
for(x in data)
{
var i=1;
var hist = data[x];
if(hist.datetime == undefined)
break;
var elem = document.createElement('div');
elem.style.marginLeft=lef + "px";
if(i==1){
elem.style.marginTop=t + "px";
}
else
elem.style.marginTop="0px";
i++;
elem.innerHTML = "<p><strong>"+hist.datetime+"</strong><br>Winner: "+hist.winner+"<br><canvas id='can"+canvID+"' width='100px' height='100px' ></canvas>";
container.appendChild(elem);
drawMiniBoard_double(document.getElementById("can"+canvID),hist.board);
canvID++;
lef+=310;
}
}
This is my javscript code. hist is a div showing history of the game.I am getting error as Cannot call method 'hasChildNodes' of null.I am getting this error after i did something using the variable left and t i.e margin-top and margin-left. Help me to solve this.
write it in a function and call it onload of document.
function deleteChildren() {
var container = document.getElementById('hist');
// Clear the container
while (container.hasChildNodes())
{
container.removeChild(container.firstChild);
}
}
<body onload="deleteChildren()">
<div id="history">
<div id="histheading" class="pull-left">History</div>
<div id='hist'><canvas id="test"></canvas></div>
</div>
</body>
its working perfectly.. check the fiddle
I have bind the click method then calling the code you provided and alert to show either we got a child inside the container or not..
--HTML--
<div id="history">
<div id="histheading" class="pull-left">History</div>
<div id='hist' onclick=f()><canvas id="test"></canvas></div>
</div>
-- JS --
function f()
{
var container = document.getElementById('hist');
// Clear the container
alert(container.hasChildNodes());
while (container.hasChildNodes())
{
container.removeChild(container.firstChild);
}
}
http://jsfiddle.net/FLC3R/

How to loop same javascript code for more than one div elements?

I have made three "boxes" and each box contains a button. When I click the button, box hiding, when click again, box appears.
This is my html code:
<div id="SC1_A_"> <!-- BOX -->
<div id="SC1_B_" onClick="SC1();" class="something"> </div> <!-- BUTTON -->
</div>
<div id="SC2_A_">
<div id="SC2_B_" onClick="SC2();" class="something"> </div>
</div>
<div id="SC3_A_">
<div id="SC3_B_" onClick="SC3();" class="something"> </div>
</div>
This is my javascript code:
<script type="text/javascript">
function SC1(){
var SC1_A = document.getElementById('SC1_A_);
var SC1_B = document.getElementById('SC1_B_);
if (SC1_A.style.display == 'block' || SC1_A.style.display == ''){
SC1_A.className = 'something';
SC1_B.className = 'something else';}
else {SC1_A.className = 'something else';
SC1_B.className = 'something';}
}
}
</script>
The example above works, but I have to make three similar scripts for each button. So I though to make something like this script below, using for loop. As you can imagine it didn't work. Any idea how can I make it work???
<script type="text/javascript">
for (i=1; i<10; i++){
function SCi(){
var SCi_A = document.getElementById('SC'+i+'_A_');
var SCi_B = document.getElementById('SC'+i+'_B_');
if (SCi_A.style.display == 'block' || SCi_A.style.display == ''){
SCi_A.className = 'something';
SCi_B.className = 'something else';}
else {SCi_A.className = 'something else';
SCi_B.className = 'something';}
}
}
</script>
Please don't down-vote if you think question is too easy, but just give me your help here!!! Thank you in advance!!!
You're on the right track, you just need to learn the right syntax for what you are trying to express:
var SC = [];
First off, to have a lot of different functions, so instead of attempting to name them differently (which you were trying to do), we are going to just store each function in a different index in the SC array.
for (var i = 1; i < 10; i++) {
SC[i] = (function () {
var SC_A = document.getElementById('SC' + i + '_A_');
var SC_B = document.getElementById('SC' + i + '_B_');
return function () {
if (SC_A.style.display === 'block' || SC_A.style.display === '') {
SC_A.className = 'something';
SC_B.className = 'something else';
} else {
SC_A.className = 'something else';
SC_B.className = 'something';
}
}
})();
}
Now, to call these functions you would do SC[1](), SC[2](), ... So you can either put that in each onclick in your HTML, or you could bind the events from the javascript.
Edit: I forgot to mention this because it isn't directly related to the syntax of the code, but the calls to 'document.getElementByIdwill not work until the document is fully loaded. So if you just put the script directly between to` tags it won't work. You have two choices. You either can keep the current code, but run it when the page loads. Or, you could restructure the code like this:
var SC = [];
for (var i = 1; i < 10; i++) {
SC[i] = (function (i) {
return function () {
var SC_A = document.getElementById('SC' + i + '_A_');
var SC_B = document.getElementById('SC' + i + '_B_');
if (SC_A.style.display === 'block' || SC_A.style.display === '') {
SC_A.className = 'something';
SC_B.className = 'something else';
} else {
SC_A.className = 'something else';
SC_B.className = 'something';
}
}
})(i);
}
What's happening here is you are calling document.getElementById every time the button is clicked, instead of just once when the function is created. Slightly less efficient, but it works.
You define each section on the page as calling the one function and passing in the name of the other .
<div id="SC1_A_"> <!-- BOX -->
<div id="SC1_B_" onClick="SC('SC1_A_');" class="something"> </div> <!-- BUTTON -->
</div>
<div id="SC2_A_">
<div id="SC2_B_" onClick="SC('SC2_A_');" class="something"> </div>
</div>
<div id="SC3_A_">
<div id="SC3_B_" onClick="SC('SC3_A_');" class="something"> </div>
</div>
There is just one function used for all of them
function SC(nameOfA){
var SCi_A = document.getElementById(nameOfA);
var SCi_B = this;
if (SCi_A.style.display == 'block' || SCi_A.style.display == ''){
SCi_A.className = 'something';
SCi_B.className = 'something else';
} else {
SCi_A.className = 'something else';
SCi_B.className = 'something';}
}
}
here you can use this function on every click:
<div id="SC1_A_"> <!-- BOX -->
<div id="SC1_B_" onClick="SC(event)" class="something"> </div> <!-- BUTTON -->
</div>
<script type="text/javascript">
function SC(event){
var SCA = event.currentTarget.parentNode;
var SCB = event.currentTarget;
................
}
</script>
Your code is defining a function named SCi 8 times. I think if you swap the first two lines you will get what you want.
You're redefining the same function (function SCi) eight times. The only version of the function that is retained is the version that's defined last. Going by your code, you're only creating a function that can work with the 8th box.

Categories

Resources