Consider the following HTML where IDs #p1
, #p2
and #p3
are siblings (see fiddle):
<div id="container">
<span id="p1">Paragraph 1</span>
<span id="p2">Paragraph 2</span>
This is just loose text.
<p id="p3">Paragraph 3</p>
</div>
These are my definitions of strict and loose siblings:
I consider ID #p1
and #p2
strict siblings (because there is no text which is not encapsulated in any kind of html element between them.
And ID #p2
and #p3
to be loose siblings.
Given any element with a next sibling is it possible to know if the next sibling is strict or loose?
Edit: The siblings may be of different type and I updated the fiddle to reflect that.
The adjacent sibling selector is used to select an element that is directly after another specific element. Sibling elements must have the same parent element, and "adjacent" means "immediately following".
With the adjacent-sibling selector, you can apply styles to elements based on the elements which immediately precede them in the document.
To select all sibling elements of an element, we will use siblings() method. The siblings() method is used to find all sibling elements of the selected element. The siblings are those having the same parent element in DOM Tree.
You can easily style every element which has an adjacent item right before it using the Adjacent Sibling Selector (+). The adjacent sibling selector is used to select the element that is adjacent or the element that is next to the specified selector tag.
Is this what you meant: http://cssdeck.com/labs/0blyuslnzv
var isStrict = function(elem1, elem2) {
"use strict";
var e1 = document.querySelectorAll(elem1)[0],
elemNext = document.querySelectorAll(elem1 +" + "+ elem2)[0];
if (e1.nextSibling.textContent.trim().length) {
return e1.nextSibling === elemNext;
} else {
return e1.nextElementSibling === elemNext;
}
};
Usage eg.
isStrict("head", "body") => true
isStrict("#p1", "#p2") => true
isStrict("#p2", "#p3") => false
Answering your question of
Given any element with a next sibling is it possible to know if the next sibling is strict or loose?
rather than following your lead from the fiddle, yes it's possible.
function isMyNextSiblingStrict(element)
{
return ("nodeType" in element && element.nodeType === 1 && element.nextSibling !== null && element.nextSibling.nodeType === 1);
}
This will return true
when an element's next sibling is another element. However, be careful with your example as it is incorrect by your own definition, the two spans have a text node between them made up of white space, so #1 and #2 are not "strict siblings".
<div id="container">
<span id="p1">Paragraph 1</span><!-- WHITESPACE
--><span id="p2">Paragraph 2</span>
This is just loose text.
<p id="p3">Paragraph 3</p>
</div>
These would be "strict siblings".
<div id="container">
<span id="p1">Paragraph 1</span><span id="p2">Paragraph 2</span>
This is just loose text.
<p id="p3">Paragraph 3</p>
</div>
edit - just for fun I've created a jQuery extension that should do what you want - you can see it in your updated jsFiddle, I've not tested it much but it seems to work as you describe
$.fn.extend({
siblingsStrict: function( until, selector ) {
var ret = jQuery.map( this, function( elem ) {
var n = ( elem.parentNode || {} ).firstChild,
r = [],
contig = false;
for ( ; n; n = n.nextSibling ) {
if ( n === elem ) {
contig = true;
}
else if ( n.nodeType === 1 && n !== elem ) {
r.push( n );
}
else if ( n.nodeType === 3 && n.textContent.replace(/\s/g, "") === "" ) {
continue;
}
else if ( n.nodeType === 3 && contig === true ) {
break;
}
else if ( n.nodeType === 3 && contig === false) {
r = [];
}
}
return r;
}, until );
if ( name.slice( -5 ) !== "Until" ) {
selector = until;
}
if ( selector && typeof selector === "string" ) {
ret = jQuery.filter( selector, ret );
}
if ( this.length > 1 ) {
// Remove duplicates
if ( !guaranteedUnique[ name ] ) {
ret = jQuery.unique( ret );
}
// Reverse order for parents* and prev-derivatives
if ( rparentsprev.test( name ) ) {
ret = ret.reverse();
}
}
return this.pushStack( ret );
}
});
Try this.
var $selector = $("#p1");
$selector.siblings().each(function(){
$(this).addClass('checkSelector');
if(document.querySelectorAll($selector.selector+' + .checkSelector').length){
//Do Strict Action
}else if(document.querySelectorAll($selector.selector+' ~ .checkSelector').length){
//Do non strict but still sibling action
}
$(this).removeClass('checkSelector');
});
http://jsfiddle.net/chsck/5/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With