Skip to main content
added 25 characters in body
Source Link
Shaggy
  • 173
  • 1
  • 9

I have a function I've been using for years that retrieves the index of an HTML element within its parent element, or, if a second argument is passed to it, the index of an HTML element within the collection of elements of the same name in that parent:

var childindex=function(node){
    var index=0;
    while(node.previousSibling){
        if(arguments.length==childindex.length||node.previousSibling.nodeName.toLowerCase()==arguments[1])index++;
        node=node.previousSibling;
    }
    return index;
}

However, in a recent overhaul of my JavaScript library, I went over all these old functions to try to improve upon them and this is what I came up with to replace the above:

let childindex=(node,...selectors)=>
        Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

I'm pretty happy with the result, especially as it gives me the added ability to get the index of the element within any collection of selectors by passing each selector as a new argument and also ignores text nodes even when no additional arguments are passed to it.

I'm wondering, though, if anyone can see anywhere I can improve on it further, either in efficiency or conciseness of code.

Here's a working example to show it in action:

(()=>{
    let item=document.getElementById("getthis"),
        index=childindex=(node,...selectors)=>
            Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

    //Gets index of `item` within all child elements of <section>
    console.log(indexchildindex(item)); // 5
    //Gets index of `item` within all child <article> elements of <section>
    console.log(indexchildindex(item,"article")); // 3
    //Gets index of `item` within all child elements of <section> with .class
    console.log(indexchildindex(item,".class")); // 2
    //Gets index of `item` within all child <article> & <header> elements of <section>
    console.log(indexchildindex(item,"header","article")); // 4

})();
<section>
    <header class="class"></header>
    <article></article>
    <article></article>
    <aside class="class"></aside>
    <article></article>
    <article class="class" id="getthis"></article>
    <footer></footer>
</section>

I have a function I've been using for years that retrieves the index of an HTML element within its parent element, or, if a second argument is passed to it, the index of an HTML element within the collection of elements of the same name in that parent:

var childindex=function(node){
    var index=0;
    while(node.previousSibling){
        if(arguments.length==childindex.length||node.previousSibling.nodeName.toLowerCase()==arguments[1])index++;
        node=node.previousSibling;
    }
    return index;
}

However, in a recent overhaul of my JavaScript library, I went over all these old functions to try to improve upon them and this is what I came up with to replace the above:

let childindex=(node,...selectors)=>
        Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

I'm pretty happy with the result, especially as it gives me the added ability to get the index of the element within any collection of selectors by passing each selector as a new argument and also ignores text nodes even when no additional arguments are passed to it.

I'm wondering, though, if anyone can see anywhere I can improve on it further, either in efficiency or conciseness of code.

Here's a working example to show it in action:

(()=>{
    let item=document.getElementById("getthis"),
        index=(node,...selectors)=>
            Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

    //Gets index of `item` within all child elements of <section>
    console.log(index(item)); // 5
    //Gets index of `item` within all child <article> elements of <section>
    console.log(index(item,"article")); // 3
    //Gets index of `item` within all child elements of <section> with .class
    console.log(index(item,".class")); // 2
    //Gets index of `item` within all child <article> & <header> elements of <section>
    console.log(index(item,"header","article")); // 4

})();
<section>
    <header class="class"></header>
    <article></article>
    <article></article>
    <aside class="class"></aside>
    <article></article>
    <article class="class" id="getthis"></article>
    <footer></footer>
</section>

I have a function I've been using for years that retrieves the index of an HTML element within its parent element, or, if a second argument is passed to it, the index of an HTML element within the collection of elements of the same name in that parent:

var childindex=function(node){
    var index=0;
    while(node.previousSibling){
        if(arguments.length==childindex.length||node.previousSibling.nodeName.toLowerCase()==arguments[1])index++;
        node=node.previousSibling;
    }
    return index;
}

However, in a recent overhaul of my JavaScript library, I went over all these old functions to try to improve upon them and this is what I came up with to replace the above:

let childindex=(node,...selectors)=>
        Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

I'm pretty happy with the result, especially as it gives me the added ability to get the index of the element within any collection of selectors by passing each selector as a new argument and also ignores text nodes even when no additional arguments are passed to it.

I'm wondering, though, if anyone can see anywhere I can improve on it further, either in efficiency or conciseness of code.

Here's a working example to show it in action:

(()=>{
    let item=document.getElementById("getthis"),
        childindex=(node,...selectors)=>
            Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

    //Gets index of `item` within all child elements of <section>
    console.log(childindex(item)); // 5
    //Gets index of `item` within all child <article> elements of <section>
    console.log(childindex(item,"article")); // 3
    //Gets index of `item` within all child elements of <section> with .class
    console.log(childindex(item,".class")); // 2
    //Gets index of `item` within all child <article> & <header> elements of <section>
    console.log(childindex(item,"header","article")); // 4

})();
<section>
    <header class="class"></header>
    <article></article>
    <article></article>
    <aside class="class"></aside>
    <article></article>
    <article class="class" id="getthis"></article>
    <footer></footer>
</section>

edited tags
Link
200_success
  • 145.7k
  • 22
  • 191
  • 481
deleted 26 characters in body; added 2 characters in body
Source Link
Shaggy
  • 173
  • 1
  • 9

