Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[JS] DOM sorteren op top & left

Pagina: 1
Acties:

  • NeFoRcE
  • Registratie: Mei 2004
  • Laatst online: 20-11 11:19

NeFoRcE

Hallo? Bent u daar?

Topicstarter
Heren,

Ik breek m'n hoofd hier.

Ik wil nadat de pagina gerenderd is, een aantal DOM elementen sorteren op hun absolute posities. Dus met behulp van jQuery.

Elementen zijn bijv als

<div style="position:absolute;left:0;top:250px;">blabla</div>
<div style="position:absolute;left:0;top:500px;">blabla</div>
<div style="position:absolute;left:100px;top:500px;">blabla</div>
<div style="position:absolute;left:0;top:30px;">blabla</div>
<div style="position:absolute;left:0;top:750px;">blabla</div>

Ze staan dus door elkaar. Wat ik graag wil is dat ze (zoals ze zichtbaar zijn voor het oog) gepositioneerd worden in de DOM. Van linksboven naar rechtsonderen...

Zelf had ik dit;

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
childelements.detach().sort(function(a, b) {

    if ($(a).css('top') <= $(b).css('top'))
    {
        return -1;
    }
    else if ($(a).css('top') > $(b).css('top'))
    {
        return 1;
    }
    else if ($(a).css('top') == $(b).css('top') && $(a).css('left') <= $(b).css('left'))
    {
        return -1;
    }
    else
    {
        return 1;
    }

});


Maar dat werkt (nog) niet goed...

Professioneel Heftruck Syndroom


  • geert1
  • Registratie: Maart 2006
  • Laatst online: 19-11 12:18
Sorry, ik kan je zo snel niet verder helpen met je script, maar ik ben wel heel benieuwd: Waarom heb je dit nodig? Wat is de situatie? Als je wat meer context geeft, kunnen mensen misschien met andere benaderingen komen.

  • NeFoRcE
  • Registratie: Mei 2004
  • Laatst online: 20-11 11:19

NeFoRcE

Hallo? Bent u daar?

Topicstarter
Een klant van ons vraagt hierom. Onze huidige software is hier nog niet geschikt voor, dus we willen even een tijdelijke oplossing implementeren. That's all eigenlijk :)

Professioneel Heftruck Syndroom


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 20-11 22:59

Janoz

Moderator Devschuur®

!litemod

Sowieso komt hij nooit bij regel 11 of verder. De eerste twee if's dekken immers al alle mogelijkheden af. Verander de <= in een < en hij zal vast al een stuk beter werken. Verder zou je 0 terug moeten geven wanneer beiden gelijk zijn om aan het contract van de comparefucntie te voldoen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • NeFoRcE
  • Registratie: Mei 2004
  • Laatst online: 20-11 11:19

NeFoRcE

Hallo? Bent u daar?

Topicstarter
Hm.. aangepast, maar heb het gevoel dat ik keihard overheen kijk.

Prioriteit van de elementen moet gewoon zijn, van boven naar beneden, zitten er meerdere elementen op dezelfde hoogte, dan moet de linker eerst komen, en daarna die er naast, etc. Vervolgens degene die eronder staat weer, en zo verder...

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var childelements = content.children(".selector");

childelements.detach().sort(function(a, b) {

    if ($(a).css('top') < $(b).css('top'))
    {
        return -1;
    }
    else if ($(a).css('top') > $(b).css('top'))
    {
        return 1;
    }
    else if ($(a).css('top') == $(b).css('top'))
    {
        return 0;
    }
    else if (&& $(a).css('left') < $(b).css('left'))
    {
        return -1;
    }
    else if (&& $(a).css('left') > $(b).css('left'))
    {
        return 1;
    }
    else if (&& $(a).css('left') == $(b).css('left'))
    {
        return 0;
    }

});

childelements.each(function() {
    content.append($(this));
});

Professioneel Heftruck Syndroom


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 20-11 22:59

Janoz

Moderator Devschuur®

!litemod

Deze code is bijna goed. Er zit echter nog 1 fout in. Loop maar eens door de functie heen om te kijken wat er gebeurt wanneer van twee objecten de top gelijk is. Komt hij dan wel of niet bij de checks van left ;).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • NeFoRcE
  • Registratie: Mei 2004
  • Laatst online: 20-11 11:19

NeFoRcE

Hallo? Bent u daar?

Topicstarter
Janoz schreef op donderdag 16 oktober 2014 @ 13:02:
Deze code is bijna goed. Er zit echter nog 1 fout in. Loop maar eens door de functie heen om te kijken wat er gebeurt wanneer van twee objecten de top gelijk is. Komt hij dan wel of niet bij de checks van left ;).
-_-' in vervolg wat vroeger naar bed dus. Haha, ik zal het zo even fixen en weer proberen. Thanks!

