1

バニラ 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>

/content/green.css上記の例では、相対 URL が次の外部 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 に答える