lastChild not working - javascript

I have the following code:
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8"/>
<script type = "text/javascript" src = "js/jquery.js" ></script>
</head>
<body>
<div id = 'div'>
<div id = "1">
</div>
<div id = "2">
</div>
</div>
</body>
</html>
My JavaScript code is:
$(document).ready(function(){
var lastcommentq = document.getElementById('div').lastChild.id;
alert(lastcommentq);
});
It should alert the id of the lastchild of the div with the id 'div' which is '2' but I am getting the alert as "undefined". I don't know what I have done wrong. Please help me.

Your elements probably have text nodes around them, so the last child node of the outer <div> won't necessarily have an "id" attribute.
I'm not sure if all browsers support it, but there's a "lastElementChild" property that explicitly gets only elements, and not things like comment nodes or text nodes. Failing that, you could just loop through the node list looking for type 1 nodes.

is this your wanted behaivour?
$(document).ready(function(){
var lastchild = $("div").last().attr("id")
alert(lastchild);
});
<div id="div">
<div id ="1">
</div>
<div id="2">
</div>
</div>
check out this fiddle for live example
http://jsfiddle.net/sHgbF/

In jquery:
$(function(){
alert($("#div :last-child").attr('id'));
});

The jQuery way:
// assuming the last child is always a div
var lastcommentq = $('#div > div:last-child').attr('id');
// alternatively
var lastcommentq0 = $('#div').children('div').last().attr('id');
The JavaScript way:
var lastcommentq = document.getElementById('div').lastElementChild.id;
Note that this works in all modern browsers and IE 9+. See lastElementChild on MDN.

this is what I would have done, but I'm not clear as to if it's what you want:
$(function () {
var lastchild = $('#div div:last-child').attr('id');
alert(lastchild);
});
http://jsfiddle.net/pFjPS/
also, I don't believe classes or ids can start with numbers, so your markup is probably not valid
edit :
HTML5 supports it, but is not generally recommended.

I would use this approach, since ID is a property and not an attribute.
$(function () {
var lastchild = $('#div div:last-child').prop('id');
alert(lastchild);
});

Related

How to set CSS class property in Javascript?

