Wrap a new div element around specific text - javascript

I am struggling with this one.
How can I wrap a new <div> element around text that does not have any class or ID?
Below is the scenario:
<div class="ContentDiv">.....</div>
Share your knowledge. Be the first to write a review »
I need the new div to wrap around "Share your knowledge. Be the first to write a review »"
I have tried the following:
$(document).ready(function() {
$('.ContentDiv').each(function() {
$(this).add($(this).next()).wrapAll('<div class="NewDiv"></div>');
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="ContentDiv">.....</div>
Share your knowledge. Be the first to write a review »
but it is not working because it wraps around the <a> element only and leaves the text below it. I need the rest of the text in there as well.

You need to get the next textnode after .ContentDiv and wrap that:
$('.ContentDiv').each(function() {
$(this).next('a').add(this.nextSibling).wrapAll('<div class="NewDiv"></div>');
});
FIDDLE
Since jQuery does'nt really get textnodes, the native nextSibling should work.

For this you can add a div after $('.ContentDiv') and then add the html to it.
$("<div id='new_div'></div").insertAfter($('.ContentDiv')).html("Share your knowledge. <a href='URL'>Be the first to write a review »</a>");

Related

Remove any specific html code using javascript

In the past I used Google Developer Console to delete some specific divs on a page. I could do it manually of course but in some cases where the divs where many I had to use the console. I had a single line code that did the job (I found it while searching the internet) but I lost my note.
So how can I delete using javascript any html code (by copy pasting the code).
Something like:
elements = $('<div ... </div>');
elements.remove();
OR
$('<div ... </div>').remove();
Any ideas? I am not an expert in javascript (obviously) and I've been searching stackoverflow for hours without finding anything that works.
UPDATE: I think some people might get confused with my question. Google developer console accepts javascript command lines. So even though I ask for javascript I will use the code on the google developer console.
UPDATE 2 :
Here is an example of a div I need to delete. Keep in mind I want to copy paste the entire code in the javascript code. Not just identify the div.
<div class="entry-status-overlay" data-entry-status="declined">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">Declined</span>
</div>
</div>
It's the data-entry-status="declined" that makes that div unique so I can't just identify the div using an id selector or a class selector. I need to put the entrire thing there and remove it.
I tried:
$('<div class="entry-status-overlay" data-entry-status="declined"><div class="entry-status-overlay__inner"><span class="entry-status-overlay__title">Declined</span></div></div>').remove();
It didn't remove the div.
Try to search the dom by its outerHTML.
function deleteDomByHtml(html){
html=html.replace(/\s/g,'');
$("*").each(function(){
if(this.outerHTML.replace(/\s/g,'')===html){
$(this).remove();
}
});
}
And try this line on this page:
deleteDomByHtml(`<span class="-img _glyph">Stack Overflow</span>`);
You cannot do by simply pasting the code. That will remove all the div element.
You may need a specific selector like id,class or child to specific parent to remove the element from the dom.
Consider this case the divs have common class but the data-entry-status is different. So you can get the dom using a selector and then check the dataset property.
For demo I have put it inside setTimeout to show the difference. In application you can avoid it
setTimeout(function() {
document.querySelectorAll('.entry-status-overlay').forEach(function(item) {
let getStatus = item.dataset.entryStatus;
if (getStatus === 'declined') {
item.remove()
}
})
}, 2000)
<div class="entry-status-overlay" data-entry-status="declined">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">Declined</span>
</div>
</div>
<div class="entry-status-overlay" data-entry-status="accepted">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">accepted</span>
</div>
</div>
Just add any attribute with [] and it will remove the element.
$('[class="entry-status-overlay"]').remove();
/*OR*/
$('[data-entry-status="declined"]').remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="entry-status-overlay" data-entry-status="declined">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">Declined</span>
</div>
</div>
function del(){
var h = document.body.outerHTML;
h = h.match('<div>...</div>');
h.length--;
return h;
}
I guess this will work just give it a try... i tried on browser console and it worked, this way you can match the exact you want.
I might as well add my take on this. Try running this in your console and see the question vanish.
// convert the whole page into string
let thePage = document.body.innerHTML,
string = [].map.call( thePage, function(node){
return node.textContent || node.innerText || "";
}).join("");
// I get some string. in this scenario the Question or you can set one yourself
let replacableCode = document.getElementsByClassName('post-layout')[0].innerHTML,
string2 = [].map.call( replacableCode, function(node){
return node.textContent || node.innerText || "";
}).join("");
// replace whole page with the removed innerHTML string with blank
document.body.innerHTML = thePage.replace(replacableCode,'');
If you want to identify divs with that particular data attribute, you can use a data-attribute selector. In the example below, I've used a button and click event to make the demo more visual, but in the console the only line you'd need would be:
$('div[data-entry-status="declined"]').remove();
$(function() {
$("#testbutton").click(function() {
$('div[data-entry-status="declined"]').remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="entry-status-overlay" data-entry-status="declined">
<div class="entry-status-overlay__inner">
<span class="entry-status-overlay__title">Declined</span>
</div>
</div>
<div id="x">Some other div</div>
<button type="button" id="testbutton">Click me to test removing the div</button>
See https://api.jquery.com/category/selectors/attribute-selectors/ for documentation of attribute selectors.
P.S. Your idea to paste some raw HTML into the jQuery constructor and then execute "remove" on it cannot work - you're telling jQuery to create an object based on a HTML string, which is, as far as it's concerned, a new set of HTML. It does not try to match that to something existing on the page, even if that exact HTML is in the DOM somewhere, it pays it no attention. It treats what you just gave it as being totally independent. So then when you run .remove() on that new HTML...that HTML was never added to the page, so it cannot be removed. Therefore .remove() has no effect in that situation.

How to change h1 tittle when clicked/make the section centered

I'm working on some simple questions as practice for my exam, but most of the questions don't have any answers for me to check if I don't know. There is one I'm really unsure about, so I thaught I'd check here. The question is:
Suppose we have an HTML document that contains these two lines:
<Body>
<H1 title = "When this is clicked, the section changes"> Title </ h1>
<P id = "first" title = "When this is clicked, the title is centered"> First section: Original version. </ P>
</ Body>
Type the code that would change the look of this page so that:
• When you click on the h1 title, the section changes from "First section: Original Version" to "First section: modified version ".
• When you click on the section, the position of the title changes and gets centered.
Hope someone can help learn me this so I have an answer if something similar shows up on my exam:)
var h1 = document.querySelector('h1');
var first = document.querySelector('#first');
h1.addEventListener('click', function() {
first.innerText = 'First section: modified version.';
});
first.addEventListener('click', function() {
h1.style.textAlign = 'center';
});
As others have mentioned, you should be able to find everything on Google. But to help you out, this is what the answer should be:
var heading = document.getElementsByTagName("h1")[0];
var section = document.getElementById("first");
heading.addEventListener("click", function() {
section.innerText = "First section: modified version";
});
section.addEventListener("click", function() {
heading.setAttribute("style", "text-align: center");
});
<h1 title="When this is clicked, the section changes">Title</h1>
<p id="first" title="When this is clicked, the title is centered">First section: Original version.</p>
Is this what you are looking for?
$(document).on("click", "h1", function() {
$(this).css("text-align", "center");
})
p, h1 {
text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 title="When this is clicked, the section changes"> Title </h1>
<p id="first" title="When this is clicked, the title is centered"> First section: Original version. </p>
First of all Please correct your html markup to standards and add some javascript code. Check below snippet:
$(document).on('click', 'h1', function(){
$('#first').text('First section: Modified version.');
});
$(document).on('click', '#first', function(){
$('h1').css('text-align','center');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<h1 title = "When this is clicked, the section changes"> Title </h1>
<P id = "first" title = "When this is clicked, the title is centered"> First section: Original version. </ P>
</body>
I really have no idea why you're being downvoted here. From what I gather you've tried your best on all your assigned questions and this one happened to stump you...
Anyways.. this question has a few different problems that need to be solved for you to complete the question. I'm going to try to break these down into the components, and then explain the pieces that help us get to where you want to be.
Question 1
Thinking through this a bit, here are the following steps to solve your problem.
Find a way to "listen" for a "click event" on the <h1> element.
Find a way to change the text within the <p> element to the desired text when the <h1> element is clicked.
There are some substeps buried in this but this should get us started.
To solve this issue, we'll need to find a way to select elements on a page. A Google search yields a few methods to do this in vanilla JS based solely on the code you've given.
Query Selectors: document.querySelector and document.querySelectorAll
Tag selectors: document.getElementsByTagName
There are many others as well, but using only the code that you've supplied, and assuming we're not allowed to add class attributes or anything, we'll roll with the above choices.
The selectors above all return HTML "nodes" from the page. You can think of a HTML nodes as objects that make up an HTML page. They have all sorts of properties and we can perform many operations on them.
Your best bet is to use the first suggestion, document.querySelector because it returns a single HTML node based on the passed selector. Be careful though. If we had more than one of the same element, it would only return the first which isn't at all useful.
Here's some documentation you can read and a few examples to help you understand how it works.
document.querySelector documentation
So now we have a way of selecting the <h1> element on the page.
document.querySelector(h1);
Now, we need a way to listen for events. A search of "listening for events in vanilla JS" would bring you to the addEventListener method, which allows us to listen for events on a given HTML element.
eventListener documentation
Now we can put these two together and we have an <h1> element that listens for events. I'm going to skip ahead a bit and fill in the function so we have.
let title = document.querySelector('h1');
title.addEventListener('click', function() {
alert('I just clicked the title');
});
If you plug that in and click the title, you'll see a modal pop up indicating that you clicked the title. One step down.
Now, we have to find a way to change the "text content" of the <p> element to the desired text. To do this, we first need to select the <p> element and store it in a variable. You now know how to do this so I'll leave you to it.
Now that we have the reference to the node we want to modify, we need to change a property of that node related to the text. A Google search of this will return a few different properties, but I'm going to nudge you in the right direction and let you know you want the elem.textContent property.
Putting this all together, here's the code I have that works and satisfies your requirements for the first question.
let headerTxt = document.querySelector('h1');
let sectionTxt = document.querySelector('p');
headerTxt.addEventListener('click', function() {
sectionTxt.textContent = 'First section: modified version';
});
Question 2
Some similarities from the first question here. We need to...
Select both the <h1> and <p> elements on the page (DONE)
add a click event listener to the <p> element that centers the <h1> element.
We can skip the first piece since we did that in question 1. I'm also going to skip adding an event listener to the <p> since we did something similar to that in the first question.
After adding the event listener, we need a way to change the text-alignment of some text in an HTML element.
A Google search brings us to the textAlign CSS property which we can modify using JS.
textAlign
Putting this all together, here's the complete solution
let headerTxt = document.querySelector('h1');
let sectionTxt = document.querySelector('p');
headerTxt.addEventListener('click', function() {
sectionTxt.textContent = 'First section: modified version';
});
sectionTxt.addEventListener('click', function() {
headerTxt.style.textAlign = 'center';
});
<body>
<h1 title = "When this is clicked, the section changes"> Title </h1>
<p id = "first" title = "When this is clicked, the title is centered"> First section: Original version. </p>
</body>
Hope this helps man. One takeaway of advice I have for you is get used to searching and get used to reading documentation. I'm a beginner too and I've figured that out quickly lol.
Good luck!

work on all <span> at the current <div> then check for the value of an attribute of the <span>

i am kinda stuck with my javascript, I am making a greasemonkey script for a site, that restricts me to use plain-old javascript only. For now, my script currently does is, search for all the tables, and table row with ProjectTable-row then for each ProjectTable-row look for a div with ProjectTable-status, if that div is not found, it will delete the whole row.
it works great.
document.getElementById("gmSomeID").onclick = function showAlert() {
console.log('invoked');
var projectDescriptions = document.querySelectorAll('tr.ProjectTable-row'),
projectDescriptions = Array.prototype.slice.call(projectDescriptions);
projectDescriptions.forEach(function(el) {
if (el.querySelector('div.ProjectTable-status')) {
} else {
el.parentNode.removeChild(el);
}
});
}
but, now I do not know how to work on the current div and loop on all span inside it. I am still 2 steps short.
Loop on all span
Search for all span which contains data-content="apple" if none of the span has this attribute, then delete it.
Something like this:
For a HTML tag like this:
<div class="ProjectTable-status">
<span data-content="apple">
</span>
</div>
this will not be deleted data-content is apple.
For a HTML tag like this:
<div class="ProjectTable-status">
<span data-content="banana">
</span>
</div>
this will be deleted, no span has data-content="apple".
For HTML code like this:
<div class="ProjectTable-status">
<span data-content="banana"></span>
<span data-content="apple"></span>
</div>
this will NOT be deleted, the div contains at least 1 span that has data-content of apple.
I have no idea, how to proceed now and really tired or trying anything, i do not even know how to check for attribute value.
Hope someone can guide or put me at the right path.
Thanks!
Starting with what you provided, I've just slightly refactored it to check for an "apple" span within each div as it loops through. Using continue, we can execute the next iteration of the loop without deleting the div element if we find that it contains an "apple" span. This code is not tested, but just what came off the top of my head, so it might need some tweaking.
document.getElementById("gmSomeID").onclick = function showAlert() {
console.log('invoked');
var projectDescriptions = document.querySelectorAll('tr.ProjectTable-row'),
projectDescriptions = Array.prototype.slice.call(projectDescriptions);
//pointer to work with current div
var currentDiv;
projectDescriptions.forEach(function(el) {
currentDiv = el.querySelector('div.ProjectTable-status');
//do we have a div?
if (currentDiv) {
//look for an apple within the div
if(currentDiv.querySelector('span[data-content="apple"]')){
//go to the next iteration of the loop without delete
continue;
}
}
//if we made it this far, we didn't find an apple
el.parentNode.removeChild(el);
});
};

JS - Shouldn't this be written better? One function vs multiples?

I have a tweet stream where new tweets are added at the top and the older ones pushed down. You can click on the entire tweet and a panel slides down to reveal, "reply", "retweet", "favorite" etc. The panel is added to each new tweet added in the stream.
The code below works. Shouldn't this be better written so that only one call is being made? Or, as a new tweet is added. would I just have to add to the code with div#tc4, ul#tb4 etc?
$(document).ready(function () {
$("div#tc1").click(function () {
$("ul#tb1").slideToggle("fast");
});
$("div#tc2").click(function () {
$('ul#tb2').slideToggle("fast");
});
$("div#tc3").click(function () {
$('ul#tb3').slideToggle("fast");
});
});
Added Markup:
<div id="tc1" class="tweetcontainer">
<div class="avatarcontainer">
<div class="avatar"></div>
</div>
<div class="content">
<div class="tweetheader">
<div class="name">
<h1>John Drake</h1>
</div>
<div class="tweethandle">
<h2>#Drakejon</h2>
</div>
<div class="tweettime">10m</div>
</div>
<div>
<p>Exceptional Buys Ranger To Give Monitoring Shot In The Arm To Its 'DevOps' Platform http://tcrn.ch/11m3BrO by #sohear </p>
</div>
</div>
</div>
<!-------------Tool Bar -------------------------------->
<ul id="tb1" class="toolbar">
<li><a class="reply" href="#"><span>reply</span></a></li>
<li><a class="retweet" href="#"><span>retweet</span></a></li>
<li><a class="favorite" href="#"><span>favorite</span></a></li>
<li><a class="track" href="#"><span>track</span></a></li>
<li><a class="details" href="#"><span>details</span></a></li>
</ul>
I highly recommend separating your javascript from your detailed page function. The best way to do this is to put the retweeting panel inside the tweet container, then you don't even need to give it an id at all or encode in the javascript information about your html structure and ids. You can then just do:
$('.tweetcontainer').on('click', function(event) {
if ($(event.target).is(':descendantof(.toolbar)')) {
//ignore all clicks within the toolbar itself
return;
}
$(this).find('.toolbar').slideToggle();
});​
It's that easy! See it in action in a jsFiddle.
Now you can add as many tweet containers as you want to your page--and your javascript doesn't have to change one bit. Other solutions that require knowledge of specific ids linking to specific ids are suboptimal.
Note the descendantof pseudo-selector is custom (see the fiddle to find out how it works). Also, since you didn't provide any css, I had to choose some--it was quick so don't expect much. (Aww heck I just saw you updated your question to provide a jsFiddle with css giving a far prettier result--but I won't change mine now.) I did have to add a class to the actual tweet itself, but there is probably a better way to style it.
And if you want a click on the displayed toolbar itself (outside of a link) to allow collapsing the toolbar, change the code above to :descendantof(a).
If you don't want to change your page layout, another way to it is to encode the information about the linkage between html parts in the html itself using a data attribute. Change your tweetcontainer div to add a data attribute with a jQuery style selector in it that will properly locate the target:
<div class="tweetcontainer" data-target="#tb1">
You don't really have to remove the id if you use it elsewhere, but I wanted you to see that you don't need it any more. Then on document.ready:
$('.tweetcontainer').click(function () {
$($(this).data('target')).slideToggle('fast');
});
Here is another jsFiddle demonstrating this alternate technique (though it less elegant, in my opinion).
Last, I would like to mention that it seems possible you have a little bit of "div-itis". (We have all been there.) The toolbar anchor elements have unnecessary spans inside of them. The tweet name h1 element is inside a div, but could just be an h1 with class="name" instead.
In general, if there is only a single item inside a div and you can change your stylesheet to eliminate the div, then the div isn't needed. There are an awful lot of nested divs in your html, and I encourage you to remove as many of them as you can. Apply style to the other block elements you use and at least some, if not many, won't be needed.
I'd suggest (though currently untested):
$('div[id^="tc"]').click(function(){
var num = parseInt(this.id.replace(/\D+/g,''),10);
$('#tb' + num).slideToggle("fast");
});
Though given that you don't need the num to be a number (it'd be fine as a string), you could safely omit the parseInt().
Yes, you can write this code much more compactly like this:
$(document).ready(function() {
for (var i = 1; i < 3; i++) {
$("div#tc" + i).click(function() { $("ul#tb" + i).slideToggle("fast"); } );
}
});

Javascript or jQuery for Adding Style to Phrases on Page

I'm applying a style to a certain phrase on our website over and over again. Is there a way to search the page for instances of that phrase and apply that style automatically?
Example:
<div>
This is what you get from <span class="comp">Company Name</span>.
We do all kinds of things here at <span class="comp">Company Name</span>.
</div>
You could take a look at these questions:
Highlight a word with jQuery
How to highlight certain words with jQuery
Both of the top answers point to the highlight plugin for jQuery.
sure...
http://docs.jquery.com/Selectors/contains#text
$("div:contains('Conpany Name')").css("text-decoration", "underline");
var body = document.getElementByTagName("body")[0].innerHTML;
body.replace(/Company Name/g, '<span class="comp">Company Name</span>');
document.getElementByTagName("body")[0].innerHTML = body;
The above should get everything in the body and replace it with your span and that doesnt need jQuery.

Categories