译者: David Gilbertson是一位著名的作者,他撰写了有关Web和加密货币技术的文章。 他吸引了大批读者,讲述了各种技巧和有趣的领域。
小介绍让我们讨论一下HTML和DOM之间的区别。
例如,从HTML中获取
table元素。 您可以在扩展名为.html的文件中使用它。 在其中,我们指示一组确定页面外观和“行为”的属性。
就是这样,与JavaScript无关。
DOM使您可以将JavaScript代码与文档中的HTML元素组合在一起,以便您可以将它们作为对象进行交互。
这是一个目标文档模型。
HTML中的任何类型的元素都有其自己的“ DOM”接口,该接口定义了属性和方法。 例如,
table具有一个名为
HTMLTableElement的接口。
您可以通过编写以下内容来获得指向特定元素的链接:

您可以访问特定元素类型的所有属性和方法。 例如,您可以使用searchBox.value访问值属性,或者使用searchBox.focus()将光标设置到特定位置。
现在让我们讨论一个更重要的事情:大多数元素没有有趣的方法,因此如果您不故意研究此问题,很容易错过重要的事情。
但是,幸运的是,对细节的关注和对规范的研究是我的专长。 因此,我做了所有必要的事情,并在本文中介绍了结果。
如果您想尝试自己处理DOM,则应使用浏览器工具来学习一些元素。 为此,请在元素树中选择其中之一,然后在控制台中键入$ 0。 这将为您提供到所选项目的链接。 要将其转换为对象,请键入dir($ 0)。
您可以在控制台中执行许多操作。

