2017-09-25 7 views
0

DOM要素(HTMLやSVG要素など)に実行時に動的に、つまりユーザーの入力に基づいて属性をプログラムで追加する必要があります。属性が標準のものであればそのまま使用しますが、そうでない場合、つまりカスタム属性に変換する必要がある場合は、「data-」という接頭辞を追加します。属性が標準HTML(またはSVG)で有効かどうかを確認

文字列が「標準/標準」DOM属性を表すかどうかを判断する方法はありますか?例えば

、次のように私はSVG矩形を持っていると言う:

<rect x="10" y="10" width="80" height="40" stroke="black"/> 

注塗りつぶしの色が(まだ)指定されていないこと。二つの属性を追加すること

ユーザーの要求:

  • fill="red"
  • という名前の属性「価格(接頭辞が存在しないことに注意)が得値「赤」と「満たす」という名前の属性、 data-price="expensive"を得なければならない 『高価な、"値を』

は、どのように私は動的にこれら二つを区別しない(data-接頭辞に注意してください)? fill属性は現在のDOM要素には存在しないため、その名前の属性に既存の値があるかどうかを確認することはできません。プレフィックスを付けずに属性を作成すると、エラーがスローされるかどうかを確認することもできないと私は信じていません。少なくとも現在のブラウザ(Chrome v61.0)では属性を追加できますこれはベストプラクティスではありませんが、price="expensive"data-の接頭辞なし)です。

私は、次のような何かをしたい:

const elementNodeName = "rect"; 
const attributeName = "height"; // or, e.g. "price" 
const nameIsValid = testAttributeNameValidity(elementNodeName, attributeName); 
if (!nameIsValid) attributeName = 'data-' + attributeName; 

はそこに任意の既存のtestAttributeNameValidity型の機能はありますか?

私はjavascriptとタグ付けしました.Javascriptソリューションを探しています。

** UPDATE:私は非のための有効な属性名のtruefalseを返すことになっているattributeName in document.createElement(elementNodeName)を使用してみましたthe suggested link in the commentsに基づいてHTMLではなくSVG **

内の他のSO答える作品からソリューション有効なもの。 HTML要素に有効な属性名 "id"を使用すると(<p>)、このアプローチが有効です。

これとは対照的に、私はまだこのアプローチをSVGで動作させていません。 createElementcreateElementNSに変換しようとしましたが、それでも問題を解決していないようです。以下の私のテストコードを参照してください。テストコードの重要な機能は、testHtmlAttributeNameValiditytestSvgAttributeNameValidityです。コードを実行してコンソールの出力を確認すると、HTMLで正しく動作することが示されます。つまり、id="someId" data-price="expensive"が生成されます。しかし、SVGでは、望ましくない出力しか生成しません:data-fill="yellow" data-price="expensive"

違いがある場合は、Chrome v61で作業しています。

テストコード:正しくコードが起こらない、黄色に黒の塗りつぶし矩形を変更する必要があり作業

const testHtmlAttributeNameValidity = (elementNodeName, attributeName) => { 
 
    return (attributeName in document.createElement(elementNodeName)); 
 
}; 
 

 
const testHtmlAttributeName = (attributeName, attributeValue) => { 
 
    const elementNodeName = "p"; 
 
    const nameIsValid = testHtmlAttributeNameValidity(elementNodeName, attributeName); 
 
    if (!nameIsValid) attributeName = 'data-' + attributeName; 
 
    const element = document.querySelector(elementNodeName); 
 
    element.setAttribute(attributeName, attributeValue); 
 
}; 
 

 
testHtmlAttributeName("id", "someId"); 
 
testHtmlAttributeName("price", "expensive"); 
 

 
console.log(document.querySelector('div').innerHTML); 
 

 

 
const svgNS = "http://www.w3.org/2000/svg"; 
 

 
const testSvgAttributeNameValidity = (elementNodeName, attributeName) => { 
 
    return (attributeName in document.createElementNS(svgNS, elementNodeName)); 
 
}; 
 

 
const testSvgAttributeName = (attributeName, attributeValue) => { 
 
    const elementNodeName = "rect"; 
 
    const nameIsValid = testSvgAttributeNameValidity(elementNodeName, attributeName); 
 
    if (!nameIsValid) attributeName = 'data-' + attributeName; 
 
    const element = document.querySelector(elementNodeName); 
 
    element.setAttribute(attributeName, attributeValue); 
 
}; 
 

 
testSvgAttributeName("fill", "yellow"); 
 
testSvgAttributeName("price", "expensive"); 
 

 
console.log(document.querySelector('svg').innerHTML);
#someId { 
 
    color: green; 
 
}
<svg height="55"> 
 
    <rect x="10" y="10" width="80" height="40" stroke="red"/> 
 
</svg> 
 

 
<div> 
 
<p>Hello world</p> 
 
</div>

+1

