Javascript命令div的数据值最高

时间:2017-05-12 21:17:52

标签: javascript jquery ecmascript-6

我有这个代码。如果查看数据,则id是div的id。 接下来是悬停字段,每个字段都有一个数字值。

下面的代码会在每次div悬停时增加悬停。

var counter = [
    {id: 1, hovers: 1},
    {id: 2, hovers: 0},
    {id: 3, hovers: 8},
    {id: 4, hovers: 5},
    {id: 5, hovers: 3},
    {id: 6, hovers: 4},
    {id: 7, hovers: 2},
    {id: 8, hovers: 9},
    {id: 9, hovers: 2}
]

$('div').mouseover(function() {
  var obj = counter.find(e => e.id == $(this).attr('id'))
  if(obj) obj.hovers++
  console.log(obj)
})

以下是悬停和反击的html div。

<div id="1"><p>Box 1</p></div>
<div id="2"><p>Box 2</p></div>
<div id="3"><p>Box 3</p></div>
<div id="4"><p>Box 4</p></div>
<div id="5"><p>Box 5</p></div>
<div id="6"><p>Box 6</p></div>
<div id="7"><p>Box 7</p></div>
<div id="8"><p>Box 8</p></div>
<div id="9"><p>Box 9</p></div>

如果我们查看计数器数据。

我怎样才能移动div,以便那个徘徊最多的人与其他人一起顺序?

2 个答案:

答案 0 :(得分:4)

所以你要做的事实上非常昂贵。使用当前的数据结构,每次发生鼠标悬停时都必须对counter数组进行排序以保持正确的顺序。这意味着,如果N中有M鼠标悬停和counter项,则此操作的时间复杂度为O(N*MlogM)

每次悬停发生时,还会搜索数组。

假设您需要此排序列表的频率远远小于悬停量,您可以在需要时进行排序,而不是在每次悬停时进行排序。

此外,您可以将数据保存在Map<id, hoverCount>而不是数组中,以使悬停更新成为一个恒定时间操作。这也允许使用任何JS值作为id而不仅仅是数字。

const counter = new Map([
  [1, 1],
  [2, 0],
  [3, 8],
  [4, 5],
  [5, 3],
  [6, 4],
  [7, 2],
  [8, 9],
  [9, 2]
]);

$('div').mouseover(function() {
  const id = Number($(this).attr('id'));
  if (counter.has(id)) {
    counter.set(id, counter.get(id) + 1);
  }
});

如果你知道你的id将匹配每个元素的索引值-1,就像现在一样,那么就不需要映射也不需要迭代数组,只需使用id作为即时索引访问:

$('div').mouseover(function() {
  const idx = Number($(this).attr('id')) - 1;
  if (idx >= 0 && idx < counter.length) {
    counter[idx].hovers += 1;
  }
});

就排序而言,只需要比较每个元素的hovers属性:

// sorting the Map
getSorted() {
  return [...counter.entries()].sort((a, b) => b[1] - a[1]);
}

// sorting the array of <id, hovers> objects
getSorted() {
  return counter.sort((a, b) => b.hovers - a.hovers));
}

答案 1 :(得分:1)

这是一项有趣的任务,这是我的解决方案:

(注意我使用click事件来查看更多可控操作;将事件更改为您需要的任何内容)

单击元素时,计数器会递增,并且所有元素都会相应地重新排序。最高值位于顶部(如果需要,可在sort函数内更改)。

&#13;
&#13;
const els = document.querySelectorAll('div');

const counter = [
    {id: 1, hovers: 1},
    {id: 2, hovers: 0},
    {id: 3, hovers: 8},
    {id: 4, hovers: 5},
    {id: 5, hovers: 3},
    {id: 6, hovers: 4},
    {id: 7, hovers: 2},
    {id: 8, hovers: 9},
    {id: 9, hovers: 2}
];

const cMap = new Map(); // create a map for convenience
for (const el of counter) {
  cMap.set(el.id, el.hovers);
}

for (const el of els) {
  el.addEventListener('click', function() { // change event to a different one if needed
    const id = parseInt(el.id);
    cMap.set(id, cMap.get(id) + 1);
    el.innerHTML = '<p>Box ' + id + '; hovers: ' + cMap.get(id) + '</p>';

    const sortedIds = [...new Map([...cMap.entries()].sort((a, b) => b[1] - a[1])).keys()];
   
    const b = document.body;
    while (b.firstChild) { b.removeChild(b.firstChild); }; // clear body
    for (const i of sortedIds) {
      for (const el of els) { if (el.id == i) b.appendChild(el); } // append divs in order
    }
  })
}
&#13;
<div id="1"><p>Box 1</p></div>
<div id="2"><p>Box 2</p></div>
<div id="3"><p>Box 3</p></div>
<div id="4"><p>Box 4</p></div>
<div id="5"><p>Box 5</p></div>
<div id="6"><p>Box 6</p></div>
<div id="7"><p>Box 7</p></div>
<div id="8"><p>Box 8</p></div>
<div id="9"><p>Box 9</p></div>
&#13;
&#13;
&#13;