I'm trying change CSS class property value. I'm using this soluction:
let pizzas = document.querySelectorAll('.pizza');
pizzas.forEach( pizzaElement => pizzaElement.style.display = 'none' );
Anyone has a solution without use iteration?
It's better to use classList API with possibility to add, remove or toggle CSS classes: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
let pizzas = document.querySelectorAll('.pizza');
pizzas.forEach( pizzaElement => pizzaElement.classList.add('d-none') );
jsfiddle
EDIT:
Please describe exactly where you want to use it. If you do not want to change the property of any event it is unnecessary to do with JS. You can overwrite css or add a new class ..
if your using pure JavaScript You can use this code:
let pizzas = document.querySelectorAll('.pizza');
pizzas[0].style.display = 'none';
pizzas[1].style.display = 'none';
pizzas[2].style.display = 'none';
or if you are using JQuery you can use this:
$(document).ready(function(){
$('.pizza').css('display','none');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<DOCTYPE html>
<head>
</head>
<body>
<div class="pizza">Some Text</div>
<div class="pizza">Some Other Text</div>
<div class="pizza">Text</div>
</body>
</html>

How to built a text array of the document content with javascript

Hi how can I extract the text of an document as an array within javascript.
It´s easy to get the innerHTML, but I do not get the text before and after the div for example.
This should be the output:
[0]=before div
[1]=innerHTML
[2]=aferHTML
[3]=before div2
[4]=innerHTML2
[5]=aferHTML2
Of the following document:
<html><head>
<body>
before div <div>innerHTML </div>aferHTML
before div2 <div>innerHTML2 </div>aferHTML2
</body></html>
I found this link, but it does not get the text before and after the elements as well:
How to get all text from all tags in one array?
You scenario is not clear. Could you please elaborate more the specific reason.
However if you want to get text from all elements in a document, kindly review this thread -> link.
By using the childNodes property you can achieve this. But for afterHtml and before div2, you need to do some extra work because they are part of the same text node.
Please take a look at the snippet below. You can remove the last element of the array manually.
const arr = [];
document.body.childNodes.forEach(node => {
arr.push(node.textContent.trim());
})
console.log(arr)
<body>
before div <div>innerHTML </div>aferHTML
before div2 <div>innerHTML2 </div>aferHTML2
</body>
Okay here's mine.
As you can see, I wrapped your HTML inside a div with a class name content.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="content">
before div <div>innerHTML </div>aferHTML
before div2 <div>innerHTML2 </div>aferHTML2
</div>
</body>
</html>
<script type="text/javascript">
var body = document.querySelector('.content').children;
var list = [];
for (var i = 0; i < body.length ; i++) {
var before = body[i].previousSibling.nodeValue.trim();
var inner = body[i].innerHTML;
var after = body[i].nextSibling.nodeValue.trim();
if (before && i == 0) list.push(before); //prevent duplication and empty value
list.push(inner);
if(after) list.push(after); //prevent empty value
}
console.log(list); //output
</script>
in innerHTML, you could split the string using inner.split(" ") if you like.

i have many data-self element, but how can i get all of them?

just like this:
// with jquery i have tried
$('body').data('self'); // undefined
$('body').data('date-self'); //undefined
// but i can use this method to get the defined element
$('button').data('self'); // self
// with javascript
document.querySelector('button').dataset.self // self
<html>
<head>
</head>
<body>
<div data-self="self">self</div>
<span data-self="self">span self</div>
<ul>
<li data-self="self">li1 self</li>
<li data-self="self">li2 self</li>
</ul>
<button data-self="self">button self</button>
</body>
</html>
but i can't find a way to get all elements with 'data-self'.
if someone know, please tell me, any help would be greatly appreciated.
Well, first off, your HTML is invalid. date-self should probably be data-self, yes?
Second, getting the value in data-* attributes is done using the .data() method:
var dataSelf = $(".elem").data("self");
You can also get it directly from the attribute, like so:
var dataSelf = $(".elem").attr("data-self");
Selecting elements that have the data-self attribute is done as follows:
var elementsWithDataSelf = $("[data-self]");
You're just going to have to iterate over them all.
var $elems = $('[data-self]');
var selfs = [];
$elems.each(function ($elem) {
selfs.push($elem.data('self'));
});
You can get all elements where 'data-self' attribute is set using this query:
var elementList=document.querySelectorAll('[data-self]');
If you need to select all elements where 'data-self' attribute is equal to something then you can use next line:
var elementList=document.querySelectorAll('[data-self="something"]');

JS get value of generated textnode

I have this Javascript in a for loop:
renderAElements[i] = document.createElement ("a");
renderAElements[i].setAttribute("href", "#");
renderAElements[i].setAttribute("class", "expander");
renderAElements[i].appendChild(expand);
alert (renderAElements[i].nodeValue);
where expand is created as:
var expand = document.createTextNode("+");
The alert, which is meant to return the link text of each created element returns null. Why is this?
Because you are trying to get the nodeValue of the Element node and not the Text node.
alert (renderAElements[i].firstChild.nodeValue);
It's because the a element contains another element and not a value. If you want to get the text out of the node you'll need to do either
renderAElements.childNodes[0].nodeValue
or
renderAElements.innerText
Check this out
<head>
<script type="text/javascript">
function GetTextNode () {
var textContainer = document.getElementById ("textContainer");
var textNode = textContainer.firstChild;
alert (textNode.data);
}
</script>
</head>
<body>
<div id="textContainer">This is a simple text in the container.</div>
<button onclick="GetTextNode ()">Get the contents of the container</button>
</body>
try this alert (renderAElements[i].firstChild.nodeValue);

how to get tinyMCE editable for a cloned textarea by cloneNode(true) function

When I try to clone a textarea by using cloneNote(true), the cloned textarea is not editable. Does anyone know how to resolve the problem? The sample codes show as following:
<html>
<head>
<script type="text/javascript" src="/javascripts/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
tinyMCE.init({
theme : "advanced",
mode : "textareas",
});
</script>
<script type="text/javascript">
testclonenode = {
addAbove : function (element) {
var rowEl = element.parentNode.parentNode.parentNode;
var rowElClone = rowEl.cloneNode(true);
rowEl.parentNode.insertBefore(rowElClone, rowEl);
return false;
}
};
</script>
</head>
<body>
<table>
<tr><td>
<textarea name="content" style="width:100%">this is a test </textarea>
<p> <button onclick='return testclonenode.addAbove.call(testclonenode, this);'> Add above </button>
</td></tr>
</table>
</body></html>
It does not work that way. Also, it is impossible to move a tinymce editor using dom manipulation.
The tinymce wiki states the following:
mceAddControl
Converts the specified textarea or div
into an editor instance having the
specified ID.
Example:
tinyMCE.execCommand('mceAddControl',false,'mydiv');
So when you clone a textarea there is another problem: You will have the same id twice which will result in errors accessing the right tinymce instance.
I got this to work by using an ID which is incremented each time my clone function is triggered, so
var insertslideID = 0;
function slideclone() {
$('<div class="slides"><textarea name="newslide['+insertslideID+'][slide_desc]" id="mydiv'+insertslideID+'"></textarea></div>').insertAfter('div.slides:last');
tinyMCE.execCommand('mceAddControl',false,'mydiv'+insertslideID);
insertslideID++;
}
$('input[name=addaslidebtn]').click(slideclone);
Seems to work.
A wee bit tidier, I just use a number for my id - copy1 is the name of my button - I add the new element to the end of my container.
var count = 0;
$("#copy1").click(function(){
var newId = count;
$( "#first" ).clone().appendTo( "#container" ).prop({ id: newId, });
tinyMCE.execCommand('mceAddControl',false,newId);
count++;
});
I ran into a similar problem, except my element IDs (not just textareas) could be anything, and the same ID was always appearing twice. What I did is supposed to be horribly inefficient but there was no noticeable performance loss with dozens of elements on the page.
Basically I removed the TinyMCE ID first (uses jQuery):
$(new_element).find('.mce-content-body').each(function () {
$(this).removeAttr('id');
});
Then I reinitialized TinyMCE for all relevant elements.

Categories