Skillbox建议: Web开发人员在线课程
我们提醒您:对于所有Habr读者-使用Habr促销代码注册任何Skillbox课程时均可享受10,000卢布的折扣。
1号 表格方法
有许多方便的方法可以让您在宜家组装桌子,例如家具。
const tableEl = document.querySelector('table'); const headerRow = tableEl.createTHead().insertRow(); headerRow.insertCell().textContent = 'Make'; headerRow.insertCell().textContent = 'Model'; headerRow.insertCell().textContent = 'Color'; const newRow = tableEl.insertRow(); newRow.insertCell().textContent = 'Yes'; newRow.insertCell().textContent = 'No'; newRow.insertCell().textContent = 'Thank you';
在这里,您不仅看到document.createElement()。 例如,如果您直接在树中组织对此元素的调用,则.insertRow()方法将内联
tbody 。 那不是很棒吗?
2号 scrollIntoView()
您知道如果URL中包含#something,那么在页面加载时,浏览器将滚动到具有此ID的元素吗?
这通常有很大帮助,但如果在页面加载后呈现此元素,则不会起作用。 为了利用上述机会,只需规定document.querySelector(document.location.hash).scrollIntoView();
3号 隐藏的
是的,这有点像一种方法,但是由于有一个setter(用于设置属性的方法),因此可以将其视为一种方法。
就是这样,您是否曾经使用myElement.style.display ='none'来隐藏元素? 如果是这样,则不要这样做。
最好使用myElement.hidden = true。
4号 切换()
我们可以使用此方法通过myElement.classList.toggle('some-class')添加或删除元素类。
而且,如果您曾经使用if添加过一个类,请考虑:也许您应该尝试其他方法?
例如,您可以简单地将第二个参数用于toggle方法。 您需要将其传递给切换方法。 如果发生这种情况,您的课程将被添加到元素中:
el.classList.toggle('some-orange-class', theme === 'orange');
是的,我知道您现在在想什么:这不是“ toogle”这个词本身的意思。 那些在Internet Explorer后面? 对此表示同意,并完全不使用第二个参数表示抗议。
但是,让我们把它找回来。 自由选择!
5号 querySelector()
好吧,您绝对应该知道这一点,但是我怀疑大约有17%的读者不知道如何将此方法与元素结合使用。
示例:myElement.querySelector('。My-class')将显示具有my-class类和myElement的“子代”的元素的对应关系。
6号 最近的
此方法可用于查看元素树的所有元素。 这与querySelector()有点相反。 因此,我们可以通过以下方式使用当前部分的标题:
myElement.closest('article').querySelector('h1');
我们从
文章开始,到第一个
h1结束。
7号 getBoundingClientRect()
该方法返回一个对象,其中包含有关我们指定的元素的详细信息。
{ x: 604.875, y: 1312, width: 701.625, height: 31, top: 1312, right: 1306.5, bottom: 1343, left: 604.875 }
但请注意:此示例将导致重画。 根据设备和页面的复杂程度,这可能要花费几毫秒。 因此,如果您反复调用它(例如在动画中),请记住这一点。
并非所有浏览器都返回所有这些值。
8号 符合()
我想检查某个元素是否属于某个类。
最大难度:
if (myElement.className.indexOf('some-class') > -1) { // do something } , : if (myElement.className.includes('some-class')) { // do something }
您需要什么:
if (myElement.matches('.some-class')) {
9号 insertAdjacentElement()
我今天发现了! 这类似于appendChild(),但是在添加child的过程中提供了更多控制。
parentEl.insertAdjacentElement('beforeend',newEl)的功能与parentEl.appendChild(newEl)大致相同,但是您可以指定beforebegin,beginbe或afterend将其放置在这些名称指示的位置。
控制多少!
10号 包含()
您是否曾经想知道另一个元素内部是否有元素? 我一直想知道这一点。
例如,如果我处理鼠标单击并想了解它是发生在内部还是外部(以便可以将其关闭),请执行以下操作:
const handleClick = e => { if (!modalEl.contains(e.target)) modalEl.hidden = true; };
这里模态El是对模态窗口的引用,而e.target是要单击的元素。
这很有趣,但是当我第一次尝试使用该方法时,我经常会在逻辑上犯错误。 然后,当我尝试纠正错误时,我又错了。 而且此方法有助于立即对其进行处理。
11号 getAttribute()
元素最无用的方法之一,但在这种特殊情况下不是。
您还记得通常属性是指属性吗?
有时情况并非如此,例如,当href是元素的属性时,例如href =“ / animals / cat”> Cat </ a。
如您所料,el.href不会给我们/动物/猫。 这是因为该元素实现了HTMLHyperlinkElementUtils接口,该接口是一堆帮助程序属性,例如协议和哈希,指向链接对象。
这是有用的href属性之一,它将提供完整的L,而不是属性中的相对URL。
因此,如果在href属性中需要文字字符串,则应使用el.getAttribute('href')。
12号 对话
相对较新的
对话元素有两种好的方法和一种理想的方法。 show()和close()确实完成了对它们的期望。 我想那很好。
但是showModal()将在页面上放置的所有其他元素上方显示一个
对话框 。 不需要z-index,也不需要手动添加暗淡的背景,也不需要跟踪Escape按钮的按下。 浏览器知道模态窗口如何工作,并将为您做所有事情。 太好了。
13号 forEach()
有时,当需要引用元素列表时,可以使用forEach()。
但是,如果您需要记录所有页面链接的所有URL,该怎么办? 您可以这样做并查看错误。
document.getElementsByTagName('a').forEach(el => { console.log(el.href); });
或这样做:
document.querySelectorAll('a').forEach(el => { console.log(el.href); });
关键是,getElementsByTagName和其他get ...方法返回HTMLCollection,但是querySelectorAll返回NodeList。
NodeList接口为我们提供了forEach()方法(以及键(),值()和条目())。
来自ECMA的好朋友给我们提供了Array.from(),它将看起来像数组的所有内容转换为数组本身。
Array.from(document.getElementsByTagName('a')).forEach(el => { console.log(el.href); });
加分 创建数组时,可以使用map(),filter(),reduce()或任何其他方法。 例如,返回一个外部链接数组:
Array.from(document.querySelectorAll('a')) .map(el => el.origin) .filter(origin => origin !== document.origin) .filter(Boolean);
我真的很喜欢开.filter(布尔值),因为如果没有它,将来我将不得不挠头,试图记住它是什么以及它是如何工作的。
14号 表格
您可能已经知道,
Form有一个commit()方法。 如果您对表单元素使用验证,则您不太可能知道表单具有reset()方法并可以报告Validity()值。
您还可以使用表单元素的点表示法属性通过其name属性引用元素。 例如,myFormEl.elements.email将返回
输入名称=“ email” /属于
表单的元素(“ belongs”并不一定意味着它是其“后代”)。
现在我撒谎了。 事实是元素不会返回元素列表。 它返回控件列表(当然,这不是数组)。
示例:如果您有三个单选按钮,每个单选按钮的名称与动物相同,则formEl.elements.animal将为您提供此单选按钮集的链接(1个控件,3个元素)。
并且formEl.elements.animal.value将返回所选单选按钮的值。
如果您考虑一下,这是一个奇怪的语法。 分解吧:formEl是一个元素,元素是HTMLFormControlsCollection,不是一个数组,其中每个元素不一定是HTML元素。 Animal组合了几个开关,只是因为它们具有相同的名称属性(为此具有一个RadioNodeList接口),并且值通过集合中任何开关的value属性进行查找。
15号 选择()
.select()方法将选择您调用的任何输入中的所有文本。
感谢您的阅读,希望所有这些对您有所帮助。 始终检查浏览器的功能,以免日后痛苦不已。
Skillbox的实用程序 ,它将帮助新手程序员成为抢手的专家: