.textContent not working on a cloned node - javascript

I'm trying to clone a DOM element and then replace the text inside of it. Here is a very simple example.
https://codepen.io/anon/pen/rmZbPR
The issue is that the cloning appears to prevent .textContent (or .innerHTML) from working. I get the following error...
Uncaught TypeError: pCloned.textContent is not a function
Any pointers would be much appreciated.
var p = document.getElementById('para');
var pCloned = p.cloneNode(true);
// Remove this to see that the clone works correctly
pCloned.textContent('This is a cloned paragraph');
document.getElementById('list').appendChild(pCloned);
<p id="para">This is a paragraph</p>
<div id="list"></div>

textContent is not a function, but a simple get/set string property. Correct it to this:
pCloned.textContent = 'This is a cloned paragraph';

Related

Is there a way to get the exact indexOf an element in a big html string

I am working on an app with vue.js and quill.js in which I am creating some documents.
The content of a document is stored in document.content which is one giant string with a bunch of html tags in it coming straight from quill.js.
When previewing the document I'm rendering the big html string inside a div with v-html attribute like this:
<div v-html="document.content"></div>
i.e.
document.content = "<p>Hello</p><p>World</p><p>Hello World</p><p>Hello</p>"
It's rendereded as (you get the idea):
<div data-v-4ee08204>
<p>Hello</p>
<p>World</p>
<p>Hello World</p>
<p>Hello</p>
</div>
The question is:
When clicking somewhere inside the div is there a way to get the exact index of the character/word/element I've clicked on (because I need to add a comment to it)?
I've tried to attach a click listener to the div, getting the outerHTML of the target element and trying to get the indexOf document.content, but it's not always working, because there can be similar stuff inside the big string like <p>Hello</p> twice and it will get the first one only.
It's possible that my whole approach is wrong, but I'm not really sure.
Any suggestion is welcome. Thanks!
What you could do is to clone the parent element, add the comment using DOM manipulation and then use the parent element's innerHTML, here is an example:
const parent = document.querySelector('#parent');
parent.addEventListener('click', event => {
event.target.classList.add('toBeModified');
const clone = parent.cloneNode(true);
const node = clone.querySelector('.toBeModified');
const comment = document.createElement('span');
comment.textContent = '(edited)';
node.appendChild(comment);
node.classList.remove('toBeModified');
event.target.classList.remove('toBeModified');
console.log(clone.innerHTML);
});
<div id="parent">
<p>Hello</p>
<p>World</p>
<p>Hello World</p>
<p>Hello</p>
</div>
What this does is to add a class (toBeModified) to the clicked element so it can be easily found once the parent is cloned.

Get element's html tag content

Is it possible to get a node's top-level tag html via the dom api? To be clear, if I have
<div data-x="a">
<span>Hello</span>
</div>
I want to just get back <div data-x="a">
Is a crude string matching on outerHTML the best I can do, or is there a fast and direct way to achieve what I want?
If you clone the node, the innerHTML property will be empty.
For your example, a shallow clone is appropriate (pass false or don't pass anything).
// get the div element
var element = document.querySelectorAll('div')[0];
// view the outerHTML of the element
console.log('original outerHTML', element.outerHTML);
// clone the element
var clone = element.cloneNode();
// view the outerHTML of the clone
console.log('outerHTML of clone', clone.outerHTML); // has what you want
<div data-x="a">
<span>Hello</span>
</div>
.cloneNode() on MDN
You can use the outerHTML to get all of it, and the innerHTML to get the stuff just inside. Then do a string replace on the outerHTML, replacing the innerHTML with an empty string, and doing the same for the end tag.

Get text inside parent div

I'm trying to get a text from an element, which isn't the first parent of the string. i.e.
<div id="wrp">
<h1>
this is the text I want
</h1>
</div>
let's say I got the div parent by element=document.getElementById("wrap") and now I want to get it's final text without looking inside all it's children : h1 and a. just the text that I see on the site.
Is it possible? Please show me an example.
You can use both innerText or textContent, but innerText doesn't works on Firefox. So, a crossbrowser solution:
var text = element.innerText || element.textContent;
JSBin. Interesting comparision about them.
You want to chain your queries so that you get the anchor tag after you get the wrap div (assuming you will never add more divs inside the anchor tag, which would be a bit weird):
var wrap = document.getElementById("wrap");
var text = wrap.getElementsByTagName("a")[0].innerHTML;
If you take a look at the Mozilla article it has more examples on how to do this. Alternatively there is textContent but since you stated that you might add more elements at a later date, if they have text in them too then you end up needing to refactor:
var wrap = document.getElementById("wrap");
var text = document.getElementById("wrap").textContent;

adding content problem

Here I've got some trouble trying to add content in a page.
<body>
<div id="wrapper">
<div id="nav">
<ul>
<li><span>exercizeI</span></li>
<li><span>exercizeII</span></li>
<li><span>........</span></li>
<li><span>........</span></li>
</ul>
</div>
<div id="content"></div>
</div>
</body>
So I'be tried to use that piece of code and it didn't work
var table1='<table>..some content..</table>}';
$('#nav li a:eq(1)').click(function (){$('#content').innerHTML='habarlaaaa';});
then tried this one
function press(){
var but = document.getElementById('wrapper').getElementById('nav').getElementsByTagName('ul')[0].getElementsByTagName('li')[1].getElementsByTagName('a')[0];
var table1='<table>..some content..</table>}';
var content = document.getElementById('wrapper').getElementById('content');
but.onclick=function(){content.innerHTML=table1};
};
..and it became even worse by giving me:
Uncaught TypeError: Object # has no method 'getElementById'
error
Why is this happening?
BR, Stephan
Using jQuery you can use the html() function like this:
$('#nav li a:eq(1)').click(function (){$('#content').html(table1);});
To add data inside the content div:
$('#content').append("data");
The reason why your second try fails is because you are applying getElementById() to the result of the previous "getElementById()".
In your first Javascript code you were mixing concepts of DOM methods and jQuery code. Please try the following code
$('#nav li a:eq(1)').click(function (){$('#content').eq(0).html('habarlaaaa');});
the difference is that instead of
$('#content').innerHTML = '......';
You should have used
.eq(0).html('habarlaaaa')
Agreed with Vincent, the reasoning is that when you use the jQuery function, $, you don't get a DOM element, but rather you get a jQuery object representing what you've selected. There are a couple ways of doing this, one of which #vincent-ramdhanie has already mentioned. If you want to get at the actual DOM element, you can do either this:
$('#content')[0].innerHTML='habarlaaaa';
or this:
$('#content').get(0).innerHTML='habarlaaaa';
remember: innerHTML is a property of a DOM element, not a jQuery object.

element = $(element); Object expected error?

on a webpage in under developmnt i'm getting this error on IE
element = $(element);
this code is in prototype.js
Object expected
How to get rid of this error.
Update:
jQuery is also being used on site.
Is "element" the id of your element? If so try making it element = $("element")
your statement should be
element = $("id of element")
suppose you have the following code.
<div id="mainDiv">
...
</div>
To access this control, in prototype, it is
element = $("mainDiv");
UPDATE:
Based on your comment, you can combine both jquery and prototype in the same page.
var J = jQuery.noConflict();
After this statement, $("#foo") will be J("#foo").
See this stackoverflow question
You need to put a var in front of the variable assignment when the variable and element id are the same in IE.
var element = $(element);

Categories