javascript - Sort an array with DOM tags and attributes by left and top values - Stack Overflow

I have got an array with DOM tags (div -> children img -> div closed). Those tags has attributes

I have got an array with DOM tags (div -> children img -> div closed). Those tags has attributes (left and top values). I added em as nodeLists so i can access elements offsetLeft and offsetTop to determine those values but i cant figurate out how to rearange those tags in the array ascending by left or top values.

HTML

<body>
    <div style="left:40px;top:10px;position:absolute">
        <img src="assets/images/text1.png" />
    </div>
    <div style="left:200px;top:88px;position:absolute">
        <img src="assets/images/text2.png" />
    </div>
    <div style="left:85px;top:166px;position:absolute">
        <img src="assets/images/text3.png" />
    </div>
</body>

JavaScript

var unsortedElements = [];
        var sortedElements = [];

        var elements = document.querySelectorAll("body > div");
        for (var i = 0; i < elements.length; i++) {
            var element = elements[i];
            if (element != null) {
                unsortedElements.push(element);

                var x = element.offsetLeft;
                var y = element.offsetTop;
                customSort(unsortedElements[i]);
            }
        }

function customSort(element){
var left = element.offsetLeft;

sortedElements.push(left);
console.log(sortedElements); -> will return the left values (40,85,200) BUT i need this array sorted with div tags (like [<div style="left: 40px;">img child</div>, <div style="left: 85px;">img child</div>, <div style="left: 200px;">img child</div>])

}

Note

Pure Javascript please!

Thank you :)

I have got an array with DOM tags (div -> children img -> div closed). Those tags has attributes (left and top values). I added em as nodeLists so i can access elements offsetLeft and offsetTop to determine those values but i cant figurate out how to rearange those tags in the array ascending by left or top values.

HTML

<body>
    <div style="left:40px;top:10px;position:absolute">
        <img src="assets/images/text1.png" />
    </div>
    <div style="left:200px;top:88px;position:absolute">
        <img src="assets/images/text2.png" />
    </div>
    <div style="left:85px;top:166px;position:absolute">
        <img src="assets/images/text3.png" />
    </div>
</body>

JavaScript

var unsortedElements = [];
        var sortedElements = [];

        var elements = document.querySelectorAll("body > div");
        for (var i = 0; i < elements.length; i++) {
            var element = elements[i];
            if (element != null) {
                unsortedElements.push(element);

                var x = element.offsetLeft;
                var y = element.offsetTop;
                customSort(unsortedElements[i]);
            }
        }

function customSort(element){
var left = element.offsetLeft;

sortedElements.push(left);
console.log(sortedElements); -> will return the left values (40,85,200) BUT i need this array sorted with div tags (like [<div style="left: 40px;">img child</div>, <div style="left: 85px;">img child</div>, <div style="left: 200px;">img child</div>])

}

Note

Pure Javascript please!

Thank you :)

Share Improve this question asked Aug 27, 2015 at 18:13 OzZieOzZie 5239 silver badges21 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

With ES6, you get a new bunch of functions to have the job done more elegantly. For the purpose of that update, i'm just going to sort for the left property. I guess the replacement of a parator function is straightforward from now on.

HTML

<caption>Sorting by left offset</caption>
<div id="container" style="position:relative">
    <div class="candidate" style="left:200px;top:88px;position:absolute">
        <span>3 was 1 before sorting</span>
    </div>
    <div class="candidate" style="left:40px;top:10px;position:absolute">
        <span>1 was 2 before sorting</span>
    </div>    
    <div class="candidate" style="left:85px;top:166px;position:absolute">
        <span>2 was 3 before sorting</span>
    </div>
</div>

Pure JavaScript / EcmaScript 2015

Array.from(document.querySelectorAll("div.candidate")).sort(function(a, b){
    let aLeft = a.style.left.replace("px","");
    let bLeft = b.style.left.replace("px","");
    return aLeft-bLeft;
}).forEach(function(el){
    document.querySelectorAll("#container")[0].appendChild(el);
});

JSFiddle http://jsfiddle/a4e41pmr/

I used appendChild as a trick to move the nodes once sorted.

You can use high order function to create custom filter, in order to filter DOM element.

You can do the following :

var elements = document.querySelectorAll('div');

//Create our function generator
function sortBy(prop){
  return function(a, b){
    var filter_a = parseInt( a.style[prop] );
    var filter_b = parseInt( b.style[prop] );
    return filter_a < filter_b
    ? -1
    : (filter_a > filter_b ? 1 : 0);
  }
}

function sortDom(filter){
  //Transform our nodeList into array and apply sort function
  return [].map.call(elements, function(elm){
    return elm;
  }).sort(sortBy(filter))
}

//Sort by left style property
var byLeft = sortDom('left');
//Sort by top style property
var byTop = sortDom('top');

You could use the sort function of javascript arrays. Unfortunately that doesn't work on nodelists (which you get from calling querySelectorAll), so you have to do some converting:

var elements = document.querySelectorAll("body > div");
var divs=[];
for (var i=0;i<elements.length;i++) {
    divs.push(elements[i]);
}

This puts all your elements into an array. Now for the sorting:

divs.sort(function(a,b){
    var aLeft = a.style.left.replace("px","");
    var bLeft = b.style.left.replace("px","");
    return aLeft-bLeft;
});

This sorts by the left style attribute, provided that they're all in the form 123px.

In practice I would probably do it as @Paul Boutes suggested as it's more generic, but I thought that this way might be easier to understand.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742342816a4425966.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信