The sample code below currently gets an HTML page, and tries to read it into an array. The AJAX is working perfectly, and I can get a nodelist object successfully. Is it possible to somehow read this page into an array and not one singular object? Eventually I need to pull out every single member of this array individually as I am attempting in the for loop below:
$.ajax({
url: "/thePageToScrape.html",
dataType: 'text',
success: function(data) {
var elements = $("<div>").html(data)[0].getElementsByTagName("body");
for(var i = 0; i < elements.length; i++) {
var theText = elements.firstChild.nodeValue;
// Do something here
}
}
});
If all you want, like you stated in your comment, is to turn the NodeList into an array:
elements = Array.prototype.slice.apply(elements);
That's all, really.
If you are using JQuery, you can get a list of each node immediately below the body with
var elements = $(data).children("body").children();
or every node with
var elements = $(data).children("body *");
you can then loop over them with
$.each(elements, function(index, value) {
var text = this.text()
//..do something with text
});
Looks like $.parseHTML() method do exactly what you want:
Description: Parses a string into an array of DOM nodes.
var arrElements = $.parseHTML(data);
Related
Hello stackoverflow community, I need help with my JavaScript. How can I transfer array with id of kasce?
When I'm printing array in ajax_import.php file, it prints nothing. So probably my array is empty.
Here is my code:
function SubmitImp() {
var import_tasken = document.getElementById("import_tasken");
//import_tasken.style.display = "none";
var kasce = document.getElementsByName("impTaskCh");
var array = "";
for (i = 0; i < kasce.length; i++) {
array[i] = kasce[i].getAttribute('id');
}
$.ajax({
type: "POST",
url: 'modules/projects/ajax/ajax_import.php',
data: {
data: array,
},
success: function(data)
{
alert("Viskas ok!");
}
});
}
A couple of problems there.
First, you're not sending an array, you're sending a blank string.. Here, you put a string in array:
var array = "";
Later, you do this:
array[i] = kasce[i].getAttribute('id');
...which is trying to assign a new value to a single character of the string. You can't do that, strings are immutable in JavaScript; the line ends up not changing the string at all.
array[i] is a single character in the string. You're trying to assign a string to it.
To make array an array, use:
var array = [];
Next, and this may not be a problem, here:
data: {
data: array,
}
...you're telling jQuery to send a URI-encoded parameter called data with the value array. jQuery will call toString on array, which with a true array ends up being Array#join. That may well be what you want, you'll get something like this:
firstId,secondId,thirdId
Your PHP should look for it as $_POST['data'].
Side note: You're falling prey to The Horror of Implicit Globals because you never declare your i variable. You want to declare it.
I have what I am sure is a very straightforward question! I have an xml document and, using AJAX, I am wanting to get the values from tags with the same name into an array. XML:
<data>
<instance>
<term>Dog</term>
<clicks>11235</clicks>
</instance>
<instance>
<term>Cat</term>
<clicks>6309</clicks>
</instance>
</data>
My Javascript:
console.log(xml.getElementsByTagName("clicks")[0].childNodes[0].nodeValue);
This only seems to return the first value. How do you return them all?
Try i wrote in java, I think you have to change the array part. hope this helps.
NodeList clicks = xml.getElementsByTagName("clicks")
int[] clickArray = new int[clicks.getLength()];
for(int i=0; i<clicks.getLength();i++){
clickArray[i] = clicks[i].childNodes[0].nodeValue;
}
function test(){
var clicks = xml.getElementsByTagName("clicks");
var result = new Array();
foreach(var c in clicks){
console.log(c);
result.push(c.childNodes[0].nodeValue);
}
return result;
}
this should print all "click" tags. In your result array now are all values, but note that this just works, if the tag "structure" is always the one you posted above
You can use jQuery to get all tags, and then use .each() to get all values:
$(xml).find('clicks').each(function(){
console.log($(this).html());
});
or if you want to get an array, you can use .map() function:
var list = $(xml).find('clicks').map(function(){
return $(this).html();
}).get();
Using d3.js you can do something like this:
Define a div in your DOM <div></div>
var list = d3.select('div')
.html(xml) // set the xml content
.selectAll('clicks')
.each(function(){
console.log(this.innerHTML);
});
console.log(list); //you can do what you want with all clicks elements
I am looking to create an array of all the images in a string of HTML.
I've tried using the following but it generates errors if the complete URL path is not present in the src.
var found = $(html).find('img');
$("img").each(
function(index) {
theArray.push( $(this).attr("src") );
});
Quick run down of how to achieve this:
Open with jQuery's DOM Ready function ->
$(function(){
Create the variable found which holds a collection of the elements.
var found = $('p > img');
Create an empty Array to hold our results.
var results = new Array();
Iterate through each of the elements that we found
$.each(found, function(index,value){
For each 'value' (the item) that we find, we want to take the src, and push that src into the array.
results.push($(value).attr('src'));
Erroneous closure
});
Alert the total amount of items in the array;
alert('There is a total of '+results.length+' results in the Array.');
Alert just the src of the 3rd item we added to the array.
alert('The src of the 3rd item is: '+results[2]); //3nd item in array, indexes are 0 based
Erroneous closure
});
Hopefully this helps clear things up a bit.
You can do that with simple and plain JavaScript by creating an "instant" html element:
Create a element
Insert the string as innerHTML
Query the node
Example:
var html = "<html><body><img src='/img1.png' /><br /><img src='/img2.png' /></body></html>";
var node = document.createElement("div");
node.innerHTML = html;
for(var i=0; i < node.children.length; i += 1) {
if (node.children[i].tagName === 'IMG') {
alert(node.children[i].src)
};
}
Just try this:
var imgArray = $('img'),
srcArray = [];
console.log(imgArray); // array of imgs
$.each(imgArray, function() {
srcArray.push(this.src));
});
What is the cleanest way to put the source attribute string of all images within a div into an array?
I was hoping this would work -
var imageSourceArray = $("#leDiv img").attr('src');
alert(imageSourceArray[3]); //not alerting the source, boo hoo.
Do I need to loop through $("#leDiv img") and add each src string to an array individually? Or is there a more elegant way to do this?
You can use jQuery's map function which is described as:
Pass each element in the current matched set through a function, producing a new jQuery object containing the return values.
For your example:
var mySources = $('#leDiv img').map(function() {
return $(this).attr('src');
}).get();
Edit: Far more elegant solution, there's obviously still some looping involved internally:
var img_sources = $('#leDiv img').map(function(){ return $(this).attr('src') });
You will in fact need to loop over the collection and add sources individually.
var img_sources = [];
$('#leDiv img').each(function(i,e){
img_sources.push($(e).attr('src'))
})
Some background: jQuery.fn.attr() maps to jQuery.access() internally, the key part of which looks like this:
function( elems, key, value, exec, fn, pass ) {
var length = elems.length;
// setter functions omitted here …
// Getting an attribute
return length ? fn( elems[0], key ) : undefined;
}
Note the elems[0] part – only the first item in the collection is fed to the subsequent callback function (jQuery.attr() in fact) responsible for extracting the information.
var imageSourceArray = [];
$('#leDiv img').each(function(){
var src = $(this).attr("src");
imageSourceArray.push(src);
});
alert(imageSourceArray[3]);
you already have the src in a collection when you fetch the the images. It may be more efficient to not store the src attributes in another array:
$('#leDiv img').each(function(i,e){
var dosomethingwith = $(e).attr('src');
})
or you could do:
var ImageCol = $('#leDiv img');
alert(ImageCol[3].attr('src'));
I've a function that takes an object as a parameter, and uses the structure of the object to create nested DOM nodes, but I receive the following error:
http://new.app/:75NOT_FOUND_ERR: DOM Exception 8: An attempt was made to reference a Node in a context where it does not exist.
What I would like my function to do, is, when supplied with a suitable object as a parameter, example:
var nodes = {
tweet: {
children: {
screen_name: {
tag: "h2"
},
text: {
tag: "p"
}
},
tag: "article"
}
};
It would create the following DOM nodes:
<article>
<h2></h2>
<p></p>
</article>
Here is my attempt so far:
function create(obj) {
for(i in obj){
var tmp = document.createElement(obj[i].tag);
if(obj[i].children) {
tmp.appendChild(create(obj[i].children)); /* error */
};
document.getElementById("tweets").appendChild(tmp);
};
};
I'm already struggling!
Ideally I'd like to eventually add more child key's to each object, not just tag, but also id, innerHTML, class etc.
Any hel would be much appreciated, though please: I'm sure a framework or library could do this for me in just a few lines of code, or something similar, but I'd prefer not to use one for this particular project.
If you could briefly explain your answers too it'd really help me learn how this all works, and where I went wrong!
Thank you!
NB: I've changed and marked the line in my function that the error message is talking about.
I changed it from:
mp.appendChild(obj[i].children);
to:
mp.appendChild(create(obj[i].children));
This is because I want any nested keys in the children object to also be created, so screen_name had a children key, they too would be created. Sorry, I hope you can understand this!
I'm looking at http://jsperf.com/create-nested-dom-structure for some pointers, this may help you too!
Your "create" function is going to have to be written recursively.
To create a node from your data (in general), you need to:
Find the "tag" property and create a new element
Give the element the "id" value of the element (taken from the data)
For each element in "children", make a node and append it
Thus:
function create(elementDescription) {
var nodes = [];
for (var n in elementDescription) {
if (!elementDescription.hasOwnProperty(n)) continue;
var elem = elementDescription[n];
var node = document.createElement(elem.tag);
node.id = n; // optional step
var cnodes = create(elem.children);
for (var c = 0; c < cnodes.length; ++c)
node.appendChild(cnodes[c]);
nodes.push(node);
}
return nodes;
}
That will return an array of document elements created from the original "specification" object. Thus from your example, you'd call:
var createdNodes = create(nodes);
and "createdNodes" would be an array of one element, an <article> tag with id "tweets". That element would have two children, an <h2> tag with id "screen_name" and a <p> tag with id "text". (Now that I think of it, you might want to skip the "id" assignment unless the node description has an explicit "id" entry, or something.)
Thus if you have a <div> in your page called "tweets" (to use your example, though if so you'd definitely want to cut out the "id" setting part of my function), you'd add the results like this:
var createdNodes = create(nodes), tweets = document.getElementById('tweets');
for (var eindex = 0; eindex < createdNodes.length; ++eindex)
tweets.appendChild(createdNodes[eindex]);
I added a function appendList that accepts a list of elements, and the container to append to. I removed the append to "tweets" part out of the create function to more effectively separate your code.
function create(obj) {
var els = [];
for(i in obj){
var tmp = document.createElement(obj[i].tag);
var children;
if(children = obj[i].children) {
var childEls = create(children);
appendList(childEls, tmp);
}
els.push(tmp);
};
return els;
};
function appendList(list, container){
for(var i = 0, el; el = list[i]; i++){
container.appendChild(el);
}
};
// gets an array of root elements populated with children
var els = create(nodes);
// appends the array to "tweets"
appendList(els, document.getElementById("tweets"));
Building on the previous answer:
I think you still need to create the element you're trying to append:
tmp.appendChild(children[prop].tag);
should be
tmp.appendChild(document.createElement(children[prop].tag));
function create(obj) {
for(i in obj){
var tmp = document.createElement(obj[i].tag);
var children;
if(children = obj[i].children) {
for(var prop in children)
tmp.appendChild(document.createElement(children[prop].tag));
}
document.getElementById("tweets").appendChild(tmp);
};
};