Append / Insert Into DOM Fails for Element Node - javascript

I setup the following console.log's to make sure of what my variable contains.
console.log(globalAttributes[0])
console.log(globalAttributes[0].outerHTML)
These return:
HTMLElement {}
<code id="global-attributes:the-accesskey-attribute">accesskey</code>
And when I try either .append or .appendChild nothing shows up on my resulting HTML page. And if I try inserting as .innerHTML the text shows up as expected unrendered.
I'm using JSDOM in Node.js and
fs.writeFileSync("elements.html", prettify.prettyPrint(doc.body.innerHTML), {indent_size: 2});
Everything else is working fine. Any ideas why .append and .appendChild fail to inject the Element node?
attributesSummaryElement.textContent = "Attributes";
attributesDetailsElement.appendChild(attributesSummaryElement);
console.log(globalAttributes[0])
console.log(globalAttributes[0].outerHTML)
attributesDetailsElement.appendChild(globalAttributes[0])

Related

use QuerySelectorAll to get element in page source

I have an html page where it is completely replaced by another html. Page source has my element, but DOM does not have it.
Following is my jQuery code, which works fine:
var account = parseInt($(".adajacent_links.pd0").find("li").first().text());
Whereas following code only works before replacing the content. It does not work after the DOM is replaced.
var account = parseInt(document.querySelectorAll(".adajacent_links.pd0 > li:first-child")[0].innerText);
even document.querySelectorAll(".adajacent_links") or document.querySelector(".adajacent_links") is not returning anything . adajacent_links class is present only in the page source, but not in the DOM. How does it works fine in jQuery?

Clone HTML and remove some nodes using jQuery

I'm developing a little tool for live editing using Chrome DevTools, and I have a little button "Save" which grabs the HTML and sends it to server to update the static file (.html) using Ajax. Very simple indeed.
My problem is that I need to filter the HTML code before sending it to the server, I need to remove some nodes and I'm trying to achive this using jQuery, something like this:
// I grab all the HTML code
var html = $('<div>').append($('html').clone()).html();
// Now I need to remove some nodes using jQuery
$(html).find('#some-node').remove();
// Send the filtered HTML to server
$.post('url/to/server/blahblahblah');
I already tried this Using jQuery to search a string of HTML with no success. I can't achieve to use jQuery on my cloned HTML code.
Any idea about how to do this?
The DOM is not a string of HTML. With jQuery, you do DOM manipulation, not string manipulation.
What you're doing is
cloning the document (unnecessary because you convert it to HTML anyway),
appending that cloned document to a new div for some reason
converting the content of that div to an HTML string
converting that HTML back to DOM nodes $(html) (so we're back to the first point above)
finding and removing an element in those nodes
presumably posting the html variable to the server.
Unfortunately, the html string has not changed because you manipulated DOM nodes, not the string.
Hopefully you can see above that you're doing all sorts of conversions that have little to do with what you ultimately want.
I don't know wny you'd need to do this, but all you need is to do a .clone(), then the .find().remove(), then .html()
var result = $("html").clone(false);
result.find("#some-node").remove();
var html = result.html();
Maybe like this?
var html = $('html').clone();
html.find('#some-node').remove();

Can't make Bootstrap tooltip work when creating elements with javascript

I'm pretty new to jquery in particular and js in general, so I hope I didn't make a silly mistake.
I have the following js code:
var speechText = "Purpose of use:<br/>";
speechText += "<script>$(function(){$(\".simple\").tooltip();});</script>";
speechText += "simple use";
speechElement.innerHTML = speechText;
This function changes the content of an element on the html page.
When calling this function everything works, including displaying the link "simple use", but the tooltip doesn't appear.
I tried writing the exact thing on the html document itself, and it worked.
What am I missing?
First, Script tags inserted into the DOM using innerHTML as text, will not execute. See Can Scripts be inserted with innerHTML. Just some background on script tags, they're parsed on pageload by default in a synchronous manner meaning beginning with earlier script tags and descending down the DOM tree. However this behaviour can be altered via defer and async attributes, best explained on David Walsh's post.
You can however create a script node, assign it attribute nodes and content and append this node to an node in the DOM (or another node that is inserted into the DOM) as suggested by an answer in the aforementioned SO link (here: SO answer).
Secondly, You don't need to inject that piece of JavaScript into the DOM, you can just use that plugin assignment in the context of the string concatenation. So as an example you might refactor your code like this:
HTML
var speechText = "Purpose of use:<br/>";
speechText += "simple use";
speechElement.innerHTML = speechText;
$(function(){ $(".simple").tooltip(); });

javascript: get contents of textarea, textContent vs. innerHTML vs. innerText

I am having trouble getting the contents of a textarea with js. I feel like I've done this many times before without problems but something is throwing it off or I have a mental block.
html
<textarea id="productdescript">test copy..asdfd</textarea><button value="Enter" onclick="addProduct()">
js
function addProduct() {
var descript = document.getElementById('productdescript').textContent;
alert(descript);
}
Firefox is the only browser I have currently.
When I use textContent, the alert box appears but it is blank.
When I use value, the alert box appears and says "Undefined"
When I use innerHTML, all the HTML appears including the tags.
Also, I understand that textContent only runs in FF and for cross browser compatibility you need to do something like innerText and textContent but textContent is not working in FF. There is no jquery on this app
What is the correct cross browser way to get contents of textarea! Thanks for any suggestions.
For textarea, you could only use .value in your scenario (I tested your given code and it works fine).
.
Also,
1) keep in mind that you call this function addProduct() ONLY after your element is mentioned in the code, otherwise it will be undefined.
2) there must not be another element with id as productdescript
3) there must not be a JS variable called productdescript
This are your code?
you write document.getElementByID.... and the "D" should be written lowercase "d"
document.getElementById('productdescript').textContent;

