Target <div> with Javascript? - javascript

I have code similar to this:
<div>
<div> randomText 11235 </div>
<div> randomText </div>
<div> randomText </div>
<div> randomText </div>
<div> randomText </div>
</div>
As you can see, each div contains random text but the first div also has a "11235" added at the end.
This "11235" will be added at the end of any of the divs (Note that this can be multiple divs).
Here is one scenario that can happen:
<div>
<div> randomText </div>
<div> randomText 11235 </div>
<div> randomText </div>
<div> randomText 11235 </div>
<div> randomText </div>
</div>
Is is possible to be able to target those divs that only have the 11235 added onto the end and remove the 11235.
I would prefer a solution in javascript (jQuery is fine).
Thanks

Using jQuery you could iterate all divs containing 11235 and replace '11235' in the text of those elements using the standard js-replace function:
$("div div:contains('11235')").each(function () {
$(this).text($(this).text().replace("11235",""));
});
As noted by Rick you could also use implicit iteration, it's slightly more elegant:
$("div div:contains(11235)").text(function (i, text) {
return text.replace("11235","");
});
If there's any chance each div element might contain multiple occurances of 11235 use the regex-version of replace:
$("div div:contains(11235)").text(function (i, text) {
return text.replace(/11235/g,"");
});

You can use the :contains() selector and the html() method of jQuery, like this:
$("div:contains(11235)").html(function( i, html ) {
return $.trim( ( html || "" ).replace(/11235/g, "") );
});
This works without the need for iterating with each() as jQuery is built on the contept of "implied iteration", meaning all setter methods will automatically iterate each element they receive from the calling jQuery object (unless otherwise noted).
See: http://jsfiddle.net/rwaldron/DeybW/

Related

Find elements of similar hierarchy by JavaScript (for web scraping)

For example, when I select one of the p.item-title elements below, all p.item-title elements should be found (not by the class name). Also, when I select one of the table elements below, all similar tables should be found. I need this for web scraping.
<div>
<div>
<p class="item-title">...</p>
<table>...</table>
</div>
</div>
<div>
<div>
<p class="item-title">...</p>
<table>...</table>
</div>
</div>
jQuery's siblings() method is similar in concept, but it finds similar elements under the same parent node. Is there any method or library to find similar elements from different parent nodes?
Just do querySelectorAll by the path (hierarchy) you want:
var allElements = document.querySelectorAll("div > div > p");
allElements.forEach(p => console.log(p));
<div>
<div>
<p class="item-title">Text 1</p>
<table>...</table>
</div>
</div>
<div>
<div>
<p class="item-title">Text 2</p>
<table>...</table>
</div>
</div>
Try this:
jQuery.fn.addEvent = function(type, handler) {
this.bind(type, {'selector': this.selector}, handler);
};
$(document).ready(function() {
$('.item-title').addEvent('click', function(event) {
console.log(event.data.selector);
let elements = document.querySelectorAll(event.data.selector);
elements.forEach(e => console.log(e));
});
});
Thanks to Jack, I could create a running script.
// tags only selector (I need to improve depending on the use case)
function getSelector(element){
var tagNames = [];
while (element.parentNode){
tagNames.unshift(element.tagName);
element = element.parentNode;
}
return tagNames.join(" > ");
}
function getSimilarElements(element) {
return document.querySelectorAll(element);
}

Move closing </a> tag to the end of a containing element