I have a function I've been using for years that retrieves the index of an HTML element within its parent element, or, if a second argument is passed to it, the index of an HTML element within the collection of elements of the same name in that parent:

var childindex=function(node){
    var index=0;
    while(node.previousSibling){
        if(arguments.length==childindex.length||node.previousSibling.nodeName.toLowerCase()==arguments[1])index++;
        node=node.previousSibling;
    }
    return index;
}

Pretty standard stuff.

However, in a recent overhaul of my JavaScript library, I went over all these old functions to try to improve upon them and this is what I came up with to replace the above:

let childindex=(node,...selectors)=>
        Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

I'm pretty happy with the result, especially as it gives me the added ability to get the index of the element within any collection of selectors by passing each selector as a new argument and also ignores text nodes even when no additional arguments are passed to it.

I'm wondering, though, if anyone can see anywhere I can improve on it further, either in efficiency or conciseness of code.

Here's a working example to show it in action:

(()=>{
    let item=document.getElementById("getthis"),
        index=(node,...selectors)=>
            Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

    //Gets index of `item` within all child elements of <section>
    console.log(index(item)); // 5
    //Gets index of `item` within all child <article> elements of <section>
    console.log(index(item,"article")); // 3
    //Gets index of `item` within all child elements of <section> with .class
    console.log(index(item,".class")); // 2
    //Gets index of `item` within all child <article> & <header> elements of <section>
    console.log(index(item,"header"header",article""article")); // 4

})();
<section>
    <header class="class"></header>
    <article></article>
    <article></article>
    <aside class="class"></aside>
    <article></article>
    <article class="class" id="getthis"></article>
    <footer></footer>
</section>

I have a function I've been using for years that retrieves the index of an HTML element within its parent element, or, if a second argument is passed to it, the index of an HTML element within the collection of elements of the same name in that parent:

var childindex=function(node){
    var index=0;
    while(node.previousSibling){
        if(arguments.length==childindex.length||node.previousSibling.nodeName.toLowerCase()==arguments[1])index++;
        node=node.previousSibling;
    }
    return index;
}

Pretty standard stuff.

However, in a recent overhaul of my JavaScript library, I went over all these old functions to try to improve upon them and this is what I came up with to replace the above:

let childindex=(node,...selectors)=>
        Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

I'm pretty happy with the result, especially as it gives me the added ability to get the index of the element within any collection of selectors by passing each selector as a new argument and also ignores text nodes even when no additional arguments are passed to it.

I'm wondering, though, if anyone can see anywhere I can improve on it further, either in efficiency or conciseness of code.

Here's a working example to show it in action:

(()=>{
    let item=document.getElementById("getthis"),
        index=(node,...selectors)=>
            Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

    //Gets index of `item` within all child elements of <section>
    console.log(index(item)); // 5
    //Gets index of `item` within all child <article> elements of <section>
    console.log(index(item,"article")); // 3
    //Gets index of `item` within all child elements of <section> with .class
    console.log(index(item,".class")); // 2
    //Gets index of `item` within all child <article> & <header> elements of <section>
    console.log(index(item,"header,article")); // 4

})();
<section>
    <header class="class"></header>
    <article></article>
    <article></article>
    <aside class="class"></aside>
    <article></article>
    <article class="class" id="getthis"></article>
    <footer></footer>
</section>

I have a function I've been using for years that retrieves the index of an HTML element within its parent element, or, if a second argument is passed to it, the index of an HTML element within the collection of elements of the same name in that parent:

var childindex=function(node){
    var index=0;
    while(node.previousSibling){
        if(arguments.length==childindex.length||node.previousSibling.nodeName.toLowerCase()==arguments[1])index++;
        node=node.previousSibling;
    }
    return index;
}

However, in a recent overhaul of my JavaScript library, I went over all these old functions to try to improve upon them and this is what I came up with to replace the above:

let childindex=(node,...selectors)=>
        Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

I'm pretty happy with the result, especially as it gives me the added ability to get the index of the element within any collection of selectors by passing each selector as a new argument and also ignores text nodes even when no additional arguments are passed to it.

I'm wondering, though, if anyone can see anywhere I can improve on it further, either in efficiency or conciseness of code.

Here's a working example to show it in action:

(()=>{
    let item=document.getElementById("getthis"),
        index=(node,...selectors)=>
            Array.from(selectors.length?node.parentNode.querySelectorAll(`:scope>${selectors.join(",:scope>")}`):node.parentNode.children).indexOf(node);

    //Gets index of `item` within all child elements of <section>
    console.log(index(item)); // 5
    //Gets index of `item` within all child <article> elements of <section>
    console.log(index(item,"article")); // 3
    //Gets index of `item` within all child elements of <section> with .class
    console.log(index(item,".class")); // 2
    //Gets index of `item` within all child <article> & <header> elements of <section>
    console.log(index(item,"header","article")); // 4

})();
<section>
    <header class="class"></header>
    <article></article>
    <article></article>
    <aside class="class"></aside>
    <article></article>
    <article class="class" id="getthis"></article>
    <footer></footer>
</section>

Source Link
Shaggy
  • 173
  • 1
  • 9
Loading