使用左侧和顶部值对DOM标记和属性排序数组

时间:2015-08-27 18:13:07

标签: javascript

我有一个带有DOM标签的数组(div - > children img - > div closed)。这些标签具有属性(左侧和顶部值)。我添加em作为nodeLists,所以我可以访问元素offsetLeft和offsetTop来确定这些值,但我不知道如何重新排列数组中的左侧或顶部值的标记。

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>])

}

注意

纯Javascript请!

谢谢:)

3 个答案:

答案 0 :(得分:2)

您可以使用高阶函数创建自定义过滤器,以过滤DOM元素。

您可以执行以下操作:

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');

答案 1 :(得分:0)

您可以使用javascript数组的sort函数。不幸的是,这不适用于节点列表(通过调用querySelectorAll获得),因此您必须进行一些转换:

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

这会将所有元素放入数组中。现在进行排序:

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

left样式属性进行排序,前提是它们全部采用123px形式。

在实践中,我可能会这样做,因为@Paul Boutes建议它更通用,但我认为这种方式可能更容易理解。

答案 2 :(得分:0)

使用ES6,您将获得一系列新功能,以便更优雅地完成工作。 为了更新的目的,我只是要对左边的属性进行排序。 我想从现在开始直接更换比较器功能。

<强> 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.net/a4e41pmr/

我使用appendChild作为移动节点一次排序的技巧。