I am trying to remove the following div from a page with my chrome extension
HTML (TO REMOVE)
<div class="base-popup js-base-popup"><div class="js-obscurity base-popup__obscurity"></div>
<div class="base-popup__indent"></div>
<div class="base-popup__wrap">
<div class="base-popup__container clearfix base-popup__container -decor" style="width:500px;">
<i class="s-icon -m -close base-popup__close js-close"></i>
<div class="base-popup__content js-content"><div><div class="s-text">Sample Text.
<!-- close tag -->
</p>
<!-- close tag in translate -->
</div></div></div>
</div>
Here is the JS in my content script
function removeElementsByClassName(names) {
var els = document.getElementsByClassName(names),
i, element;
for (i = els.count - 1; i > 0; i -= 1) {
element = els[i];
element.parentElement.removeChild(element);
}
}
removeElementsByClassName('base-popup js-base-popup');
getElementsByClassName only accepts a single class name, but you're giving it two. Since the HTML you've shown only has a single element that has either of the two classes you're using, if that's the only element you want to remove, just pick one:
removeElementsByClassName("base-popup");
// or
removeElementsByClassName("js-base-popup");
Alternately, you could use querySelectorAll with a CSS selector:
function removeElementsBySelector(selector) {
var els = document.querySelectorAll(selector),
i, element;
for (i = els.count - 1; i > 0; i -= 1) {
element = els[i];
element.parentElement.removeChild(element);
}
}
Then if you want to remove elements that have either class:
removeElementsBySelector('.base-popup, .js-base-popup');
Or if you only want to remove a single element that has both classes:
removeElementsBySelector('.base-popup.js-base-popup');
And as this is a Chrome extension, you can do that rather more simply with Array.from, forEach, and Element#remove:
function removeElementsBySelector(selector) {
Array.from(document.querySelectorAll(selector)).forEach(element => {
element.remove();
});
}
your javascript is completely wrong. the right way:
function removeElementsByClassName(names){
names=names.split(" ");//you just get elems by one class so you need to split it into multiple operations
for(var a=1;a<names.length;a++){//ability to remove multiple classes
removeElementsByClassName(names[a]);
}
var els = document.getElementsByClassName(names[0]);
for (var i =0; i<els.length ; i++) { // its length not count
var element = els[i];
element.parentElement.removeChild(element);
}
}
removeElementsByClassName('base-popup js-base-popup');
this removes all elements that contain one of these classes, if you wanted sth else see the other solution.
Related
I am trying to randomize the hero content of a home page. I have this simple code, but it affects all the divs on the page, and I only want it to affect a few.
var elems = $("div");
if (elems.length) {
var keep = Math.floor(Math.random() * elems.length);
for (var i = 0; i < elems.length; ++i) {
if (i !== keep) {
$(elems[i]).hide();
}
}
}
Here is my html:
<div id="hero1">One</div>
<div id="hero2">Two</div>
<div id="hero3">Three</div>
<div id="constant">This content does not rotate.</div>
There is another caveat to this, I need it to work within a crappy CMS that strips out my class tags. So it has to be a solution that identifies the divs based on id.
How about
var elems = $('div').not('#constant')
?
The not function removes matching elements from the set it's called on.
I tried this code to remove every other element in the body, but it didn't work.
s = document.body.childNodes;
for (var i = 1; i < (s.length / 2); i++) {
if ((i % 2) == 0) {
document.body.removeChild(s[1]);
} else {
document.body.removeChild(s[0]);
}
}
<body>
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<div id="div4"></div>
<div id="div5"></div>
<div id="div6"></div>
</body>
There are a number of problems with your code. For one thing the logic is off, but there are some major problems with how the code deals with the DOM manipulations:
Your HTML causes text nodes to be created between your elements. And your code does not handle this.
The childNodes list changes as you remove nodes from the parent element.
With this HTML:
<div id="test-container">
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
<div id="div6">6</div>
</div>
And this JavaScript:
var container = document.getElementById("test-container");
var child = container.firstElementChild;
var remove = true;
while (child) {
var next = child.nextElementSibling;
if (remove)
container.removeChild(child);
remove = !remove;
child = next;
}
I can remove every other child. I avoid both problems I pointed out earlier by using firstElementChild and nextElementSibling.
First, you need to get the elements using children or querySelectorAll() not childNodes, childNodes will get all nodes including the text. Try the following code:
var s = document.body.children;
var itemCount = s.length;
for (var i = 0; i < itemCount; i++)
{
if (i % 2 !== 0)
{
document.body.removeChild(s[i]);
}
}
Here is a JSBin example.
Note that in JSBin we get the elements using querySelectorAll(), beacuse it also adds script elemets inside the body, for example:
var s = document.querySelectorAll('div');
Also, note that IE8 and below includes comment nodes when using children.
You need to know that a nodeList will update when the dom is updated, that means that if you are removing the first child node, the element 0 in the list will not refer to null but the node that was initial child 1.
This means that if you want to remove node 0, 2, 4, 6, ... you will actually have to remove 0,1,2,3,4... (because the nodeList always will update):
var body = document.body;
// Consider that you might want to use `body.children` instead of
// `body.childNodes` because it excludes all text nodes
var nodes = body.childNodes;
var len = nodes.length / 2;
for ( var i = 0; i < len; i++ ) {
body.removeChild(nodes[i]);
}
I know it can seams kind of odd, but this will actually remove all the nodes: 0, 2, 4, 6, ...
See more at MDN
I'd just use querySelectorAll with a :nth-child(odd) selector:
var divs = document.querySelectorAll('body > div:nth-child(odd)');
divs = [].slice.call(divs); // convert from NodeList to real array
divs.forEach(function(elem) {
document.body.removeChild(elem);
});
jsFiddle
Why not use jQuery and simply do:
$('.remOdd').on('click', function(){
$('div').filter(':odd').remove();
})
http://jsfiddle.net/dh5uymzL/
Or of course use ":even" if you like
http://api.jquery.com/filter/
Hi i am trying to change Display property of any HTML Tag with certain attribute..
But after many tries i am unable to change the tag properties.. My code is as below
function getAllElementsWithAttribute(attribute)
{
var matchingElements = [];
var allElements = document.getElementsByTagName('*');
for (var i = 0; i < allElements.length; i++)
{
if (allElements[i].getAttribute(attribute))
{
// Element exists with attribute. Add to array.
matchingElements.push(allElements[i]);
}
}
return matchingElements;
}
tags = getAllElementsWithAttribute('data-shares');
for(i=0;i<tags.length;i++)
{
tags[i].style.display = "none";
}
And the HTML has below Tag
<div class="shareTools" data-shares="facebook" data-url="#" data-title="Facebook" data-description="Facebook">
<div class="shareToolsBox">
<ul class="shareToolsList">
<li data-share="facebook">
<span>Facebook</span>
</li>
</ul>
</div>
</div>
Does anyone has any idea how to change Tag Style of any tag which has attribut i-e data-shares...
Change the function call to:
tags = getAllElementsWithAttribute('data-shares');
Here's it working on a JS Bin demo: http://jsbin.com/ufogExo/1/ The <div>s with the data-shares attribute are all hidden.
The problem was indeed the extra commas you had on your function call arguments.
I believe this does what you want:
function getAllElementsWithAttribute(attribute)
{
var items = document.querySelectorAll('['+attribute+']'),
i = items.length;
while ( i-- > 0 && (items[i].style.display = 'none') );
}
getAllElementsWithAttribute('data-shares');
see
http://jsfiddle.net/754zR/
I wrote a function to insert divs dynamically into the web page. but then I have to remove these divs. While adding the divs I used a classname to all the divs. So I got all the elements from the dom using getElementsByClassName() and looping through all these elements and deleting the divs. My code is not removing all the divs that were created earlier.
Please find my code snippet:
var elements = document.getElementsByClassName("xxxx");
for (var i = 0; i < elements .length; i++) {
var element = elements[i];
if (element && element.hasChildNodes()) {
var parent_node = element.parentNode;
while(element.firstChild) {
parent_node.insertBefore(element.firstChild, element);
}
parent_node.removeChild(element);
}
elements = document.getElementsByClassName("xxxx");
}
You need to remove the last line "elements = document.getElementsByClassName("xxxx");" - that line will cause you to miss out every other element as you go around the loop.
If all you want is to remove all DIV elements with that class, you can use this code:
var elements = document.getElementsByClassName("xxxx");
while ( elements[0] ) {
elements[0].parentNode.removeChild(elements[0]);
}
It will remove your DIVs and their child nodes as well.
I have some div ids that are generated dynamicly via php
<div id='a<?php echo $gid?>>
How can I access them in JavaScript? All these divs start with "A" followed by a number.
Is there some kind of search function
getElementById(a*)?
Thanks for any help
No generic JavaScript function for this (at least not something cross browser), but you can use the .getElementsByTagName and iterate the result:
var arrDivs = document.getElementsByTagName("div");
for (var i = 0; i < arrDivs.length; i++) {
var oDiv = arrDivs[i];
if (oDiv.id && oDiv.id.substr(0, 1) == "a") {
//found a matching div!
}
}
This is the most low level you can get so you won't have to worry about old browsers, new browsers or future browsers.
To wrap this into a neater function, you can have:
function GetElementsStartingWith(tagName, subString) {
var elements = document.getElementsByTagName(tagName);
var result = [];
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.id && element.id.substr(0, subString.length) == subString) {
result.push(element);
}
}
return result;
}
The usage example would be:
window.onload = function() {
var arrDivs = GetElementsStartingWith("div", "a");
for (var i = 0; i < arrDivs.length; i++) {
arrDivs[i].style.backgroundColor = "red";
}
};
Live test case.
In case you choose to use jQuery at some point (not worth for this thing alone) all the above code turns to single line:
$(document).ready(function() {
$('div[id^="a"]').css("background-color", "blue");
});
Updated fiddle, with jQuery.
No, you need a fixed id value for getElementById to work. However, there are other ways to search the DOM for elements (e.g. by CSS classes).
You can use querySelectorAll to get all divs that have an ID starting with a. Then check each one to see if it contains a number.
var aDivs = document.querySelectorAll('div[id^="a"]');
for(var index = 0, len = aDivs.length; index < len; index++){
var aDiv = aDivs[index];
if(aDiv.id.match(/a\d+/)){
// aDiv is a matching div
}
}
DEMO: http://jsfiddle.net/NTICompass/VaTMe/2/
Well, I question myself why you would need to select/get an element, that has a random ID. I would assume, you want to do something with every div that has a random ID (like arranging or resizing them).
In that case -> give your elements a class like "myGeneratedDivs" with the random ID (if you need it for something).
And then select all with javascript
var filteredResults=document.querySelectorAll(".myGeneratedDivs").filter(function(elem){
....
return true;
});
or use jQuery/Zepto/YourWeaponOfChoice
var filteredResults=$(".myGeneratedDivs").filter(function(index){
var elem=this;
....
return true;
});
If you plan to use jQuery, you can use following jQuery selectors
div[id^="a"]
or
$('div[id^="id"]').each(function(){
// your stuff here
});
You will have to target the parent div and when someone click on child div inside a parent div then you can catch the child div.
<div id="target">
<div id="tag1" >tag1</div>
<div id="tag1" >tag2</div>
<div id="tag1" >tag3</div>
</div>
$("#target").on("click", "div", function() {
var showid = $(this).attr('id');
alert(showid)
});
getElementById() will return the exact element specified. There are many javascript frameworks including jQuery that allow much more powerful selection capabilities. eg:
Select an element by id: $("#theId")
Select a group of elements by class: $(".class")
Select subelements: $("ul a.action")
For your specific problem you could easily construct the appropriate selector.