непредвиденное поведение childNode

Если производительность важна, переходите к уровню numpy:

import numpy as np

df = pd.DataFrame( {'a':np.random.randint(0,60,600), 'b':[1,2,5,5,4,6]*100})

def f(df):
         keys,values=df.sort_values('a').values.T
         ukeys,index=np.unique(keys,True)
         arrays=np.split(values,index[1:])
         df2=pd.DataFrame({'a':ukeys,'b':[list(a) for a in arrays]})
         return df2

Тесты:

In [301]: %timeit f(df)
1000 loops, best of 3: 1.64 ms per loop

In [302]: %timeit df.groupby('a')['b'].apply(list)
100 loops, best of 3: 5.26 ms per loop
0
задан zolty13 13 July 2018 в 08:36
поделиться

2 ответа

Вы можете использовать свойство children для доступа к дочерним элементам данного узла:

Свойство ParentNode g2] children - свойство только для чтения, которое возвращает живой HTMLCollection , который содержит все дочерние элементы узла, на который он был вызван.

MDN web docs

function myFunction() {
  var divv = document.getElementById("divv");
  var myCollection = divv.children;
  var len = myCollection.length;
  var i;
  for (i = 0; i < len; i++) {
    myCollection[i].style.color = "red";
  }
}
<div id="divv">
  <h2>JavaScript HTML DOM</h2>
  <p>Hello World!</p>
  <p>Hello Norway!</p>
  <p>Click the button to change the color of all p elements.</p>
  <button onclick="myFunction()">Try it</button>
</div>


Другой способ сделать ES6 будет распространять дочерние узлы в массив и прокручивать их с помощью .forEach :

const myFunction = () => {
  
  [...document.querySelector('#divv').children].forEach(child => {
  
    child.style.color = 'red';
  
  });
  
}
<div id="divv">
  <div class="child">
    I am a child
  </div>
  <div>
    <div class="grandchild">
      I am a grand child
    </div>
  </div>
  
  <button onclick="myFunction()">Try it</button>
</div>

В качестве альтернативы вы можете использовать .forEach непосредственно из класса NodeList , но предыдущий метод дает вам больше свободы для работы с методом Array, таким как .reduce, .map и т. д. ...

const myFunction = () => {
  
  document.querySelectorAll('#divv > *').forEach(child => {
  
    child.style.color = 'red';
  
  });
  
}
<div id="divv">
  <div class="child">
    I am a child
  </div>
  <div>
    <div class="grandchild">
      I am a grand child
    </div>
  </div>
  
  <button onclick="myFunction()">Try it</button>
</div>

3
ответ дан Ivan 17 August 2018 в 13:23
поделиться
  • 1
    ChildNode всегда возвращает и внуков? – zolty13 13 July 2018 в 08:13
  • 2
    @ zolty13, No The Node.childNodes read-only property returns a live NodeList of child nodes of the given element where the first child node is assigned index 0., поэтому он возвращает только детей, а не внуков. Но помните, что добавив стиль родителям, вы добавляете стиль детям и внукам! – Ivan 13 July 2018 в 08:18
  • 3
    Итак, почему я получаю 11 элементов из childNode. @CertainPerfomance использует: if (myCollection [i] .nodeType === 1) myCollection [i] .style.color = "red" ;; – zolty13 13 July 2018 в 08:21
  • 4
    Да, вы получите 11, посмотрите на myCollection, есть только дочерние узлы, а не внуки – Ivan 13 July 2018 в 08:24
  • 5
    @ zolty13, чтобы отличить text от element: прочитайте this – Ivan 13 July 2018 в 08:24

У текстовых узлов нет атрибутов style. Если вы хотите использовать childNodes, убедитесь, что сначала nodeType - 1 (узел Element):

function myFunction() {
  var divv = document.getElementById("divv");
  var myCollection = divv.childNodes;
  var len = myCollection.length;
  var i;
  for (i = 0; i < len; i++) {
    if (myCollection[i].nodeType === 1) myCollection[i].style.color = "red";
  }
}
<div id="divv">
  <h2>JavaScript HTML DOM</h2>
  <p>Hello World!</p>
  <p>Hello Norway!</p>
  <p>Click the button to change the color of all p elements.</p>
  <button onclick="myFunction()">Try it</button>
</div>

Но я предпочел бы использовать querySelectorAll и forEach здесь:

function myFunction() {
  document.querySelectorAll('#divv > *')
    .forEach(child => child.style.color = "red");
}
<div id="divv">
  <h2>JavaScript HTML DOM</h2>
  <p>Hello World!</p>
  <p>Hello Norway!</p>
  <p>Click the button to change the color of all p elements.</p>
  <button onclick="myFunction()">Try it</button>
</div>

(или, вы могли бы просто установите #divv 's style.color на красный)

4
ответ дан CertainPerformance 17 August 2018 в 13:23
поделиться
  • 1
    Спасибо. Это не просто цвет :). Itg - простой пример моей проблемы. Я не понимаю, почему я получаю текстовые узлы, когда хочу только дочерний узел. Текстовым узлом является внук. var myCollection = divv.childNodes; – zolty13 13 July 2018 в 08:11
  • 2
    Поскольку childNodes будет содержать текстовые узлы. Новые строки также являются текстовыми узлами. Если вам не нужны текстовые узлы, вы можете иметь HTML, например <h2>JavaScript HTML DOM</h2><p>Hello World!</p><p>Hello Norway!</p> без новых строк и пробелов между элементами <> s. – CertainPerformance 13 July 2018 в 08:23
Другие вопросы по тегам:

Похожие вопросы: