gjcxywwx 2019-07-01
As a web freshman, we having to make do with a long, nested batch of elements that together provide a custom page feature. however, some of frame often to ues custom elements and looks so cool or 逼格(how translate it ??),so, questing begging, how could we use the custom element and achieve it ??
MDN Official Documents just having some of unclear, so let's Simple and clear it!!
在MDN官方文档中,如果你想要使用自定义标签,可以使用customElement类中define方法(IE浏览器默默离开...),
使用:customElements.define('myselfTagName', myselfClass, extendsObj);
参数:
官方文档对于shadow DOM解释很模糊,简单的说就是DOM的'一体双魂',拥有同样的函数和方法,但是Shadow DOM比被附加DOM更多的功能,前者具有独自的作用域,并且与外界DOM分隔。(这个作用就是shadow DOM的核心功能,它可以使你编写的DOM与css与其他区域互不影响,相当于vue中css样式<style scoped> </style>的作用);
shadow DOM弥补了customElements缺少隔离作用域(DOM和css作用域)的缺陷。
shadom DOM Root的创建方法: this.attachShadow({mode: 'open'});
this: shadom DOM对象coding.... 莫道征途路漫漫 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Pop-up info box — web components</title> </head> <body> <h1>Pop-up info widget - web components</h1> <form> <div> <label for="cvc">Enter your CVC <popup-info img="img/alt.png" data-text="Your card validation code (CVC) is an extra security feature — it is the last 3 or 4 numbers on the back of your card."></label> <input type="text" id="cvc"> </div> </form> </body> <script> /** * * @description:将shadow root附加到customelement上, 然后通过一系列DOM操作创建custom element的内部阴影DOM结构, 再将其附加到 shadow root上,最后再将一些CSS附加到 shadow root的style节点上。 */ class PopUpInfo extends HTMLElement { constructor() { // 必须使用super初始化customElements类的构造器 super(); // 创建shadom Dom Root,该Root 挂载在自定义DOM上,该DOM Root节点是一个真实节点。 const shadow = this.attachShadow({mode: 'open'}); // Create spans const wrapper = document.createElement('span'); wrapper.setAttribute('class', 'wrapper'); let icon = document.createElement('span'), info = document.createElement('span'), text = this.getAttribute('data-text'); icon.setAttribute('class', 'icon'); icon.setAttribute('tabindex', 0); info.textContent = text; info.setAttribute('class', 'info'); let imgUrl = this.hasAttribute('img') ? this.getAttribute('img'): 'img/default.png', img = document.createElement('img'); img.src = imgUrl; icon.appendChild(img); // 优化样式 const style = document.createElement('style'); console.log(style.isConnected); style.textContent = ` .wrapper { position: relative; } .info { font-size: 0.8rem; width: 200px; display: inline-block; border: 1px solid black; padding: 10px; background: white; border-radius: 10px; opacity: 0; transition: 0.6s all; position: absolute; bottom: 20px; left: 10px; z-index: 3; } img { width: 1.2rem; } .icon:hover + .info, .icon:focus + .info { opacity: 1; } `; // 插入shadow dom Root shadow.appendChild(style); console.log(style.isConnected); shadow.appendChild(wrapper); wrapper.appendChild(icon); wrapper.appendChild(info); } } // 自定义标签 customElements.define('popup-info', PopUpInfo); </script> </html>
自定义标签的使用减少了我们频繁编写一堆冗余、深层嵌套的代码,提高了速率。然而,如果我们看页面源码会发现customElements.define不会消除自定义标签,自定义标签如果绑定了大量的数据、事件、敏感信息,页面上又完全显示出来,这就增加前端页面的不安全性。如何保证开发者即使用自定义标签又不会编译自定义标签从而导致DOM的过度挂载和数据的泄漏(总不能remove自定义标签吧,频繁操作DOM是不建议的),值得思考...
Vue和React是数据驱动视图,如何有效控制DOM操作?能不能把计算,更多的转移为js计算?因为js执行速度很快。patch函数-->patch,对比tag,对比tag与key,对比children