【发布时间】:2016-05-15 15:48:27
【问题描述】:
这是一个关于 Angular 2 选择器、自定义标签与自定义属性、SEO 和浏览器渲染的问题。
当我第一次开始查看 Angular 2 时,我按照他们的快速入门做的第一件事就是将我的选择器更改为 '[my-component]'(属性选择器)而不是 'my-component'(标签选择器) ),所以我可以在我的 html 中使用 <div my-component></div> 而不是 <my-component></my-component>,这不是有效的 html。所以我会根据标准编写html。好吧,至少非常接近标准(因为my-component 不是有效的 html 属性,但我只能忍受那个 html 验证错误)
然后,在 youtube 上的某个视频中,Angular 团队的某个人提到我们应该使用标签选择器,至少在性能方面是这样。
好吧,我说,搞砸 html 验证...还是不应该?
所以:
假设由于
<custom-tags>,我忽略了 W3C 对我的 html 完全无效的尖叫。实际上,我还有另一个更大更真实的担忧:这对 SEO 有何影响?
我的意思是不要只考虑客户端应用程序,因为在现实世界中(以及我的 angular 2 项目)我也有服务器端渲染,原因有两个:SEO 和在应用启动之前,快速初始呈现网站给用户的初始视图。否则,您不能拥有非常高流量的 SPA。
当然,无论我使用什么标签,谷歌都会抓取我的网站,但它在两种情况下的排名是否相同:一种使用<custom-make-believe-tags>,另一种仅使用标准 html 标签?让我们谈谈浏览器和css:
当我开始在 Angular 2 中构建我的第一个 SPA 网站时,我立即面临另一个问题:
说(在非 SPA 网站中)我有以下 html 标记:
<header>
<a class="logo">
...
</a>
<div class="widgets">
<form class="frm-quicksearch"> ... </form>
<div class="dropdown">
<!-- a user dropdown menu here -->
</div>
</div>
</header>
<div class="video-listing">
<div class="video-item"> ... </div>
<div class="video-item"> ... </div>
...
</div>
Angular 2 明智的我将拥有以下组件树:
<header-component>
<logo-component></logo-component>
<widgets-component>
<quicksearch-component></quicksearch-component>
<dropdown-component></dropdown-component>
</widgets-component>
</header-component>
<video-listing-component>
<video-item-component></video-item-component>
...
</video-listing-component>
现在,我有两个选择。让我们以<video-listing-component> 为例,为了保持简单...我要么
A) 将我已经拥有的整个标准 html 标记 (<div class="video-item"></div>) 放在 @987654332 中@标签,并且一旦渲染将导致:
<video-listing-component>
<div class="video-listing>
<video-item-component>
<div class="video-item>...</div>
</video-item-component>
...
...
</div>
</video-listing-component>
或:
B) 仅将 <div class="video-item"> 的内容直接放入我的<video-item-component> 组件中,并在组件标签上添加所需的类(class="video-item")进行样式设置,结果是这样的:
<video-listing-component class="video-listing">
<video-item-component class="video-item"></video-item-component>
<video-item-component class="video-item"></video-item-component>
...
</video-listing-component>
无论哪种方式(A 或 B),浏览器都可以正常呈现所有内容。
但是,如果您仔细查看(当然,在所有内容都在 dom 中呈现之后),默认情况下自定义标签不会占用 dom 中的任何空间。它们是 0px x 0px。只有它们的内容占据空间。我不明白为什么浏览器仍然呈现您希望看到的所有内容,我的意思是在第一种情况下(A):
虽然在div class="video-item" 上有float: left; width: 25%;,但是这些 div 中的每一个都在 within 一个 <video-item-component> 标签中,它没有任何样式......这不只是一个幸运的一面 -浏览器会按照您的预期呈现所有内容吗?随着所有<div class="video-item"> 浮动在彼此旁边,即使它们每个都在另一个标签内,<video-item-component> 没有浮动:左?我已经在 IE10+、Firefox、Chrome 上测试过,一切正常。只是幸运还是对此有可靠的解释,我们可以安全地依赖所有(或至少大多数)浏览器所期望的这种标记来呈现?
第二种情况(B):
如果我们直接在自定义标签 (<video-item-component>) 上使用类和样式......再次,一切都很好。但据我所知,我们不应该设置自定义组件的样式,对吧?这不也是一个幸运的预期结果吗?或者这也可以吗?我不知道,也许我还活在 2009 年……是吗?
这两种方法(A 或 B)中的哪一种是推荐的方法?还是两者都很好?
我不知道!!
编辑:
哦,谢谢 Günter Zöchbauer。是的,因为我的 div 有浮动:左,这就是为什么他们包裹的(自定义或非自定义)标签不会扩展它的高度。自从我开始研究 Angular 2 以来,似乎我已经忘记了 css 的工作原理:)
但是还有一件事:
如果我在块元素上设置百分比宽度(称为 E),我会假设它占它 直接父级的 x%。如果我设置浮动:左,我希望在直接父级内浮动。在我的 A 案例中,由于直接父级是没有显示类型和宽度的自定义标签,我希望事情会以某种方式中断,但仍然......我的 E 元素的行为就像它们的父级一样不是它们各自包含的自定义标签,而是 dom 中的下一个标签(在我的例子中是 <div class="video-listing>)。它们占据了其中的 x%,并且在其中浮动。我不认为这是正常的,我认为这只是一个幸运的效果,而且我担心有一天,在浏览器更新之后......我会醒来发现我所有的 Angular 2 网站看起来都完全破碎的。
那么... A 和 B 都是同样合适的方法吗?还是我做错了,以防 A?
EDIT2:
让我们稍微简化一下。当我回答了部分问题时,让我们再举一个生成 html 的例子(稍微简化一下,内联 css):
<footer>
<angular-component-left>
<div style="float: left; width: 50%;">
DIV CONTENT
</div>
</angular-component-left>
<angular-component-right>
<div style="float: left; width: 50%;">
DIV CONTENT
</div>
</angular-component-right>
</footer>
在尚未实现的原始 html 中(没有 <angular-component-...>,这些 div 应该向左浮动并且每个占据 <footer> 的 50%。令人惊讶的是,一旦它们被包裹在 <angular-component-...> 自定义标签中,它们就会相同:占据页脚的 50%。但这对我来说似乎是幸运,愚蠢的运气......意想不到的效果。
那么,这是不是“愚蠢的运气”?
我应该这样保留它,还是重写而不是上面的代码,我会有这样的东西:
<footer>
<angular-component-left style="display: block; float: left; width: 50%;">
DIV CONTENT
</angular-component-left>
<angular-component-right style="display: block; float: left; width: 50%;">
DIV CONTENT
</angular-component-right>
</footer>
请注意,为简单起见,此处引入了内联样式,实际上我将有一个类,而不是在我的文档的 <head> 中包含的外部 css 文件中,而不是通过我的 style 或 styleUrls角度分量。
【问题讨论】:
-
我不太明白 A 和 B 之间应该表现出什么本质区别。
-
我只是在问 A 或 B 中的哪一个是正确的方法。如果 A 发生的情况符合浏览器的预期,或者只是幸运。有一天,我醒来发现这种意外效果已在所有浏览器中得到修复,我的网站看起来很糟糕。另外,我主要做 html/css。我无法将我的头包裹在自定义标签上,更不用说样式化它们了。在我看来,它们简直是不自然的。大多数客户要做的第一件事就是将我生成的任何 html 粘贴到验证器中并说:看,我有警告或错误。我们需要解决这些问题。我必须解决这些问题。
-
我不是从开发人员的角度思考,而是从将设计实现到 html/css 的人的角度思考。我说的是渲染结果,而不是角度或幕后发生的事情。
-
我不明白 A 和 B 之间的区别是什么。自定义元素是普通的 HTML,它只是在运行时扩展为完整的 HTML。这种方式更容易创建可重用的片段并允许获取范围样式,这是通过 Angular 重写 CSS 的选择器以仅匹配添加到组件元素的唯一属性(默认)或利用影子 DOM 样式范围(使用
Native封装模式)。 -
您可以将
<angular-component-left>视为具有自定义名称的<div>。如果<angular-component-left>是一个Angular组件,那么组件中指定的template将作为innerHTML添加到<angular-component-left>中。
标签: css angular seo html-validation angular2-components