1

我正在使用用 vanilla JavaScript(无框架)实现的 HTML5 Web 组件(HTML 导入、影子 DOM、模板和自定义 HTML 元素)设计一个 Web 应用程序。Web 应用程序相当简单,并且必须作为单页应用程序来实现。应用程序的部分要求是用户界面应该是可定制的。

设计方法

该示例使用<application-navigation>自定义元素。new CustomEvent('application-navigation', {location:'/sign-in'})该元素通过自定义事件(例如)和方法调用(例如)与“顶级”JavaScript(例如,JavaScript MV* 用语中的“路由器”)进行通信document.querySelector('application-navigation').enableSignOut()。本质上,自定义事件和方法构成了元素的“公共 API”。

可以使用不同的 HTML 导入将自定义<application-navigation>元素包含在应用程序中。例如,使用<link rel="import" href="default/application-navigation.html"/><link rel="import" href="my_cool_theme/application-navigation.html"/>。只要 HTML 导入具有相同的方法并产生相同的自定义事件,应用程序就应该以相同的方式运行,而不管正在使用什么用户界面自定义。

这种设计的主要好处是它通过允许非常可定制的用户界面来满足要求 - 内部 JavaScript 事件、CSS 和(影子)DOM 结构可以在模板之间完全不同。它还允许在适当的时候重用现有的库。例如,默认<application-navigation>元素可以使用来自 Twitter Bootstrap 的下拉 HTML 标记,而主题版本可以使用 Foundation 库。

但是,这个组件不是很通用。它实现了一个相当特定的目的(控制导航请求),不像一个<application-dropdown>元素(尽管该<application-navigation>元素可以使用一个(可定制的)<application-dropdown>元素)。

重述问题

我的问题是,是否应该创建自定义元素来实现特定目的、更通用的目的,或者目的的广度是否无关紧要?

4

1 回答 1

1

您可以构建特定或通用的自定义元素。两者都是相关的。

但是,定义自定义元素的主要好处是能够轻松地重用它们。所以我会说自定义元素通常是通用的。

关于架构,您可以设计通用的技术元素,然后您可以使用它们来组合特定的功能元素。


无论如何,创建 2 个具有相同标签名称的不同组件并不是一个好主意。您宁愿使用另一种方法来实现您的目标(使用属性或内部元素来自定义您的自定义元素,或者给它另一个名称)。

这是一个将主题定义为元素属性的示例:

//CUSTOM ELEMENT
var proto = Object.create( HTMLElement.prototype )

proto.createdCallback = function ()
{
  console.log( "{created}" )
  var html = document.querySelector( "template" )
  this.innerHTML = html.innerHTML
}

proto.attributeChangedCallback = function ( attr, old, val )
{
  console.log( "{changed} attr=%s, old=%s, new=%s", attr, old, val )
}

var AN = document.registerElement( "application-navigation", { 
  prototype: proto 
} )

//EVENTS
function add ()
{
  if ( AN )
    document.body.appendChild( new AN )
}

function theme ( name )
{
  var elem = document.querySelector( "application-navigation" )
  if ( elem )
    elem.setAttribute( "theme", name )
    }

function load ()
{
  var link = document.createElement( "link" )
  link.rel = "stylesheet"
  link.href = "/content/green.css"
  document.head.appendChild( link )
}
application-navigation[theme=blue] {
			color: blue ;
		}
		application-navigation[theme=red] {
			color: red ;
		}
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
  <title></title>
</head>
<body>
	<nav>
		<button onclick="add()">Add Custom Element</button>
		<button onclick="theme('red')">Change First to Red</button>
		<button onclick="load()">External CSS</button>
	</nav>
	<template>
		<h1>Title</h1>
		<p>Custom Element Content</p>
	</template>

	<application-navigation theme="blue"></application-navigation>
</body>
</html>

在上面的示例中,您甚至可以加载相对 URL 为的外部 CSS 文件/content/green.css

application-navigation[theme=blue] * {
    color: limegreen ;
}

application-navigation[theme=red] p {
    color: green ;
}

application-navigation[theme=red] h1 {
    color: orange ;
}
于 2015-10-21T10:31:47.147 回答