当前位置: 首页 > Web前端 > HTML

深入15个HTML元素方法,你见过吗?

时间:2023-04-02 18:31:38 HTML

尽管现代Web开发更多地依赖于各种MVC框架,开发者仍然需要掌握HTML和DOM的基础知识。但是,即使是有多年经验的前端开发者,也会遇到一些不清楚的情况。本文将首先为初学者介绍HTML和DOM的基础知识,然后介绍相对冷门的HTML元素的15种方法。初学者首先让我们讨论一下HTML和DOM之间的区别。显然,普通的

元素只是一段HTML代码,可以应用于任何扩展名为.html的文件。一个元素带有一组属性来控制它的显示和行为。这就是元素的全部内容,它与JavaScript无关。DOM的作用是将您的JavaScript代码与文档中的HTML元素相关联,从而允许您将这些元素作为对象进行交互。这就是所谓的文档对象模型。HTML中的每个元素都对应一个DOM“接口”,它定义了几个属性(properties,通常映射到HTML元素上的属性)和方法。例如,
元素对应于HTMLTableElement接口。您可以获得对元素的引用,如下所示:constsearchBox=document.getElementById('search-box');现在,您可以访问元素上定义的所有属性和方法。比如可以通过searchBox.value访问它的value属性,也可以调用searchBox.focus()方法将光标移动到输入框。感谢您参加这个58秒的DOM入门培训课程,哈哈。现在的问题是大多数元素不提供任何有趣的方法。因此,除非您专门去官方文档搜索您永远不会使用的东西,否则很容易遗漏一些小细节。幸运的是,浏览规范和组织技巧是我最喜欢的两种避免陷入困境的方法。那么,让我们开始吧……如果你也想尝试这些技巧,并且你正好有一些浏览器DevTools可用,你可以先在元素树结构中选择一个元素,然后在控制台中输入$0,它会返回你对所选元素的引用。如果您需要为该元素返回一个对象,请键入dir($0)。1表格方法原始的表格元素(今天仍然是排名第一的网站布局方法)带有许多简洁的方法,使创建表格就像构建宜家桌子一样简单。这里有一些有用的方法。consttableEl=document.querySelector('table');constheadRow=tableEl.createHead().insertRow();headerRow.insertCell().textContent='Make';headerRow.insertCell().textContent='Model';headerRow.insertCell().textContent='Color';constnewRow=tableEl.insertRow();newRow.insertCell().textContent='Yes';newRow.insertCell().textContent='No';newRow.insertCell()。textContent='谢谢';整个代码中不需要使用document.createElement()方法。如果直接在表格元素上调用.insertRow()方法,它甚至会自动为你插入一个元素,是不是很棒?2你知道scrollIntoView()吗?当页面的URL包含#something元素时,一旦页面加载,浏览器将自动滚动到具有此ID的元素。这确实是一个很好的特性,但是如果你在页面加载之后渲染元素,这个特性将不起作用。但是,您也可以通过执行以下操作手动重新激活此功能:document.querySelector(document.location.hash).scrollIntoView();3hidden好吧,hidden可能不是一种方法,但如果你抗议,那么我会争辩:hidden后面可能有一个setter,这是一个真正的方法,对吧?不管怎样,你有没有使用过myElement.style.display='none'来隐藏一个元素?如果是,请停止这样做!只需调用myElement.hidden=true即可实现元素的隐藏功能。4toggle()嗯,toggle不是元素的方法,它实际上是元素属性上的方法。严格来说,这是一种向元素添加或删除特定类的方法,特别是myElement.classList.toggle('some-class')。如果您曾经使用if语句向元素添加类,那么您现在应该切换到那个。正确的做法是将第二个参数传入toggle方法。如果参数返回true,指定的类将被添加到元素中。el.classList.toggle('some-orange-class',theme==='orange');我知道你在想什么:这种写法违背了'toggle'(开关)这个词的本意,历代IE开发者都这么认为,主张完全取消第二个参数的使用.所以,我收回我的话。这种写法没必要强求,大家随意!5querySelector()嗯,你当然知道这个方法,但据我猜测,只有17%的开发人员知道这个方法可以用在任何元素上。例如,myElement.querySelector('.my-class')返回属于类my-class的myElement的所有后代元素。6closest这个方法可以用在任何元素上,它可以向上搜索元素的树结构,可以理解为querySelector()的相反方法。所以我可以获得当前内容的相应标题:myElement.closest('article').querySelector('h1');该方法首先向上移动到最近的
元素,然后向下移动到最近的