Professioneel Heftruck Syndroom


  • NeFoRcE
  • Registratie: Mei 2004
  • Laatst online: 20-11 11:19

NeFoRcE

Hallo? Bent u daar?

Topicstarter
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var childelements = content.children(".selector");

childelements.detach().sort(function(a, b) {

    if ($(a).css('top') == $(b).css('top'))
    {
        if ($(a).css('left') < $(b).css('left'))
        {
            return -1;
        }
        else if ($(a).css('left') > $(b).css('left'))
        {
            return 1;
        }
        return 0;
    }
    else
    {
        if ($(a).css('top') < $(b).css('top'))
        {
            return -1;
        }
        else if ($(a).css('top') > $(b).css('top'))
        {
            return 1;
        }
        return 0;
    }

    
});

childelements.each(function() {
    content.append($(this));
});


Aangepast, maar hij doet nog steeds niet wat ie moet doen. Zie ik iets over het hoofd? Dit zou 'm moeten zijn toch??

Professioneel Heftruck Syndroom


  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Je mist 2 punten:
  1. Je moet een normale array hebben om de sort functie te gebruiken. Die krijg je door de parameterloze jQuery.fn.get aan te roepen.
  2. Je kunt niet zomaar de top en left CSS properties vergelijken. Dat zijn strings en die worden lexicografisch vergeleken. Je zult de jQuery.fn.offset of jQuery.fn.position method moeten gebruiken. Die vereist alleen dat je elementen nog in de pagina zitten, dus je moet de detachment en re-attachment logica ook een beetje anders doen.
Zo even uit het blote hoofd zou dit het zo ongeveer moeten zijn:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var
  elements = content.children( ".selector" ),
  sorted   = elements.gets();

sorted.sort( function( first, second ) {
  first  = $( first ).offset();
  second = $( second ).offset();

  var diff = first.top - second.top;
    
  // Avoid floating point instability problems w/ browsers
  // that support subpixel element alignment by treating
  // all differences less than one pixel as equal.
  return ( 1 > Math.abs( diff )) ? first.left - second.left : diff;
});

elements.detach();
content.append( sorted );

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:33

.oisyn

Moderator Devschuur®

Demotivational Speaker

Algemene tip voor het implementeren van een compare functie op basis van meerdere values

JavaScript:
1
2
3
4
5
6
7
8
9
10
function compare(l, r)
{
    if (l.a != r.a)
         return l.a < r.a ? -1 : 1; // of als het numbers zijn: return l.a - r.a; 
    if (l.b != r.b)
         return l.b < r.b ? -1 : 1;
    if (l.c != r.c)
         return l.c < r.c ? -1 : 1;
    return 0;
}

Simpel en straightforward :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Juup
  • Registratie: Februari 2000
  • Niet online
Als je wilt dat het ook nog een beetje snel wordt moet je zorgen dat je de posities maar 1x opvraagt (dus buiten de sort functie).

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


  • NeFoRcE
  • Registratie: Mei 2004
  • Laatst online: 20-11 11:19

NeFoRcE

Hallo? Bent u daar?

Topicstarter
R4gnax schreef op donderdag 16 oktober 2014 @ 23:30:
Je mist 2 punten:
  1. Je moet een normale array hebben om de sort functie te gebruiken. Die krijg je door de parameterloze jQuery.fn.get aan te roepen.
  2. Je kunt niet zomaar de top en left CSS properties vergelijken. Dat zijn strings en die worden lexicografisch vergeleken. Je zult de jQuery.fn.offset of jQuery.fn.position method moeten gebruiken. Die vereist alleen dat je elementen nog in de pagina zitten, dus je moet de detachment en re-attachment logica ook een beetje anders doen.
Zo even uit het blote hoofd zou dit het zo ongeveer moeten zijn:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var
  elements = content.children( ".selector" ),
  sorted   = elements.get();

sorted.sort( function( first, second ) {
  first  = $( first ).offset();
  second = $( second ).offset();

  var diff = first.top - second.top;
    
  // Avoid floating point instability problems w/ browsers
  // that support subpixel element alignment by treating
  // all differences less than one pixel as equal.
  return ( 1 > Math.abs( diff )) ? first.left - second.left : diff;
});

elements.detach();
content.append( sorted );
Thanks, met wat enkele aanpassingen was dit de juiste oplossing! Thankq!

Professioneel Heftruck Syndroom

Pagina: 1