javascript innerHTML without childNodes?

im having a firefox issue where i dont see the wood for the trees
using ajax i get html source from a php script
this html code contains a tag and within the tbody some more tr/td's
now i want to append this tbody plaincode to an existing table. but there is one more condition: the table is part of a form and thus contains checkboxe's and drop down's. if i would use table.innerHTML += content; firefox reloads the table and reset's all elements within it which isnt very userfriendly as id like to have
what i have is this
// content equals transport.responseText from ajax request
function appendToTable(content){
var wrapper = document.createElement('table');
wrapper.innerHTML = content;
wrapper.setAttribute('id', 'wrappid');
wrapper.style.display = 'none';
document.body.appendChild(wrapper);
// get the parsed element - well it should be
wrapper = document.getElementById('wrappid');
// the destination table
table = document.getElementById('tableid');
// firebug prints a table element - seems right
console.log(wrapper);
// firebug prints the content ive inserted - seems right
console.log(wrapper.innerHTML);
var i = 0;
// childNodes is iterated 2 times, both are textnode's
// the second one seems to be a simple '\n'
for(i=0;i<wrapper.childNodes.length;i++){
// firebug prints 'undefined' - wth!??
console.log(wrapper.childNodes[i].innerHTML);
// firebug prints a textnode element - <TextNode textContent=" ">
console.log(wrapper.childNodes[i]);
table.appendChild(wrapper.childNodes[i]);
}
// WEIRD: firebug has no problems showing the 'wrappid' table and its contents in the html view - which seems there are the elements i want and not textelements
}
either this is so trivial that i dont see the problem OR
its a corner case and i hope someone here has that much of expirience to give an advice on this - anyone can imagine why i get textnodes and not the finally parsed dom elements i expect?
btw: btw i cant give a full example cause i cant write a smaller non working piece of code
its one of those bugs that occure in the wild and not in my testset
thx all
You are probably running into a Firefox quirk of following the W3C spec. In the spec the whitespace between tags are "text" nodes instead of elements. These TextNodes are returned in childNodes. This other answer describes a workaround. Also Using something like JQuery makes this much easier.
I would expect this behavior in any browser as the += operand overwrites what is already in the table by definition. Two solutions:
Instead of receiving HTML code from your PHP file, have the PHP generate a list of items to add to the table. Comma/tab separated, whatever. Then use Table.addRow(), Row.addCell() and cell.innerHTML to add the items to the table. This is the way I would suggest doing it, no point in creating GUI elements in two separate files.
The other solution is to save all the form data that's already been entered to local JavaScript variables, append the table, and then reload the data into the form fields.
Well, returning a JSON object with the new data seems like the best option. Then, you can synthesize the extra table elements by using it.
In case one is forced to get plain HTML as response, it is possible to use var foo = document.createElement('div');, for example, and then do foo.innerHTML = responseText;. This creates an element that is not appended to anything, yet hosts the parsed HTML response.
Then, you can drill down the foo element, get the elements that you need and append them to the table in a DOM-friendly fashion.
Edit:
Well, I think I see your point now.
wrapper is a table element itself. The nodes reside under the tbody, a child of wrapper which is its lastChild (or you can access it via its tBodies[0] member, in Firefox).
Then, using the tBody element, I think that you would be able to get what you want.
BTW, You do not need to append the wrapper to the document before appending its children to the table, so no need to hide it etc.

Categories