元素。7getBoundingClientRect()在DOM元素上调用时,将返回一个包含其空间结构详细信息的简单对象。{x:604.875,y:1312,width:701.625,height:31,top:1312,right:1306.5,bottom:1343,left:604.875}不过调用这个方法有两点需要注意:调用这个方法会原因元素的重绘可能需要几毫秒,具体取决于设备和页面的复杂程度。因此,如果需要重复调??用该方法,比如在使用动画的场景中,需要特别注意。并非所有浏览器都返回这些值,他们负责吗?8matches()假设我需要检查一个元素是否包含一个特定的类。这是最复杂的方法:if(myElement.className.indexOf('some-class')>-1){//dosomething}比上面的好一点,但与本文无关:if(myElement.className.includes('some-class')){//做某事}最好的方法:if(myElement.matches('.some-class')){//做某事}9insertAdjacentElement()我今天才学会这个!它的工作方式类似于appendChild(),但可以更好地控制插入子元素的位置。parentEl.insertAdjacentElement('beforeend',newEl)与parentEl.appendChild(newEl)效果相同,但另外,还可以指定beforebegin、afterbegin或afterend的参数值,元素会被插入对应的位置如名称所示。多么强大的控制能力!真是个好主意。10contains()你有没有遇到过需要知道一个元素是否包含在另一个元素中的情况?至少这是我自己经常面对的问题。例如,假设当我处理鼠标点击事件时,我需要知道它是发生在模式窗口中还是外部(以便我可以关闭窗口),我可能会这样做:consthandleClick=e=>{if(!modalEl.contains(e.target))modalEl.hidden=true;};代码中的modalEl是模态窗口的引用,e.target代表点击事件的各种元素。有意思的是,每当我遇到这种情况,第一次写代码的时候,判断逻辑有100%的概率会颠倒过来。即使我提高了警惕,在保存代码前试图反推逻辑,我还是写错了。11getAttribute()这无疑是所有元素方法中最无用的,除了一个场景。你还记得我在本文开头提到的,一个对象的属性通常也映射到它的属性(我在上面用粗体强调了这一点,而不是斜体)?但是在一种情况下,这个假设不成立,这是一个元素的href属性,例如Cat。调用el.href并没有返回/animals/cat,这可能不是你猜的那样。原因是该元素实现了HTMLHyperlinkElementUtils接口,该接口提供了一系列辅助属性,如protocol和hash等,用于显示与链接目标相关的值。一个这样有用的属性是href,它将返回完整的URL,去除了无用的空格,而不是属性中指定的相对URL。这样,如果需要获取href属性中的字符串字面量值,只能使用el.getAttribute('href')方法。12对话框元素的三大法宝是一个比较新的元素,它带来了两个可以使用的方法,一个非常好用的方法。其中,show()和close()方法的作用和你想象的一样,我觉得还不错。showModal()方法可以在页面的顶层居中显示元素,这是模态窗口的预期行为。您不需要指定z-index,或手动添加灰色背景,也不需要监听esc按键关闭窗口。浏览器了解模态窗口的工作方式并自动执行您期望的操作。这很酷。13forEach()在某些情况下,当您获得对元素列表的引用时,您可以通过forEach()方法迭代调用。使用for()循环是2014年代的遗物。假设你需要记录页面中所有链接的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()方法(此外还有keys()、values()和entries()等方法)。理想情况下,每个方法最好只返回一个简单的数组,而不是一些类似数组的对象。不过不用担心,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(Boolean),以后调试问题的时候肯定会后患无穷,哈哈。14表单您可能已经知道,
有一个submit()方法。但是你可能不知道表单还有一个reset()方法,当你需要验证表单元素时,也可以调用reportValidity()方法。或者,您可以通过将元素的名称属性添加到表单的元素属性来调用其属性。例如,myFormEl.elements.email将返回属于的元素(“属于”并不意味着它一定是“孩子”)。好吧,其实我刚才骗了你。elements返回的不是元素列表,而是控件列表(显然不是数组,因为没有必要这样做)。例如:假设您有三个单选按钮,每个单选按钮都具有相同的名称animal,那么formEl.elements.animal将返回对单选按钮集(一个控件,三个元素)的引用。而formEl.elements.animal.value将返回所选单选按钮的值。这个语法看起来很奇怪,我们来分解一下:formEl是一个元素,elements对应的是HTMLFormControlsCollection接口,不是真正的数组,里面的每一项并不一定代表一个HTML元素。animal是多个radiobutton的集合,只是因为它们有相同的name属性,所以聚集在一起(RadioNodeList接口就是为此而生),value返回集合中被选中的radiobutton的value属性。非常直观,嗯...15select()