に関連するようです[DOM要素および/または属性が有効であるかどうかを確認するには?](https://stackoverflow.com/questions/33584700/how-to-check-if -dom-element-and-or-attribute-is-valid) –

+0

これがXHTMLが作られた理由です。しかし、誰もがHTMLを好んで墓に投げかけている。 – BoltClock

+0

@ShreyanshGandhi、私はそのリンクを見て、それは私の問題を解決するようだ。しかし、私はそれを実装することができないようですが、希望の結果をもたらさないテストコードを含む私の質問へのアップデートに示されています。さらに、私はHTMLのための標準の 'createElement'とsvgのためのより特定的な' createElementNS'の両方を使ってみました...どちらもうまくいきませんでした。 –

答えて

0

@ccprogのコメントから、この問題を解決できました。要約すると、SVG DOM要素の場合、元のチェックに加えて、同じであるが、.styleプロパティを追加した論理ORチェックが必要でした。

質問に示すように、次のように、HTML DOM要素の妥当性属性名をチェックすることによって決定することができる。

// correct for HTML: 
return (
    attributeName in document.createElement(elementNodeName) 
); 

しかし、このアプローチは、SVGのDOM要素のために動作しません。具体的には、以下の「ID」のような真の属性名の有効性を判断しますが、ない「埋める」のようなスタイルに似た属性名の妥当性を判断します:単にことを複製し、しかし

// insufficient for SVG, i.e. only partially correct: 
return (
    attributeName in document.createElementNS(svgNS, elementNodeName) 
); 

を試験と次のように、属性名の両方のカテゴリを確認することを可能にする2つのチェックのいずれかに.styleプロパティを追加:

// correct for SVG: 
return (
    attributeName in document.createElementNS(svgNS, elementNodeName).style || 
    attributeName in document.createElementNS(svgNS, elementNodeName) 
); 

これはQUEのコードと本質的に同一である次のコードに示されています上記の変更を除いて、属性名の両方のカテゴリの妥当性を判断する能力は、可視の矩形における黄色の塗りつぶしと太い線の幅の両方の外観に反映され、同時にカスタムの「データ価格」属性を要素に追加する。特に、HTML DOM要素とSVG DOM要素を別々に調べる必要があることに注意してください。

const testHtmlAttributeNameValidity = (elementNodeName, attributeName) => { 
 
    return (attributeName in document.createElement(elementNodeName)); 
 
    return (
 
    attributeName in document.createElement(elementNodeName) 
 
); 
 
}; 
 

 
const testHtmlAttributeName = (attributeName, attributeValue) => { 
 
    const elementNodeName = "p"; 
 
    const nameIsValid = testHtmlAttributeNameValidity(elementNodeName, attributeName); 
 
    if (!nameIsValid) attributeName = 'data-' + attributeName; 
 
    const element = document.querySelector(elementNodeName); 
 
    element.setAttribute(attributeName, attributeValue); 
 
}; 
 

 
testHtmlAttributeName("id", "someHtmlId"); 
 
    // This should result in "id" attribute being changed, changing the 
 
    // font color to green. 
 

 
testHtmlAttributeName("color", "orange"); 
 
    // While "color" IS a CSS property name, it is NOT an HTML DOM element 
 
    // attribute name. Therefore, this test should result in "color" NOT being 
 
    // recognized as a valid attribute name, resulting in the 
 
    // custom attribute name "data-color", with no effect on the 
 
    // actual styling of the element, i.e. this test should NOT 
 
    // turn the text orange. This test is included here 
 
    // to provide a contrast to what should happen with SVG DOM 
 
    // element style-like attributes like "fill", as shown below 
 
    // in the section testing SVG DOM element attribute names. 
 

 
testHtmlAttributeName("price", "expensive"); 
 
    // This should result in a new attribute with the name "data-price" 
 
    // and the value "expensive". 
 

 
console.log(document.querySelector('div').innerHTML); 
 

 

 
const svgNS = "http://www.w3.org/2000/svg"; 
 

 
const testSvgAttributeNameValidity = (elementNodeName, attributeName) => { 
 
    return (// ********** THIS IS THE IMPORTANT CHANGE ********** 
 
    attributeName in document.createElementNS(svgNS, elementNodeName).style || 
 
    attributeName in document.createElementNS(svgNS, elementNodeName) 
 
); 
 
}; 
 

 
const testSvgAttributeName = (attributeName, attributeValue) => { 
 
    const elementNodeName = "rect"; 
 
    const nameIsValid = testSvgAttributeNameValidity(elementNodeName, attributeName); 
 
    if (!nameIsValid) attributeName = 'data-' + attributeName; 
 
    const element = document.querySelector(elementNodeName); 
 
    element.setAttribute(attributeName, attributeValue); 
 
}; 
 

 
testSvgAttributeName("id", "someSvgId"); 
 
testSvgAttributeName("fill", "yellow"); // *** Now correctly identified as valid 
 
testSvgAttributeName("price", "expensive"); 
 

 
console.log(document.querySelector('svg').innerHTML);
#someHtmlId { 
 
    color: green; 
 
} 
 
#someSvgId { 
 
    stroke-width: 5px; 
 
}
<svg height="55"> 
 
    <rect x="10" y="10" width="80" height="40" stroke="red"/> 
 
</svg> 
 

 
<div> 
 
<p>Hello world</p> 
 
</div>

関連する問題