我发现自己使用了JavaScript,并且我遇到了childNodes
和children
属性。我想知道它们之间的区别是什么。另一个是优先选择的吗?
答案 0 :(得分:266)
.children
是Element的属性。只有Elements有子节点,这些子节点都是Element类型。
但是.childNodes
是Node的属性。 .childNodes
可以包含任何节点。
所以一个具体的例子是
var el = document.createElement("div");
el.textContent = "foo"
el.childNodes.length === 1; // TextNode is a node child
el.children.length === 0; // no Element children
当然.children
是DOM4,因此浏览器支持不稳定,但如果您使用DOM-shim,您的跨浏览器问题就会消失!
大多数情况下,您希望使用.children
,因为通常您不希望在DOM操作中循环遍历TextNodes或Comments。
如果您确实想要操作TextNodes,则可能需要.textContent
。
答案 1 :(得分:17)
Element.children
仅返回元素子元素,而Node.childNodes
返回所有节点子元素。请注意,元素是节点,因此两者都可以在元素上使用。
我相信childNodes
更可靠。例如,MDC(上面链接)指出IE只在IE 9中获得children
。childNodes
提供了较少的浏览器实现者错误空间。
答案 2 :(得分:4)
到目前为止,答案很好,我只想补充一点,您可以使用nodeType
检查节点的类型:
yourElement.nodeType
这将为您提供一个整数:(取自here)
| Value | Constant | Description | |
|-------|----------------------------------|---------------------------------------------------------------|--|
| 1 | Node.ELEMENT_NODE | An Element node such as <p> or <div>. | |
| 2 | Node.ATTRIBUTE_NODE | An Attribute of an Element. The element attributes | |
| | | are no longer implementing the Node interface in | |
| | | DOM4 specification. | |
| 3 | Node.TEXT_NODE | The actual Text of Element or Attr. | |
| 4 | Node.CDATA_SECTION_NODE | A CDATASection. | |
| 5 | Node.ENTITY_REFERENCE_NODE | An XML Entity Reference node. Removed in DOM4 specification. | |
| 6 | Node.ENTITY_NODE | An XML <!ENTITY ...> node. Removed in DOM4 specification. | |
| 7 | Node.PROCESSING_INSTRUCTION_NODE | A ProcessingInstruction of an XML document | |
| | | such as <?xml-stylesheet ... ?> declaration. | |
| 8 | Node.COMMENT_NODE | A Comment node. | |
| 9 | Node.DOCUMENT_NODE | A Document node. | |
| 10 | Node.DOCUMENT_TYPE_NODE | A DocumentType node e.g. <!DOCTYPE html> for HTML5 documents. | |
| 11 | Node.DOCUMENT_FRAGMENT_NODE | A DocumentFragment node. | |
| 12 | Node.NOTATION_NODE | An XML <!NOTATION ...> node. Removed in DOM4 specification. | |
请注意,根据Mozilla:
以下常量已被弃用,不应使用 还有:Node.ATTRIBUTE_NODE,Node.ENTITY_REFERENCE_NODE,Node.ENTITY_NODE,Node.NOTATION_NODE
答案 3 :(得分:0)
我将和ParentNode.children 一起去:
它提供了import pygame
pygame.font.init()
#--------------------------------------------------------------------------------------------------
#Begin constructing GUI
class Single_Cell:
rows = 9
columns = 9
def __init__(self, value, row, column, width, height):
self.value = value
self.row = row
self.column = column
self.width = width
self.height = height
self.temporary_value = 0
self.selectedcell = False
def insert_temporary_value(self, value):
self.temporary_value = value
def insert_value(self, value):
self.value = value
def draw_single_cell(self, screen):
cell_measuremt = self.width / 9
cell_x = self.column * cell_measuremt
cell_y = self.row * cell_measuremt
gray = (128, 128, 128)
some_blue = (0, 170, 204)
white = (255, 255, 255)
fnt = pygame.font.SysFont("comicsans", 32)
if self.selectedcell == True:
pygame.draw.rect(screen, some_blue, (cell_x, cell_y, cell_measuremt, cell_measuremt), 3)
if self.temporary_value != 0 and self.value == 0:
text = fnt.render(str(self.temporary_value), 1, gray)
screen.blit(text, (cell_x + 5, cell_y + 5))
elif self.value != 0:
text = fnt.render(str(self.value), 1, white)
screen.blit(text, (cell_x + (cell_measuremt/2 - text.get_width()/2), cell_y + (cell_measuremt/2 - text.get_height()/2)))
def draw_outcome(self, screen, outcome):
aqua = (77, 255, 255)
fuchsia = (255, 0, 255)
black = (0, 0, 0)
white = (255, 255, 255)
fnt = pygame.font.SysFont("comicsans", 32)
cell_measuremt = self.width / 9
cell_x = self.column * cell_measuremt
cell_y = self.row * cell_measuremt
pygame.draw.rect(screen, black, (cell_x, cell_y, cell_measuremt, cell_measuremt), 0)
text = fnt.render(str(self.value), 1, white)
screen.blit(text, (cell_x + (cell_measuremt/2 - text.get_width()/2), cell_y + (cell_measuremt/2 - text.get_height()/2)))
if outcome == True:
pygame.draw.rect(screen, aqua, (cell_x, cell_y, cell_measuremt, cell_measuremt), 3)
else:
pygame.draw.rect(screen, fuchsia, (cell_x, cell_y, cell_measuremt, cell_measuremt), 3)
class Global_Grid:
sudoku_board = [
[5, 0, 0, 1, 8, 0, 0, 7, 0],
[0, 0, 7, 2, 9, 0, 5, 4, 3],
[0, 0, 0, 0, 0, 4, 0, 0, 1],
[0, 5, 0, 6, 0, 0, 9, 8, 0],
[7, 0, 0, 9, 0, 0, 3, 0, 4],
[0, 9, 6, 3, 0, 8, 2, 1, 5],
[0, 0, 5, 8, 0, 0, 0, 0, 6],
[1, 4, 0, 0, 6, 0, 0, 0, 2],
[0, 3, 0, 0, 2, 7, 1, 0, 0]]
def __init__(self, rows, columns, width, height, screen):
self.rows = rows
self.columns = columns
self.width = width
self.height = height
self.screen = screen
self.singlecells = [[Single_Cell(self.sudoku_board[row][column], row, column, width, height) for row in range(rows)] for column in range(columns)]
self.updatedgrid = None
self.update_board()
self.selected = None
def solve_sudoku(self):
emptycell_location = find_empty_cells(self.updatedgrid)
if not emptycell_location:
return True
else:
(row, column) = emptycell_location
for n in range(1, 10):
if harmony(self.updatedgrid, n, emptycell_location) == True:
self.updatedgrid[row][column] = n
if self.solve_sudoku() == True:
return True
self.updatedgrid[row][column] = 0
return False
def update_board(self):
self.updatedgrid = [[self.singlecells[row][column].value for row in range(self.columns)] for column in range(self.rows)]
def commit_value(self, value):
(row, column) = self.selected
if self.singlecells[row][column].value == 0:
self.singlecells[row][column].insert_value(value)
self.update_board()
if harmony(self.updatedgrid, value, (row, column)) and solve_sudoku(self.updatedgrid) == True:
return True
else:
self.singlecells[row][column].insert_value(0)
self.singlecells[row][column].insert_temporary_value(0)
self.update_board()
return False
def clear_cell(self):
(row, column) = self.selected
if self.singlecells[row][column].value == 0:
self.singlecells[row][column].insert_temporary_value(0)
def sketch_cell(self, value):
(row, column) = self.selected
self.singlecells[row][column].insert_temporary_value(value)
def draw_grid(self):
white = (255, 255, 255)
gray = (128, 128, 128)
cell_width = (self.width / 9)
for n in range(self.column + 1):
if n % 3 == 0:
line_width = 3
else:
line_width = 1
if line_width == 3:
pygame.draw.line(self.screen, white, ((cell_width * n), 0), ((cell_width * n), self.height), line_width)
pygame.draw.line(self.screen, white, (0, (cell_width * n)), (self.width, (cell_width * n)), line_width)
elif line_width == 1:
pygame.draw.line(self.screen, gray, ((cell_width * n), 0), ((cell_width * n), self.height), line_width)
pygame.draw.line(self.screen, gray, (0, (cell_width * n)), (self.width, (cell_width * n)), line_width)
for row in range(self.rows):
for column in rang(self.columns):
self.singlecells[row][column].draw_single_cell(self.screen)
def reset_and_select(self, row, column):
for x in range(self.rows):
for y in range(self.columns):
self.singlecells[x][y].selectedcell = False
self.singlecells[row][column].selectedcell = True
self.selected = (row, column)
def user_click(self, position):
if position[0] < self.width and position[1] < self.height:
cell_width = (self.width / 9)
row = int (position[0] // cell_width)
column = int (position[1] // cell_width)
return (column, row)
else:
return None
def check_complete(self):
for row in range(self.rows):
for column in range(self.columns):
if self.singlecells[row][column].value == 0:
return False
return True
def solve_sudoku_GUI(self):
emptycell_location = find_empty_cells(self.updatedgrid)
if not emptycell_location:
return True
else:
(row, column) = emptycell_location
for n in range(1, 10):
if harmony(self.updatedgrid, n, emptycell_location) == True:
self.updatedgrid[row][column] = n
self.singlecells[row][column].insert_value(n)
self.singlecells[row][column].draw_outcome(self.screen, True)
self.update_board()
pygame.display.update()
pygame.time.delay(100)
if self.solve_sudoku_GUI() == True:
return True
self.updatedgrid[row][column] = 0
self.singlecells[row][column].insert_value(0)
self.update_board()
self.singlecells[row][column].draw_outcome(self.screen, False)
pygame.display.update()
pygame.time.delay(100)
return False
def main_window():
screenwidth = 540
screenheight = 600
screen = pygame.display.set_mode((screenwidth, screenheight))
board = Global_Grid(9, 9, 500, 500, screen)
key = None
mainloop = True
#construct pygame events handler:
while mainloop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
key = 1
if event.key == pygame.K_2:
key = 2
if event.key == pygame.K_3:
key = 3
if event.key == pygame.K_4:
key = 4
if event.key == pygame.K_5:
key = 5
if event.key == pygame.K_6:
key = 6
if event.key == pygame.K_7:
key = 7
if event.key == pygame.K_8:
key = 8
if event.key == pygame.K_9:
key = 9
if event.key == pygame.K_DELETE:
board.clear_cell()
key = None
if event.key == pygame.K_RETURN:
(row, column) = board.selected
if board.singlecells[row][column].temporary_value != 0:
if board.commit_value(board.singlecells[row][column].temporary_value) == True:
print ("Passed.")
else:
print ("Failed.")
key = None
if board.check_complete() == True:
print ("Sudoku is completed. Thanks for testing the program.")
if event.key == pygame.K_SPACE:
board.solve_sudoku_GUI()
print ("Try harder next time.")
if event.type == pygame.MOUSEBUTTONDOWN:
position = pygame.mouse.get_pos()
cell_position = board.user_click(position)
if cell_position:
board.reset_and_select(cell_position[0], cell_position[1])
key = None
if board.selected and key != None:
board.sketch_cell(key)
pygame.display.update()
main_window()
pygame.quit()
方法,使我可以直接获取子元素之一,而无需遍历所有子元素或避免使用namedItem
等。
例如
getElementById
我将和Node.childNodes 一起去:
当我使用ParentNode.children.namedItem('ChildElement-ID'); // JS
ref.current.children.namedItem('ChildElement-ID'); // React
this.$refs.ref.children.namedItem('ChildElement-ID'); // Vue
时,它提供了forEach
方法
例如
window.IntersectionObserver
在Chrome 83上
Node.childNodes提供了
nodeList.forEach((node) => { observer.observe(node) }) // IE11 does not support forEach on nodeList, but easy to be polyfilled.
,entries
,forEach
,item
,keys
和length
ParentNode.children提供了
values
,item
和length