I want to get all specific elements that appears in DOM after a specific element by jQuery.
for example all p elements that appears after p element with id="pr3".`
<div>
<p id='pr3'></p>
<span></span>
<p></p> //this p element
</div>
<div>
<p></p> //this p element
<table>...</table>
</div>
<p></p> //this p elemnt and ...
for example change color of all p elements that located after id='pr3'
You can use .index() to get the benchmark element. resource: https://api.jquery.com/index/
var current_p = $( "#pr3" );
var current_p_index=$( "p" ).index( current_p )
console.log( current_p_index );
Use the .slice() method constructs to get all p elements that appears after id='pr3'. resource: https://api.jquery.com/slice/
$( "p" ).slice( current_p_index ).css( "background-color", "red" );
There's nothing built-in that will do this, but jQuery (and the DOM) give you all the tools you need to do it. I got to wondering how hard it would be, and it turns out not to be that bad, see comments:
// Add elements following the given set of elements
// that match the given selector to the target
function addFollowing(target, set, selector) {
target = target.add(set.nextAll(selector));
target = target.add(set.nextAll().find(selector));
return target;
}
// Start with #pr3
let set = $("#pr3");
let paras = $();
// Add the ones that follow it at that level
paras = addFollowing(paras, set, "p");
// Loop up through parents
set = set.parent();
while (set[0] && set[0] !== document.documentElement) {
// Add the ones that follow at this level
paras = addFollowing(paras, set, "p");
set = set.parent();
}
console.log(`Found ${paras.length} p elements`);
paras.css("color", "green");
<p>no</p>
<div>
<p>no</p>
<div>
<p>no</p>
</div>
<div>
<p>no</p>
<p id="pr3">pr3</p>
<span></span>
<p>yes 1</p>
</div>
</div>
<div>
<p>yes 2</p>
<table>
<tr>
<td>
<p>yes 3</p>
</td>
</tr>
</table>
</div>
<p>yes 4</p>
<div>
<div>
<p>yes 5</p>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Related
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);
}
I want to make display:none parent element innertext If span element has some value and the same if span tag has empty value, i want to make it display: block.
Hope it would be clear.
var $value = $('div').children().remove().end().text();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
test
<span>span element</span>
</div>
If I understood the question correctly, you want to remove hide all child text nodes and not elements... Here you go...
$(function() {
$("div").each(function() {
if ($(this).find("span").text()) {
$(this)
.contents()
.filter((i, node) => node.nodeType === Node.TEXT_NODE)
.wrapAll("<span style='display:none'></span>");
}
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
test
<span>span element</span>
</div>
<div>
test 2
<span>span element 2</span>
</div>
<div>
test 3
</div>
<div>
test 4
<span></span>
</div>
If I understood, you can do something like that -
// keep the children elements
var children = $('#div-id').children();
// remove div content
$('#div-id').html('');
// return the children
$('#div-id').append(children);
How about just replacing with the text you want?
var $value = $('span').text();
if($value != null) $('div').text($value);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
test
<span>span element</span>
</div>
Check it out
if($('div').children().text()!= ''){
$('div').children().text($('div').children());
}
Basically I want to change smiley.gif to landscape.jpg without changing divs and tags, but this code is not working.
Any suggestions?
<div id="foo">
<div id="bar"><img src="smiley.gif">
Hello world!
</div>
</div>
<script>
getElementById("bar").getElementsByTagName("img").src="landscape.jpg";
</script>
getElementById is a method that you can only call on the document. getElementsByTagName will return a nodelist, and you need the first element in that nodelist:
document.getElementById("bar").getElementsByTagName("img")[0].src="landscape.jpg";
// Note the `[0]` here -----------------------------------^^^
JSFiddle
it will be better if you assign ID to img tag and use it like this
<div id="foo">
<div id="bar"><img src="smiley.gif" id="myImg"> Hello world! </div>
</div>
<script>
document.getElementById("myImg").src="landscape.jpg";
</script>
jsfiddle1
or Use this
<div id="foo">
<div id="bar"><img src="smiley.gif"> Hello world! </div>
</div>
<script>
var obj = document.getElementById("foo");
if(obj != null)
{
var images = obj.getElementsByTagName('img');
images[0].src = 'landscape.jpg';
}
</script>
As you have confirmed that the layout is fixed, then simply use.
document.getElementById('bar').firstElementChild.src = 'landscape.jpg';
This basically finds the unique element named bar, chooses the first child element (not firstChild, which could be an empty text node) and assigns the new value to src
Documentation on MDN
getElementById
firstElementChild
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.
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