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.
Related
I'm trying to remove a toggle function from the page when a childElement is not present. This has to be done in vanilla javascript. Unfortunately, can not use jQuery. Here's what's going on.
when I run this in the console
let content = document.getElementById('productItemRates-1');
console.log(content.firstElementChild);
Code snippet is returned for checking if childElement is present:
<div class="product-rate-card">
<div class="product-rate-card-title">
<strong>Clean Power</strong>
<button type="button" class="card-btn-plain card-tooltip" data-toggle="modal" data-target="#PK1" data-original-title="" title="">
</button>
</div>
</div>
Which is the firstElementChild: div.product-rate-card
What I'm trying to do:
Define logic to only remove the toggle button from all locations on the page (not specific to element) if the specific firstElementChild: .product-rate-card is not present in the ParentID: productItemRates-1. There are other references of the childElement: .product-rate-card found in other parentsIDs within the page. Also, order logic wont work because other childElements can take it's place when it is not present.
Used the below code to test removal, that worked, just can't figure out the conditioning logic.
document.querySelectorAll(".product-rates-toggle").forEach(el => el.remove());
Appreciate any guidance..
// replace document to content
if (!document.querySelector(".product-rate-card")) {
for (const el of document.querySelectorAll(".product-rates-toggle")) {
el.remove();
}
}
Based on a comment of yours:
const toggleratecard = document.querySelector("#productItemRates-1");
if (toggleratecard.querySelector('.product-rate-card') === null) {
toggleratecard.querySelectorAll(".product-rates-toggle").forEach(el => el.remove()); }
}
Unfortunately your question does not offer any information as to where the toggle is that needs to be removed. My answer assumes it's in the toggleratecard. You can replace that with document if all the toggle on the whole page need to be removed.
Also, from what you write, it isn't entirely clear if the element, if present, must be the first element child.
I have a template:
function useIt() {
var content = document.querySelector('template').content;
// Update something in the template DOM.
var span = content.querySelector('span');
span.textContent = parseInt(span.textContent) + 1;
document.querySelector('#container').appendChild(
document.importNode(content, true));
}
<button onclick="useIt()">Use me</button>
<div id="container"></div>
<template>
<div>Template used: <span>0</span></div>
<script>alert('Thanks!')</script>
</template>
You can try the code here.
This code basically copies the template(html5 templates does not render on your screen) into another div. This allows you to reuse the DOM.
Problem: The line "span.textContent = parseInt(span.textContent) + 1;" changes the template code directly. I need to manipulate the content DOM and clone it into the container, without changing the template. This is very important since if I want to reuse the code, I need it to stay the same.
I have tried multiple ways to use jQuery to mimic the above javascript code, but I can't manage to figure it out. It would be better if there is a jQuery way.
If you NEED to use the new <template> tag, then you are mildly stuck . . . your cleanest alternative is to use importNode to bring in the content and then modify it after it's been appended.
Assuming that the templated code is realtively small, this should happen fast enough that you would never notice the difference in approach, though, in this specific example, the alert(), would delay the change of the content, so you would see "0", until you clicked "Okay", and then it would update to "1".
The code change for that would be:
function useIt() {
var content = document.querySelector('template').content;
var targetContainer = document.querySelector('#container');
targetContainer.appendChild(document.importNode(content, true));
var $span = $(targetContainer).find("div:last-of-type").find("span");
$span.text(parseInt($span.text() + 1));
}
If you are not married to the idea of <templates>, you could use jQuery's clone() method to do what you want to do, very easily . . . but, clone does not "see" the content of a <template>, due to the special nature of that particular element, so you would have to store the templated code some other way (JS variable, hidden div, etc.).
HOWEVER, this method will not work if you need to clone a script, the way that a <template> will. It will not trigger any script code in the "template container" element when the cloned version is created or appended. Additionally, if you store it in a hidden <div>, any script code in the "template container" element will trigger immediately on page load.
A simple version of the code for the clone() approach would look something like this:
function useIt() {
var $content = $("#template").clone();
var $span = $content.find("span");
$span.text(parseInt($span.text()) + 1);
$content.children().each(function() {
$("#container").append($(this));
});
}
Assuming that your template was:
<div id="template" style="display: none;">
<div>Template used: <span>0</span></div>
<script>alert('Thanks!')</script>
</div>
You could also move the <script>alert('Thanks!')</script> out of the template and into the script section (after you completed the "append loop"), to achive the desired alert functionality, if you wanted to.
It's an old question, but, did you try cloneNode(true)? It works on templates, as this:
var span = content.querySelector('span').cloneNode(true)
regards.
I want to replace some tag-inside-a-paragraph-tag by a heading-tag-enclosed-by-a-paragraph tag. This would result in proper W3C coding, but it seems that jQuery is not able to manipulate the DOM in the right way!? I tried several ways of (jQuery) coding, but i can't get it to work ..
Original code:
<p>some text <span>replace me</span> some more text</p>
Desired code:
<p>some text</p><h2>my heading</h2><p>some more text</p>
Resulting code by jQuery replaceWith():
<p>some text<p></p><h2>my heading</h2><p></p>some more text</p>
Demo: http://jsfiddle.net/foleox/J43rN/4/
In this demo, look at "make H2 custom" : i expect this to work (it's a logical replace statement), but it results in adding two empty p-tags .. The other 2 functions ("make code" and "make H2 pure") are for reference.
Officially the W3C definition states that any heading tag should not be inside a paragraph tag - you can check this by doing a W3C validation. So, why does jQuery add empty paragraph tags? Does anybody know a way to achieve this? Am i mistaken somehow?
You can achieve this with this code. However it's pretty ugly:
$('.replaceMe').each(function() {
var $parent = $(this).parent(),
$h2 = $(this).before('$sep$').wrap('<h2>').parent().insertAfter($parent);
var split = $parent.html().split('$sep$');
$parent.before('<p>' + split[0] + '</p>');
$h2.after('<p>' + split[1] + '</p>');
$parent.remove();
});
http://jsfiddle.net/J43rN/5/
If you read the jQuery docs, you will find:
When the parameter has a single tag (with optional closing tag or
quick-closing) — $("<img />") or $("<img>"), $("<a></a>") or $("<a>")
— jQuery creates the element using the native JavaScript
createElement() function.
So that is exactly what it is doing. And as I said in my comment, you can't change a parent node from a child node, you're altering the DOM here, not HTML code. So you'll need to either use replaceWith on the parent node and replace everything or use something like remove and append to split it up in multiple elements which you append after each other.
Try this:
var temp = "<p>some text <span>replace me</span> some more text</p>";
temp.replace(/(\<span\>replace me\<\/span\>)/gi, '</p><h2>my heading</h2><p>');
This will do a case insensitive replace for multiple occurences as well.
Read more about capturing groups here
Original credit to this question!
Please try this I have updated the http://jsfiddle.net/J43rN/6/ example by the below java script function please check I hope it will work for you
function fnMakeCode() {
$('#myP #replaceMe').html("<code id='replaceMe'>My Code</code>");
}
function fnMakeH2pure() {
$('#myP #replaceMe').html("<h2 id='replaceMe'>My H2 pure</h2>");
}
function fnMakeH2custom() {
$('#replaceMe').html("<p></p>").html("<h2>My H2 custom</h2>");
}
I've been building a list of links, all of which should change the content of a div to another specific content (about 4 lines of stuff: name, website, contact etc.) upon a click.
I found this code:
<script type="text/javascript">
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
</script>
and used it in such a way:
<li class="pl11">
superlink')">Pomorskie</a>
</li>
And it doesn't work as I expected.
It changes hyperlinks text from 'Pomorskie' to 'superlink'.
The plain text works just fine but I need links.
here's the http://xn--pytyfundamentowe-jyc.pl/projektanci/kontakty-p/ (only two of them show anything)
But after trying all of your recomendations, I think I'd jump to different divs with #links, cause nothing worked with this :/
Thanks a lot for trying, and cheers :)
Just as a completely sideways look at this, I'd suggest avoiding the nesting weirdness / complexity, and reducing the problem down.
Setup the content in a hidden (ie. <div id="replacements">...</div>) Grab the innerHTML from the node you want, and be done with it.
Much easier to get replacement content from non-devs that way too, kinda works great if you're in a team.
// Probably better in a separate helpers.js file.
function replaceContentInContainer(target, source) {
document.getElementById(target).innerHTML = document.getElementById(source).innerHTML;
}
Control it with: (lose that href=javascript: and use onClick, better as an event handler, but for brevity I'll inline it as an onClick attribute here, and use a button.)
<button onClick="replaceContentInContainer('target', 'replace_target')">Replace it</button>
We have our target somewhere in the document.
<div id="target">My content will be replaced</div>
Then the replacement content sits hidden inside a replacements div.
<div id="replacements" style="display:none">
<span id="replace_target">superlink</span>
</div>
Here it is in JSBin
Improve the dynamic nature of this by using Handlebars or another nice JS templating library, but that's an exercise for the OP.
edit: Note, you should also name functions with a leading lowercase letter, and reserve the leading uppercase style for Class names e.g. var mySweetInstance = new MySpecialObject();
The quotes are mismatched! So when you click you are getting a JavaScript error.
The browser sees this string:
href="javascript:ReplaceContentInContainer('wojewodztwo', 'superlink')">Pomorskie<
as:
href="javascript:ReplaceContentInContainer('wojewodztwo', '<a href="
Chnage the " inside to #quot;
<li class="pl11">
Pomorskie
</li>
Example fiddle.
Also note, using the href tag for JavaScript is a BAD practice.
You've got a problem with nested quotes. Take a look in your DOM inspector to see what the HTML parser built from it! (in this demo, for example)
You either need to HTML-escape the quotes inside the attribute as " or ", or convert them to apostrophes and escape them inside the JS string with backslashes:
<a href="j[…]r('wojewodztwo', '<a href="http://address.com">superlink</a>')">…
<a href="j[…]r('wojewodztwo', '<a href=\'http://address.com\'>superlink</a>')">…
See working demos here and here.
Better, you should use a onclick attribute instead of a javascript-pseudo-url:
<a onclick="ReplaceContentInContainer('wojewodztwo', …)">Pomorskie</a>
or even a javascript-registered event handler:
<li class="pl11">
<a id="superlink">Pomorskie</a>
</li>
<script type="text/javascript">
function replaceContentInContainer(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
document.getElementBId("superlink").onclick = function(event) {
replaceContentInContainer('wojewodztwo', 'superlink');
event.prevenDefault();
};
</script>
(demo)
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"); } );
}
});