How to copy and alert an child element - javascript

$('h1').click(function(){
var span = $(this).find('.secondary');
alert(span);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>
Hello
<span class='secondary'>World</span>
</h1>
How to i copy the entire .secondary element and alert it like this
<span class='secondary'>World</span>

There's a few problems with your solution:
alert the span's outerHTML instead of just the JQuery span object.
.secondary instead of secondary for your selector (the . indicates that it's a class, read more here).
Use $(document).ready() This will make sure that JQuery is loaded and ready to be used, and that all the elements are loaded before running any JQuery.
In the end, with all these problems solved, your code should look like this:
$(document).ready(function () {
$('h1').click(function () {
var span = $(this).find('.secondary');
alert(span[0].outerHTML);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>
Hello
<span class='secondary'>World</span>
</h1>

What you want is the outer HTML of the currently selected element. There is no direct function for this in jQuery, so you need to:
first wrap it in another element,
then go upward to that wrapper element
now you can use html() to get inner html of this wrapper element, which is actually the outer html for your original element.
You can use jQuery's clone() method to create a copy and perform the manipulations on that clone element, thus keeping your original element as it is.
$('h1').click(function(){
var span = $(this).find('.secondary').clone().wrap('<p>').parent().html();
alert(span);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>
Hello
<span class='secondary'>World</span>
</h1>

To then grab the html element as a string you would do:
document.documentElement.outerHTML
<script>
$('h1').click(function () {
var span = document.find('secondary').outerHTML;
alert(span);
})
</script>

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.

Using Filter to return content within class and the class itself

Filter behaves as expected, it returns multiple divs with a class of post. However, it only returns the content within the div
<h1></h1>
and not
<div class="post"><h1></h1></div>
Would it be possible to get this sort of output?
I.e. this sort of output
<div class="post"><h1></h1></div>
Here's the code:
$(result).filter('.post').each(function(i, currentElement) {
var htmlOfSinglePost = $(this).html();
var p = $(htmlOfSinglePost).attr("data-post-id");
console.log(p);
});
$(this).html(); would give you the inner HTML of the specified selector excluding the selector itself.
It you want inner html and selector element itself, you may want to use
$(selector)[0].outerHTML
here is snippet
$(".post").each(function(){
console.log($(this)[0].outerHTML)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="post"><h1></h1></div>
<div class="post"><h1>This is other one</h1></div>
Assuming your result contains HTML, given some basic example HTML, within your .each() the this refers to the current HTML element (not the jQuery) object. To get the outer HTML element, you can use outerHTML as seen below.
To get the data-post-id value from the outer content, wrap it into a jQuery wrapper to use $(outerContent).data('postId').
Just to add, the reason you cannot use getAttribute() on a result
from outerHTML is because outerHTML resturns a
DOMString
and while you can take the DOMString and convert it into an element it
is faster at this point to just use jQuery $(...outerHTML).data() but only because you are already using it
$('.post').each(function(i, currentElement) {
var outerContent = this.outerHTML;
console.log(outerContent);
var p = $(outerContent).data('postId');
console.log('postId = ',p);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="post" data-post-id="15">
<h1>Post</h1>
</div>
<div class="post" data-post-id="57">
<h1>Post 2</h1>
</div>

jQuery wrap not working with append?

I have a p element <p id="test">Test</p> and wrap it inside a span by using wrap and save the new element under $test.
I append $test to p#output.
Result: p element is getting appended, but it is not wrapped inside a span anymore.
$test = $("p#test").wrap("<span style='color:red'></span>");
$("p#output").append($test);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="test">Test</p>
<p id="output">OUTPUT:</p>
jQuery documentation says .wrap() returns the original set of elements for chaining purposes.
use something like this instead $("p#output").append($('p#test').parent());

How do I replace part of text inside an element with children?

I have this HTML:
<div class="test">Orange <span class="is">is</span> my favorite color.</div>
I only want to replace Orange (and the space after it). Using .text() won't work because it selects the whole strong.
How do I do this?
This is harder to do with jQuery than with the native DOM, so if you're using jQuery, you're going to have to convert the element to the native DOM using jQuery's array indexing.
Basically, what we need to do is change the first text node. jQuery isn't really good with text nodes, which is why we use the DOM here:
//This gets the div.test element using jQuery:
var testDiv = $("div.test");
function changeColor(color) {
/* The following function changes the value of the first text node within testDiv: */
//This converts testDiv from a jQuery element to a regular DOM element. This is because jQuery isn't really meant to be handling stuff like text nodes, so doing this with the regular DOM will just be much easier.
var domElement = testDiv[0];
//Now, just change the value of the first text node:
domElement.childNodes[0].nodeValue = color;
}
//Now, as you can see if you click div.test, we can replace the color mentioned in div.test using changeColor():
testDiv.click(function() {
changeColor("Blue ");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">Orange <span class="is">is</span> my favorite color.</div>
You should use native DOM methods. In your case the simples thing is just change nodeValue property of the first childNode element (which you know is going to be TextNode element):
var el = $('.test');
el[0].childNodes[0].nodeValue = 'Green ';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">Orange <span class="is">is</span> my favorite color.</div>
or if you want you can grab text node with jQuery's $.fn.contents method:
var el = $('.test');
el.contents()[0].nodeValue = 'Green ';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">Orange <span class="is">is</span> my favorite color.</div>
If you are using jquery, here is the solution
$('.test').html(function(){
return $(this).html().replace('Orange ','');
});
Find the fiddle here: https://jsfiddle.net/MasoomS/xff6dw1t/
Used data attribute to refine the code and to use it for multiple strings
HTML:
<div class="test" data-replace="Orange ">Orange <span class="is">is</span> my favorite color.</div>
<div class="test" data-replace="Green ">Green <span class="is">is</span> my next favorite color.</div>
JQUERY:
$('.test').html(function(){
return $(this).html().replace($(this).data('replace'),'');
});
document.getElementsByClassName("test")[0].childNodes[0].nodeValue = "Black";

Move a Element in Jquery

I want to prepend a Font Element in HTML within a DIV. There will be multiple div within the same page with unique Id.
<div id="id-unknown">
"Some Text"
<font color="red">*</font>
</div>
To
<div id="id-unknown">
<font color="red">*</font>
"Some Text"
</div>
I used this Jquery code to achieve it but it gets all the fonts and prepend to every div element
$("font").prependTo($("font").parent());
http://jsfiddle.net/s4Ehw/
If you only want to do this for specific divs, just add the ID selector and use .each to obtain a reference to the specific element (this)
$('#id1, #id2, #id3').children('font').each(function() {
$(this).prependTo(this.parentNode);
});
If it so happens that every font tag needs this change, use the same .each construct as above but use $('font'), per your original code and Si Donaldson's answer.
For extra performance, replace the function body with:
var parent = this.parentNode;
parent.insertBefore(this, parent.firstChild);
i.e. replacing the jQuery calls with direct DOM manipulation.
You need to itterate through each one first using $.each and then you can work on each one individually!
http://jsfiddle.net/sidonaldson/s4Ehw/2/
$("font").each(function(){
$(this).prependTo($(this).parent());
});
use jQuery each function for manage elements in cycle
jsfiddle.net/s4Ehw/6/
$("font").each(function(){
$(this).prependTo($(this).parent());
})
$.each($("font"), function(index, element) {
console.log($(element));
$(element).prependTo($(element).parent());
});

Categories