I have three divs. How should I append a div onto an unknown div?
<div class="main" >
<div id="drag-box" >
<div id="" class=""> </div>
</div>
</div>
I want to append div on an unknown div which is come after drag-box div. I don't know which div comes after drag-box div. But there must be one div after drag-box div.
$("#drag-box div:first-child").append("<span />");
or
$("#drag-box div").first().prepend("<span>first</span>");
For a complete answers, here it is working:
http://jsfiddle.net/dMUD3/
try this
$("#drag-box div:first-child").attr("id");
Instead of giving you a one liner I would like to give you an indepth solution.
A browser takes your html and parses what is called a DOM Tree out of it.
so if your html is .
<div class="a">
<div class="foo"></div>
<button class="foogle"></button>
</div>
The tree structure will become something like
`-div.a
|-div.foo
`Button.foogle
You should actually look into DOM Api's at MDN
How DOM helps ?
With DOM api's you can actually access the unknown div using the reference to a known div. So if you actually understand your markup and its representation in DOM it should be pretty simple to get reference to nth child of an element;
You can access the child elements by the children attribute.
So
// Get reference to the element.
var parent = document.getElementById("drag-box");
// Use the dom.
var child_i_want = parent.children[0];
// or there is another way
var child_i_reallyWant = parent.firstElementChild;
There are solutions with jQuery but I feel its important for you to Understand basics of DOM even when there are helpful abstraction libraries in existance.
You'll need the + selector. It applies to the object directly following. See here.
.drag-box + div {
}
$('<div></div>').appendTo($('#drag-box div:first'))
Related
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.
Say I have HTML that looks like this:
<div>
<div>
<div class="calendar start">
</div>
</div>
<div>
<div class="calendar end">
</div>
</div>
</div>
We can assume that the start and end will always be on the same "level" of a branch from each other, and will at some point share a common parent.
Without knowledge of the exact HTML structure, how would I find calendar end from calendar start? What if they are nested further down?
Edit: For clarification. I want to start at start's parent. Search all child elements for end. Then move to the next parent, and search all child elements...etc till I find end. I am wondering if this is possible with built in JQuery functions, without writing my own DOM traversal logic.
You can do it like below, But it is a costlier process.
var parentWhichHasCalEnd =
$($(".calendar.start").parents()
.get().find(itm => $(itm).find(".calendar.end").length));
var calEnd = $(".calendar.end", parentWhichHasCalEnd);
DEMO
Explanation: We are selecting the .start element first, then we are retrieving its parent elements. After that we are converting that jquery object collection to an array of elements by using .get(). So that we could use .find(), an array function over it. Now inside of the callBack of find we are checking for .end over each parent element of .start, if a parent has .end then we would return that parent. Thats all.
You could get more understanding, if you read .get(), .find(), and arrow functions.
You can use jQuery#next() method from .start parent element
var startSelector = $('body > div > div:nth-child(3) > .start')
var endSelector = secondStart.parent().next().find('.end');
I think this method is faster rather than jQuery#children() method, but you can benchmark it if you want to
btw you may check my answer based on this JSBin
i don't know if i got this right but have you tried children function in jquery
$( ".calender" ).children( ".end" )
and for the parent you can use parent() function so you can first check the parent then the children or vicversa
edit:
if you dont know the exact structure the better way is to find the common parent and then search it's children :
$( ".calender.start").closest('.common-parent').children('.calender.end');
closest function give the nearest parent
Try:
$('.start').parent().parent().find('.end');
Is there a JavaScript method similar to jQuery .next()? I want to find the next element that has the class of "error" relative to the element. I've tried using .nextSibling as a loop but couldn't figure it out. Didn't know if there was an easier way to go about it without jQuery.
For instance, if I have this code:
<div id="section">
<div id="test">test</div>
<span class="info">Information</span>
<span class="error">Error!</span>
</div>
I'm trying to get the next .error class closest to #test, if I have a #section2 and a #test2 I would want to get the .error class closest to #test2 and so on.
The nextElementSibling property returns the element immediately following the specified element, in the same tree level.
Example: Get the HTML content of the next sibling of a list item:
var x = document.getElementById("item1").nextElementSibling
The nextElementSibling property might help.
Best bet would be to search through the jQuery code and see what they did.
http://code.jquery.com/jquery-2.0.3.js
At a glance, I do see some calls to "nextSibling" and "previousSibling."
Also see here:
How to get next element using JavaScript-only?
Hope this helps!
This is the pure javascript for you:
HTML
<div id="nodes">
<div class="error">This is error Node</div>
<div class="nextElement">This is next Element</div>
</div>
Javscript:
var nodes = Array.prototype.slice.call( document.getElementById('nodes').children ),
errorNode = document.getElementsByClassName('error')[0];
var indexOfError = nodes.indexOf(errorNode);
var nextElement = nodes[indexOfError + 1];
alert(nextElement.innerText);
Here is demo
Sounds like you may be looking for document.getElementsByClassName()... if the elements with class=error are not direct siblings in the DOM, then there's not a good way to find them otherwise. It's elementary, but you can just search through the array returned by document.getElementsByClassName('error') until you find your starting element, and then you know the next item in the array will be the next element in the DOM.
See also MDN reference. Won't work in old IE, but works for all modern browsers.
I have a markup in one of my website pages as follows:
<div id="mainPage">
<div>
<div><ul><li>etc.</li></ul>
</div>
<div>
<div><ul><li>etc.</li></ul>
</div>
</div>
What the above means is that there's a main div in my website which has the content. I want to take all the children of the particular div and save it in a var, since I want to use that var later for something like $('resurrectPage').append(someVar); where someVar has the dom elements from the main page div.
How can all the children of a particular element be selected and added to a var?
$('#mainPage').html() would give you the entire thing in a string "<div>
<div><ul><li>etc.</li></ul> </div> <div> <div><ul><li>etc.</li></ul> </div>"
$('#mainPage').children() would give you immidiate children [div,div]
$('#mainPage').find('.div') would giv =e you all the divs inside it [div,div,div,div]
if #mainPage is your main div, you can get of it's children by
var someVar = $('#mainPage').children();
Official api page
I think you're looking for jQuery detach method...
http://api.jquery.com/detach/
It will remove an element and store its contents, ready to be re-appended:
var a = p = $("a").detach()
If you only need the HTML you can save the HTML: var someVar = $("#mainPage").html(); and then append the HTML with the code you already have. Please tell me if I have misunderstood your question.
I would like to convert
<div id="outer">
<div id="inner"></div>
</div>
into
<div id="outer">
<div id="middle">
<div id="inner"></div>
</div>
</div>
I would like to preserve any references to the divs that may have been set prior to this so just doing $("#outer").html($("" + $("#outer").html() + "")) will not work for me. Is there a better way than just creating the middle div, moving all the children of outer to it and then appending it to the outer div?
Use .wrap()...
$('#inner').wrap('<div id="middle"></div>');
DEMO: http://jsfiddle.net/ENmDF/
You should note that although jQuery makes it look like you're working with HTML since it accepts a string like '<div id="middle"></div>' to create an element, the truth is that it takes your string, uses it to create DOM elements, then inserts it into the DOM, placing it, and the wrapped part, in their respective places.
It would be similar to this in the DOM API...
var inner = document.getElementById('inner');
var middle = document.createElement('div');
middle.id = 'middle';
inner.parentNode.insertBefore(middle, inner);
middle.appendChild(inner);
DEMO: http://jsfiddle.net/ENmDF/1/
jQuery has another syntax for creating elements with attributes. That is to pass an object as the second argument to the $ function, so the original code could be written like this...
$('#inner').wrap($('<div>', {id:"middle"}));
DEMO: http://jsfiddle.net/ENmDF/3/
$("#inner")
.wrap(
$("<div>")
.prop("id", "middle")
);
Works the same way as am not i am's answer, but this one uses the DOM to create the div element that wraps it.
Note the lack of a semicolon (;) after setting the id attribute.
Demo.
Also, in case you prefer it, here's a one-liner:
$("#inner").wrap($("<div>").attr("id","middle"));