I want to change content of div "act" using nextSibling of another div.
But result is - undefined.
function inner(){
var abc = document.getElementById("start").nextSibling;
document.getElementById("act").innerHTML = abc.innerHTML;
}
<img id="btnRight" src="img/btnRight.png" onclick="inner()">
<div id="act"><img src="img/home01.jpg"></div>
<div id="store">
<div id="start">
<img src="img/img01.jpg">
</div>
<div>
<img src="img/img02.jpg"> //wanted to place into "act"
</div>
<div id="end">
<img src="img/img03.jpg">
</div>
</div>
Use nextElementSibling, nextSibling could be a text node
function inner(){
var abc = document.getElementById("start").nextElementSibling;
document.getElementById("act").innerHTML = abc.innerHTML;
}
FIDDLE
If you target browser doesn't support nextElementSibling you can traverse the siblings and find the first element node.
function nextElementSibling(element) {
while (element.nextSibling){
element = element.nextSibling;
if (element.nodeType == Node.ELEMENT_NODE){
return element;
}
}
return undefined;
}
FIDDLE
You have to make sure to skip over whitespace when traversing nodes.
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
function inner(){
var abc = next(document.getElementById("start"));
document.getElementById("act").innerHTML = abc.innerHTML;
}
You can see a working example at http://jsfiddle.net/CkCR3/.
The cause of this behaviour is white space between div with id "start" and the following div. So, nextSibling will be text content. You need to do nextSibling twice:
var abc = document.getElementById("start").nextSibling.nextSibling;
Another option is to remove whitespace characters between two divs.
Please change your line of code as per below;
because every next element is check for exists or not ,then get inner html.
function inner() {
var abc = document.getElementById("start");
do {
abc = abc.nextSibling;
} while (abc && abc.nodeType != 1);
document.getElementById("act").innerHTML = abc.innerHTML;
return false;
}
I've made a jsfiddle to demonstrate an easier way.
You'll notice that the act div is red and that the start div is blue. The innerHTML will change when you click the button. Also, a reason that you might see undefined is because the DOM didn't load and so it doesn't have any idea that the divs exist. Next time you should use window.onload = inner(); to make the function run after the DOM has loaded.
This is the jsfiddle: http://jsfiddle.net/yY9Ag/16/
there are two way
first fix the code
nextSibling.nextSibling.innerHTML
or fix the html : remove all \n char
<img id="btnRight" src="img/btnRight.png" onclick="inner()"><div id="act"><img src="img/home01.jpg"></div><div id="store"><div id="start"><img src="img/img01.jpg"></div><div><img src="img/img02.jpg"> //wanted to place into "act"</div><div id="end"><img src="img/img03.jpg"></div></div>
because div tag's next sibling is empty textNode (it can't see)
Related
I'm trying to use Javascript so that a paragraph will alternate between two texts when the user presses a button on the webpage. The problem is that the <p> element I'm trying to manipulate lies within a <div> within a <div> within a <div>.
A low-level mockup of my code can be seen below:
<div id="div1">
<div id="div2">
<div id="div3">
<p>text1</p>
</div>
</div>
</div>
All solutions I've found only state what to do if the <p> is within one <div>; solutions which have not worked for me.
Here's my latest attempt:
function translate() {
var x = document.getElementById("div1").getElementById("div2").getElementById("div3").getElementsByTagName('p')[0];
if (x.innerHTML === "text1") {
x.innerHTML = "text2";
} else {
x.innerHTML = "text1";
}
}
How would I get this to work?
Edit: Nothing seems to be working so far. The <div> element all have classes, but that shouldn't affect things, right?
Edit2: My apologies for taking up your time, but I've found the issue was something else entirely. I'd been using a reserved word for my function call this whole time and had somehow never noticed that that was the issue instead. Thanks again to those who answered, and I shall look deeper at my code before posting my next question.
Why not just use
var x = document.getElementById("div3")
If accessing by the Id directly, it does not really matter what the other DIVs are.
If divs are always in that order, you can do it like this:
var x = document.querySelector('#div1 #div2 #div3 p');
You can use document.querySelectorAll to get an array of all p tags on the page.
const pTags = document.querySelectorAll('p')
pTags.forEach((p, i) => {
if(i % 2 === 0) {
p.innerHTML = 'text1'
} else {
p.innerHTML = 'text2'
}
})
Instead of Ids, you can be more specific & try the following:
var x = document.querySelector('div > div > div > p')
This will be a very strict implementation & follows the condition without the ids or classes.
Use querySelector in order to use the CSS selector #div3 p which means "pick up the paragraph element that is inside the element that has a div3 id".
Then, as you're just changing a string of text, change either the textContent of that element, or its innerText (there are subtle differences between them.)
const para = document.querySelector('#div3 p');
const button = document.querySelector('button');
button.addEventListener('click', translate);
function translate() {
if (para.textContent === 'text1') {
para.textContent = 'text2';
} else {
para.textContent = 'text1';
}
}
<div id="div1">
<div id="div2">
<div id="div3">
<p>text1</p>
</div>
</div>
</div>
<button type="button">Translate</button>
I'm using <div contenteditable="true">, when I press enter to newline with empty input, it will generate <div><br></div>.
But I just want to remove it from beginning and at the end.
For example:
<div contenteditable="true">
<div><br></div> i want to remove this
abc
<div><br></div> remain
1234
<div><br></div> i want to remove this
<div><br></div> i want to remove this
</div>
for(var x = item.length - 1 ; x >= 0 ; x--){
if($(item[x]).html() == "<br>"){
$(item[x]).remove();
}else{
break;
}
}
for(var x = 0; x <= item.length-1 ; x++){
if($(item[x]).html() == "<br>"){
$(item[x]).remove();
}else{
break;
}
}
Currently I'm using two looping to remove it, But I'm looking a better way to filter it.
Anyone can guide me?
Thanks.
You can actually achieve it with while loop instead of for loop. You need to store the reference for first and last child of the contenteditable div and manipulate it with while loop. Detailed explanation in comments around the code.
$('.remove').on('click', function() {
var firstChild = $('div[contenteditable] div:first');
var lastChild = $('div[contenteditable] div:last');
//store the reference for first and last child of the contenteditable div
while(firstChild.html()=="<br>")//remove all the element's until firstchild's html!="<br>" i.e. is not empty
{
firstChild.remove();//remove it
firstChild= $('div[contenteditable] div:first'); //again store the reference to new first child after remove
}
//same goes with last child
while(lastChild.html()=="<br>")
{
lastChild.remove();
lastChild= $('div[contenteditable] div:last');
}
})
div[contenteditable] {
background-color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true">
</div>
<button type="button" class="remove">Remove unwanted</button>
If you want to remove a div which is empty..(Your question states that)....
This may help.....
$("div:empty").remove();
This code removes div that are empty...If thats what You wanted this could help
I have the elements in the div as mentioned below:
<div id="container">
<div id="first_div">
<div id="comment-1" class="comment">Child 1 of first div</div>
<div id="comment-2" class="comment">Child 2 of first div</div>
<div id="comment-3" class="comment">Child 3 of first div</div>
<div id="comment-4" class="comment">Child 4 of first div</div>
</div>
<div id="second_div">
<div id="comment-5" class="comment">Child 1 of second div</div>
<div id="comment-6" class="comment">Child 2 of second div</div>
<div id="comment-7" class="comment">Child 3 of second div</div>
<div id="comment-8" class="comment">Child 4 of second div</div>
</div>
<div id="third_div">
<div id="comment-9" class="comment">Child 1 of third div</div>
<div id="comment-10" class="comment">Child 2 of third div</div>
<div id="comment-11" class="comment">Child 3 of third div</div>
<div id="comment-12" class="comment">Child 4 of third div</div>
</div>
I need to retrieve the next element from comment id comment-4.
$('#comment-4').next().attr('id') gives me result as undefined.I need the target div to be comment id - comment-5.How to retrieve the next element of div from another div using jquery?
Try this :
$(function(){
$('.comment').click(function(index){
var id;
if ( $(this).is(':last-child') )
id = $(this).parent().next().children(':first').attr('id');
else
id = $(this).next().attr('id');
alert(id);
});
});
Demo
Demo : http://jsfiddle.net/abdennour/PU54r/
function nextOf(id,cyclic){
var ids= $('div[id^=comment-]').toArray().map(function(e){return $(e).attr('id')}).sort();
var idx=ids.indexOf("comment-"+id);
if(idx!==-1){
if(ids.length> idx+1){
return $('div#'+ids[idx]);
}
else{
// it is the last div: if it is cyclic ,you may return the first
if(cyclic){
return $('div#'+ids[0]);
}
}
}else{
// no div with this id
}
}
Then :
var target=nextOf(4)
if(target){
target.html()
//--> Child 1 of second div
}
I think you can use $('.comment') to pick up all of your wanted, and save them in some variable such as var arrResult = $('.comment');.
So far, you can choose what you wanted use the arrResult variable.
Because your inner-most divs have different parents, I would first get all the divs you care about:
var comments = $('.comment');
Next, if we can assume your id's are all numbered sequentially, get the number in the id (assuming this references the element):
var index = parseInt($(this).attr('id').substr(8));
Now, the next div in the comment list is at that position in the comments:
var nextDiv = comments[index];
Just for good measure, I'd first make sure index is set:
var nextDiv;
if (index < comments.length) {
nextDiv = comments[index];
}
You could use an index in your case :
JS:
for (var index = 0; index <= 12; ++index) {
$("#comment-" + index).attr("id");
}
You can define a statement which checks the target id is the last child, than you can return a function according to value.
jsFiddle Demo
var target = 'comment-4';
$('.comment').each(function(i) {
if ( $(this).attr('id') == target ) {
if ( $(this).is(':last-child') ) {
$(this).parent().next().children().first().addClass('red');
}else{
$(this).next().addClass('red');
}
}
});
Here is one way - http://jsfiddle.net/jayblanchard/WLeSr/
$('a').click(function() {
var highlight = $('.highlight');
var currentIndex = $('.comment').index(highlight); // get the index of the currently highlighted item
$('.comment').removeClass('highlight');
var nextIndex = currentIndex + 1;
$('.comment').eq(nextIndex).addClass('highlight');
});
It is showing undefined because comment-4 and comment-5 are childrens of different parent elements. Means comment-4 is children of first_div and second_div parent of comment-5.
You can get the comment-5 using below code.
$('#comment-4').parent().next().children().attr('id');
Assuming jQuery-wrapped element is collected in $comment, there's one way to solve it:
function getNextComment($comment) {
var $nextComment = $comment.next();
if ($nextComment.length) {
return $nextComment;
}
var $nextParent = $comment.parent().next();
if ($nextParent.length) {
return $nextParent.children().first();
}
return null;
}
Demo. Click on one comment - and see the next one's highlighted. )
The base algorithm's very simple here. First, we attempt to retrieve the next sibling of the given element. If there's one, it's returned immediately. If not (and it's the case with #comment-4 in your question - it's the last element in its hierarchy), we go up the DOM chain for its parent (#first-div, in this case), and look for its next sibling (#second-div). If it exists, then its very first child element is returned. If it doesn't, null is returned (we can actually return an empty jQuery object - $(), but that depends on use cases.
Just one instruction : )
$('<div id="mock" />').append($('.comment').clone()).find('#comment-4').next().attr('id')//---> comment-5
Based on divs have the same Css class .comment
DEMO
Why not this will be undefined: $('#comment-4').next().attr('id') because there is no next element. as you mentioned that you want to target the #comment-5 in the next div's child then you can do this:
function giveId(el) {
var sel = el.id ? '#'+el.id : '.'+el.className;
var id = $(sel).next('div').length ? $(sel).next('div').attr('id') : $(sel).parent('div').next('div').find('> div:first').attr('id');
return id || "Either no next elem exist or next elem doesnot have any id/class.";
}
$(function () {
$('div').click(function (e) {
e.stopPropagation();
alert(giveId(this));
});
});
Updated Demo in action
Try this: JSFiddle (The easiest solution!)
$(document).ready(function(){
var currDiv = $("#comment-4"); // Try with different valies: "#comment-x"
currDivId = currDiv.prop('id');
lastDivId = currDiv.parent('div').find('.comment').last().prop('id');
if(currDivId == lastDivId){
var nextComment = currDiv.parent('div').next('div').find('.comment').prop('id');
}else{
var nextComment = currDiv.parent('div').find('.comment').next().prop('id');
}
alert(nextComment);
});
I have the following code,
$(document.getElementById('messages_message-wysiwyg-iframe').contentWindow.document).keydown(function() {
var iFrame = document.getElementById('messages_message-wysiwyg-iframe');
var iFrameBody;
if ( iFrame.contentDocument )
{ // FF
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
}
else if ( iFrame.contentWindow )
{ // IE
iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
}
console.info(iFrameBody.innerHTML);
});
What I am trying to do if get the content of an iframe, but remove all the html tags that are not,
b, strong, i, a, u, img
However I do not want to remove any of the of the text, for example if the in the iframe there is the following,
<div class="box segment panel">
<a href="http://www.google.com>hello world</a>
click this link and go far.
<img src="http://placehold.it/100x100" alt="Placeholder"/>
</div>
What would be return would be the following,
hello world
click this link and go far.
</a>
<img src="http://placehold.it/100x100" alt="Placeholder" />
Is this even possible?
Here's my pure JS solution:
function sanitize(el) {
if (el.nodeType !== 1) return;
if (!/^(B|STRONG|I|A|U|IMG)$/.test(el.tagName)) {
var p = el.parentNode;
// move all children out of the element, recursing as we go
var c = el.firstChild;
while (c) {
var d = c.nextSibling; // remember the next element
p.insertBefore(c, el);
sanitize(c);
c = d; // look at the next sibling
}
// remove the element
p.removeChild(el);
}
}
demo at http://jsfiddle.net/alnitak/WvJAx/
It works by (recursively) moving the child nodes of restricted tags out of their parent, and then removing those tags once they're empty.
With a regex:
iFrameBody.innerHTML=iFrameBody.innerHTML.replace(/<[^(b|strong|i|a|u|img)]\b[^>]*>/gi,"").replace(/<\/[^(b|strong|i|a|u|img)]>/gi,"");
The first replace removes the start tags, the second removes the end tags.
Note that there are a couple traps when using regex to match html. But in this specific case it seems like a reasonable choice (cf. my comments on the other answers).
For the record, this is what I use to access an iframe's content document:
var doc=ifr.contentWindow||ifr.contentDocument;
if (doc.document) doc=doc.document;
var iFrame = document.getElementById('messages_message-wysiwyg-iframe');
var iFrameDoc = iFrame.contentDocument || iFrame.contentWindow.document;
$(iFrameDoc).keydown(function() {
var iFrameBody = $("body", iFrameDoc);
var cleared = iFrameBody.clone();
cleared.find("*:not(b,strong,i,a,u,img)").each(function() {
var $this = $(this);
$this.replaceWith($this.contents());
});
console.log(cleared.html());
});
Demo at jsfiddle.net
I think you're a little confused about how to describe what you're trying to do. When you talk about "text", you're referring to the innerHTML/text node inside of a tag. What you're really looking to do, I think, is grab all of the specific content and the structure of the content, aka the children elements of the iFrame.
You can use jQuery's .text() method to get the text content of each element individually and save that before removing the actual tag from the DOM, if you want to lets say, get the text content of a span but you don't want the span to be in the DOM anymore, or you want to place it somewhere else in your document.
var elemText = $('span#mySpan').text();
$('span#mySpan').remove();
For what it looks like you're trying to do based on your sample HTML, you may want to look into jQuery's detach method: http://api.jquery.com/detach/
This will allow you to store the returned children elements to be appended somewhere else later.
I am using Javascrip and I have a function like the following where I want to hide all div. But I don't know why this code is not working. Will anyone help me with this?
Javasvript
function showDiv(divTag,id)
{
var i;
for(i=1;i<7;i++)
{
document.getElementById(divTag+i).style.display = 'none';
}
document.getElementById(divTag+id).style.display = 'block';
}
or
function showDiv(divTag,id)
{
var i;
for(i=1;i<5;i++)
{
var tempDiv = divTag + i;
document.getElementById(tempDiv).style.display = 'none';
}
document.getElementById(divTag+id).style.display = 'block';
}
And HTML
Show Only Div1
<div id="hide_1">
Abc
</div>
Show Only Div2
<div id="hide_2">
BCD
</div>
Show Only Div2
<div id="hide_3">
EDF
</div>
Show Only Div2
<div id="hide_4">
FGE
</div>
Both of the abov process I have tried but failed to do that
Several things:
The "onclick" (not "onClick") is the correct way to assign the click event handler in both html and JavaScript.
You are looping from 1 to 6 in for(i=1;i<7;i++) line of the first function, but you only have 4 elements in your html. When reaching the non-existing fifth - your code will throw an error. Something along the lines of "TypeError: Cannot read property 'style' of null".
As #verisimilitude has mentioned, you have a syntax error in your html where you put a quoted text inside another text that's quoted in the same way. It should be onclick="showDiv('hide_',1)". Note the single quotes around 'hide_'.
Here's the code that works. Click here to see it in action.
Here's your JavaScript function:
// Please note that it must be in the global scope
// otherwise you won't be able to call it from your html.
function showDiv(divTag, id) {
var i;
for (i = 1; i < 5; i++) {
var tempDiv = divTag + i;
document.getElementById(tempDiv).style.display = 'none';
}
document.getElementById(divTag+id).style.display = 'block';
}
Also, take a look at another working version of your code that pre-validates the existence of your elements before hiding/showing them. So you don't have to worry about your for loop iterating over elements that have been removed.
And here's your html:
Show Only Div1
<div id="hide_1">Div1</div>
Show Only Div2
<div id="hide_2">Div2</div>
Show Only Div3
<div id="hide_3">Div3</div>
Show Only Div4
<div id="hide_4">Div4</div>
Show Only Div1
yields a javascript syntax error. This should be
Show Only Div1
Check the single quotes around "hide_"