I'm trying to get a link to wrap around all text within a div. I can only find solutions where you move certain DOM elements entirely, or move other elements into an element.
current situation:
<div class="text">
text and more text
</div>
desired situation:
<div class="text">
text and more text
</div>
Unfortunately, I cannot change the markup, so I have to do something with jQuery.
Avoid messing with html directly, it's better not to change it or overwrite. All you need to do is to take next text sibling Node and append to previous a:
$('.text a').each(function() {
$(this).append(this.nextSibling)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text">
text and more text
</div>
If necessary you can check for the next node to be TextNode, if you need to skip element nodes:
if (this.nextSibling.nodeType === 3) {
$(this).append(this.nextSibling)
}
You need to use .append( function ) to insert nextSibling of anchor into it.
$(".text a").append(function(){
return this.nextSibling
});
$(".text a").append(function(){
return this.nextSibling
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text">
text and more text
</div>
Also you can use .html( function ) instead and then remove next sibling using .remove()
$(".text a").html(function(i, h){
return h + this.nextSibling.nodeValue;
})[0].nextSibling.remove();
Or in one line using ES6
$(".text a").html((i,h) => h+this.nextSibling.nodeValue)[0].nextSibling.remove();
$(".text a").html(function(i, h){
return h + this.nextSibling.nodeValue;
})[0].nextSibling.remove();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text">
text and more text
</div>
Or using pure javascript
var ele = document.querySelector(".text a");
ele.innerHTML += ele.nextSibling.nodeValue;
ele.nextSibling.remove();
var ele = document.querySelector(".text a");
ele.innerHTML += ele.nextSibling.nodeValue;
ele.nextSibling.remove();
<div class="text">
text and more text
</div>
HTML/JavaScript doesn't work in a way that you can "move" a closing tag like that, but what you can do is move the text. Also, you don't need jQuery to do it; it's very easy to do with vanilla JavaScript:
let link = document.querySelector('.text a')
let textAfterLink = link.nextSibling
link.appendChild(textAfterLink)
<div class="text">
text and more text
</div>
You can first get the HTML inside the div with class text and then replace the closing tag </a> with '' then finally append a closing </a> tag to the replaced string so that you get what you expect:
var aHTML = $('.text').html();
aHTML = aHTML.trim().replace(/<\/a>/, '') + '</a>';
$('.text').html(aHTML);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text">
text and more text
</div>
Here you have one approach that will find all unwraped text inside the element with class .text and append all of these texts to the first <a> child. This approach uses the content() method chained with a filter() using the addequated condition for remove the texts children, while at the same time they are appended to the <a> element.
$('.text').each(function()
{
$(this).contents().filter(function()
{
// Filter text type only.
return (this.nodeType === 3);
})
.appendTo($(this).find("a:first-child"));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text">
text and more text
</div>
<hr>
<div class="text">
Rise up this morning
Smile with the rising sun
<br>
Three little birds
<br>
Pitched by my doorstep
<br>
<p>DON'T TOUCH THIS ONE!</p>
Singing sweet songs
<br>
Of melodies pure and true
<br>
Sayin': This is my message to you
<br>
Saying, don't worry about a thing
<br>
'Cause every little thing
<br>
Gonna be all right
</div>

jQuery: unwrap() deletes additional parent container

I have the container .vorteile wrapped in .vorteile_outer by jQuery. When I want to remove .vorteile_outer using .unwrap() on .vorteile, the parent container of .vorteile_outer which is #template_footer_vorteile also gets removed.
Here is the jquery part (in full context it is in a function).
$('.vorteil, :vorteil_outer:not').unwrap();
And here the HTML part
<div id="template_footer_vorteile">
<div class="vorteil_outer">
<div class="vorteil kunden">
<p class="titel">kundenzufriedenheit</p>
<p class="desc">kundenzufriedenheitText</p>
</div>
</div>
<div class="vorteil_outer">
<div class="vorteil tradition">
<p class="titel">tradition</p>
<p class="desc">traditionText</p>
</div>
<div class="clear"></div>
</div>
Just give like this
$("p").unwrap(); // vorteil class div removed
$('.vorteil').unwrap(); // vorteil_outer div removed
DEMO
If you want to remove 'template_footer_vorteile' then try this :
$('.vorteil').parent().unwrap();
and if you want to remove only "vorteil_outer" and retain the "template_footer_vorteile" then try this :
$('.vorteil').unwrap();
To remove the .vorteile_outer you always have to apply unwrap to vorteil (ie) when you want to remove the div apply unwrap to the child of that div.
var gs = $("div.vorteil");
$("button").click(function () {
if (gs.parent().is("div.vorteil_outer")) {
gs.unwrap();
}
});
here is fiddle
To know about unwrap visit http://api.jquery.com/unwrap/

Javascript onmouseover and onmouseout

You can see in the headline what it is. I've four "div", and therein are each a p tag. When I go with the mouse on the first div, changes the "opacity" of the p tag of the first div. The problem is when I go on with the mouse on the second or third "div" only changes the tag "p" from the first "div". It should changes the their own "p" tags.
And it is important, that i cannot use CSS ":hover".
The problem is clear, it is that all have the same "id".
I need a javascript which does not individually enumerated all the different classes.
I' sorry for my english.
I hope you understand me.
My script:
<div onmouseout="normal();" onmouseover="hover();" >
<p id="something">LOLOL</p>
</div>
<div onmouseout="normal();" onmouseover="hover();" >
<p id="something">LOLOL</p>
</div>
<div onmouseout="normal();" onmouseover="hover();" >
<p id="something">LOLOL</p>
</div>
<div onmouseout="normal();" onmouseover="hover();" >
<p id="something">LOLOL</p>
</div>
Javascript:
function normal() {
var something = document.getElementById('something');
something.style.opacity = "0.5";
}
function hover() {
var something = document.getElementById('something');
something.style.opacity = "1";
CSS:
p {
opacity: 0.5;
color: red;
}
As Paul S. suggests, you need to pass this to the function so that it knows which element it has to work on.
<div onmouseout="normal(this);" onmouseover="hover(this);" >
<p>LOLOL</p>
</div>
<div onmouseout="normal(this);" onmouseover="hover(this);" >
<p>LOLOL</p>
</div>
<div onmouseout="normal(this);" onmouseover="hover(this);" >
<p>LOLOL</p>
</div>
<div onmouseout="normal(this);" onmouseover="hover(this);" >
<p>LOLOL</p>
</div>
And then select the child element <p> for the passed <div>. Here I select the first child p, i.e. the first element in the array of children of this element with tag p, that's why you see [0]. So if in each div you had two paragraph, then you could use e.g. getElementsByTagName("p")[1] to select the second <p>.
function normal(mydiv) {
mydiv.getElementsByTagName("p")[0].style.opacity="0.5";
}
function hover(mydiv) {
mydiv.getElementsByTagName("p")[0].style.opacity="1";
}
See the working example here: http://jsfiddle.net/mastazi/2REe5/
Your html should be something like this:
<div onmouseout="normal(1);" onmouseover="hover(1);">
<p id="something-1">LOLOL</p>
</div>
<div onmouseout="normal(2);" onmouseover="hover(2);">
<p id="something-2">LOLOL</p>
</div>
<div onmouseout="normal(3);" onmouseover="hover(3);">
<p id="something-3">LOLOL</p>
</div>
<div onmouseout="normal(4);" onmouseover="hover(4);">
<p id="something-4">LOLOL</p>
</div>
As you can see, we have different ids for your elements, and we pass the ids through the function that we trigger with onlouseover and onmouseout.
For your javascript, your code could be something like this:
function normal(id) {
var something = document.getElementById('something-'+id);
something.style.opacity = "0.5";
}
function hover(id) {
var something = document.getElementById('something-'+id);
something.style.opacity = "1";
}
For normal() and hover() we receive an id and change the style for the current element that have this id.
Please, check this JSFiddle that I've built for you.

hide div (it contains only script tag)

Hi I want to hide some divs on my webpage, they contain only script tags...how do I do that?
for example..
<div>
<div>
<div>
<script type="text/javascript">some js code</script>
</div>
<script type="text/javascript">some js code</script>
</div>
</div>
basically these divs are empty but they have script tags in it so using empty is not working. Can anyone please suggest how can I remove these divs. My aim is to remove the parent tag itself if there is no value in any of the child.
how can I identify that all the childs are empty for given parent. (I want to check for empty childs and even if it has script I want to ignore that and consider it as empty and finally if all the childs are empty, I want to remove the parent node)
for example consider this...(there can be any number of child, if all are empty then remove the parent)(I want to ignore the script tag and consider that as empty if no value is there other then script tag)
<div class="printpage">
<div class="flip">
<div>empty div</div>
<div>
<div>
<div>empty div</div>
<div>
<div>empty div</div>
<div>
<script>script</script>
<div>empty div</div>
</div>
<script>script</script>
</div>
</div>
</div>
</div>
<div class="flip">
<div>empty div</div>
<div>
<div>
<div>empty div</div>
<div>
<div>empty div</div>
<div>
<script>script</script>
<div>empty div</div>
</div>
<script>script</script>
</div>
</div>
</div>
</div>
EDIT this was harder than it sounds. This is an updated answer following #VisioN's observation that the script element's own text wasn't being ignored.
This should check whether any element apart from the <script> element contains any text output.
$('div').each(function() {
var $this = $(this);
var $c = $this.contents();
for (var i = 0, n = $c.length; i < n; ++i) {
var c = $c.get(i);
var tag = c.tagName;
if (tag === 'SCRIPT') continue; // ignore script tag
if (tag === 'IMG' || tag === 'CANVAS') return; // non-text output
if ($.trim($(c).text()).length > 0) { // check text content
return;
}
}
$this.hide();
});​
See http://jsfiddle.net/alnitak/PdCnL/
You can use :has selector:
$('div:has(script)').hide();
Or:
$('div > script').parent().hide()
$('div > script').parent().filter(function() {
return !$('script', this).siblings().length
}).remove()
You can use jQuery filter . following code will make sure that only those div get hidden which contain script tag only.
var divs = $("div")​.filter(function(){
console.log();
return $(this).text().replace(/\s/gi,'') == $('script', this).text().replace(/\s/gi,'');
}).hide();
alert(divs.length); // return 3
​
DEMO

Categories

Resources