jQueryなどのフレームワークがはるかにアドバイスされ、適用可能であることを「実際の練習」で理解しています。これは本当にフレームワークの使い方、純粋なjavascriptの仕組みとベストプラクティスに関するものではありません)。DOMノードにデータ(オブジェクト、カスタム属性)を格納する方法をコーディングする方法
とにかく、私は単純なJavaScriptコードを書いています。私は、セット{on、off}から一度に1つの状態を持つ一連のボタン群を作成し、各状態は、その状態に入るときに起動される対応する関数にマップしたいと考えました。マスターセット内の各ボタングループには、一度にオン状態のボタンが1つだけ含まれています。概念はラジオボタンの考え方に似ています。 なぜラジオボタンを使用しないのですか?意味的には、いくつかのコントロール要素用のボタンがいくつかあると思われますが、いずれの方法でも可能ですが、質問は実際にはそうではありません。
この問題を解決するために、具体的なbutton
要素に多くのカスタム属性を追加しました。これは、私のJavascriptでid
です。私はいくつかの調査をしていましたが、これはquestionとこれがquestionで、DOMノード(オブジェクト)のカスタム属性の使用に関するものです。彼らはそのような練習に反対しているようだが、ブラウザの実装に応じてメモリリークを引き起こす可能性があるということさえある。
しかし、ボタンごとにたくさんの属性を記録する必要があります。このスクリプトを展開すると、さらに追加する必要があります。だから、DOMノードにそれらを格納するのに最も良い方法はありますが、すべてを追跡して使用することができますこのなどの機能には?
DOMノードbutton
要素にwell-name spacingオブジェクトの参照を最小限格納することなく、これを行う方法を私には容易にはわかりませんでした。
このことから、question jQueryにはこれを行う方法がいくつかありますが、これは純粋なjavascriptでどのように行われているのか知りたいのです。
<!DOCTYPE html>
<html>
<head>
<title>Button Test Script</title>
<script language="javascript" type="text/javascript">
window.button_groups = {};
function isset(type) {
return !(type==='undefined');
}
function debug(txt) {
if(!isset(typeof console)) {
alert(txt);
} else {
console.log(txt);
}
}
function img(src) {
var t = new Image();
t.src = src;
return t;
}
function turnGroupOff(group) {
if(isset(typeof window.button_groups[group])) {
for(var i = 0; i < window.button_groups[group].length; i++) {
if(window.button_groups[group][i].toggle == 1)
window.button_groups[group][i].click();
}
}
}
/**
* buttonId = id attribute of <button>
* offImg = src of img for off state of button
* onImg = src of img for on state of button
* on = function to be fired when button enters on state
* off = function to be fired when button enters off state
*/
function newButton(buttonId, offImg, onImg, group, on, off) {
var b = document.getElementById(buttonId);
b.offImg = img(offImg);
b.onImg = img(onImg);
b.on = on;
b.off = off;
b.img = document.createElement('img');
b.appendChild(b.img);
b.img.src = b.offImg.src;
b.group = group;
b.toggle = 0;
b.onclick = function() {
switch(this.toggle) {
case 0:
turnGroupOff(this.group);
this.on();
this.toggle = 1;
this.img.src = this.onImg.src;
break;
case 1:
this.off();
this.toggle = 0;
this.img.src = this.offImg.src;
break;
}
}
if(!isset(typeof window.button_groups[group]))
window.button_groups[group] = [];
window.button_groups[group].push(b);
}
function init() {
var on = function() { debug(this.id + " turned on") };
newButton('button1', 'images/apply-off.jpg', 'images/apply-on.jpg', 'group1',
on,
function() { debug(this.id + " turned off"); }
);
newButton('button2', 'images/unapply-off.jpg', 'images/unapply-on.jpg', 'group1',
on,
function() { debug(this.id + " turned off (diff then usual turn off)"); }
);
newButton('button3', 'images/apply-off.jpg', 'images/apply-on.jpg', 'group2',
on,
function() { debug(this.id + " turned off (diff then usual turn off2)"); }
);
newButton('button4', 'images/unapply-off.jpg', 'images/unapply-on.jpg', 'group2',
on,
function() { debug(this.id + " turned off (diff then usual turn off3)"); }
);
}
window.onload = init;
</script>
</head>
<body>
<button id="button1" type="button"></button>
<button id="button2" type="button"></button>
<br/>
<button id="button3" type="button"></button>
<button id="button4" type="button"></button>
</body>
</html>
UPDATE
jQueryの事は私の目的のためにビットやり過ぎだった:
は、ここに私が働いている完全なサンプルコードです。私は任意の要素を拡張する必要はありません。私はそれがどのようにjQuery(キャッシュインデックス整数を格納している任意の名前のついた任意の属性を持つ)に固有であるかを知っています。
私は、どのホスト要素を拡張する必要があるのか、またその方法を知っています。また、HTML側のそれぞれにid
属性を設定することもできます。
jQueryの設定に影響を受けて、DOMキーのid属性をキャッシュキーとして使用する以外は、グローバルキャッシュ変数も作成することにしました。それは一意の識別子(定義による)でなければならないので、idを動的に変更する予定はなく、これは簡単な作業でなければなりません。私のJavascriptオブジェクトはDOMオブジェクトから完全に分離されていますが、data
への多くの呼び出しでコードがかなり醜く見えにくくなります。私は本当に唯一の「特別な」属性を格納する必要が閉鎖の電源を使用して、それがボタンのグループであることがわかっ
<!DOCTYPE html>
<html>
<head>
<title>Button Test Script</title>
<script language="javascript" type="text/javascript">
window.button_groups = {};
function isset(type) { // For browsers that throw errors for !object syntax
return !(type==='undefined');
}
var c = { // For browsers without console support
log: function(o) {
if(isset(typeof console)) {
console.log(o);
} else {
alert(o);
}
},
dir: function(o) {
if(isset(typeof console)) {
console.dir(o);
}
}
};
function img(src) { // To avoid repeats of setting new Image src
var t = new Image();
t.src = src;
return t;
}
var cache = {};
function data(elemId, key, data) { // retrieve/set data tied to element id
if(isset(typeof data)) {// setting data
if(!isset(typeof cache[elemId]))
cache[elemId] = {};
cache[elemId][key] = data;
} else { // retreiving data
return cache[elemId][key];
}
}
var button_groups = {}; // set of groups of buttons
function turnGroupOff(group) { // turn off all buttons within a group
if(isset(typeof window.button_groups[group])) {
for(var i = 0; i < window.button_groups[group].length; i++) {
if(data(window.button_groups[group][i].id, 'toggle') == 1)
window.button_groups[group][i].click();
}
}
}
/**
* buttonId = id attribute of <button>
* offImg = src of img for off state of button
* onImg = src of img for on state of button
* on = function to be fired when button enters on state
* off = function to be fired when button enters off state
*/
function newButton(buttonId, offImg, onImg, group, on, off) {
var b = document.getElementById(buttonId);
data(b.id, 'offImg', img(offImg));
data(b.id, 'onImg', img(onImg));
data(b.id, 'on', on);
data(b.id, 'off', off);
var btnImg = document.createElement('img');
btnImg.src = data(b.id, 'offImg').src;
data(b.id, 'img', btnImg );
b.appendChild(btnImg);
data(b.id, 'group', group);
data(b.id, 'toggle', 0);
var click = function() {
switch(data(this.id,'toggle')) {
case 0:
turnGroupOff(data(this.id,'group'));
(data(this.id,'on'))();
data(this.id,'toggle',1);
data(this.id,'img').src = data(this.id,'onImg').src;
break;
case 1:
(data(this.id,'off'))();
data(this.id,'toggle',0);
data(this.id,'img').src = data(this.id,'offImg').src;
break;
}
}
b.onclick = click;
if(!isset(typeof window.button_groups[group]))
window.button_groups[group] = [];
window.button_groups[group].push(b);
}
function init() {
var on = function() { c.log(this.id + " turned on") };
newButton('button1', 'images/apply-off.jpg', 'images/apply-on.jpg', 'group1',
on,
function() { c.log(this.id + " turned off"); }
);
newButton('button2', 'images/unapply-off.jpg', 'images/unapply-on.jpg', 'group1',
on,
function() { c.log(this.id + " turned off (diff then usual turn off)"); }
);
newButton('button3', 'images/apply-off.jpg', 'images/apply-on.jpg', 'group2',
on,
function() { c.log(this.id + " turned off (diff then usual turn off2)"); }
);
newButton('button4', 'images/unapply-off.jpg', 'images/unapply-on.jpg', 'group2',
on,
function() { c.log(this.id + " turned off (diff then usual turn off3)"); }
);
}
window.onload = init;
</script>
</head>
<body>
<button id="button1" type="button"></button>
<button id="button2" type="button"></button>
<br/>
<button id="button3" type="button"></button>
<button id="button4" type="button"></button>
</body>
</html>
UPDATE 2
:私は、以下の変更を提示します所属していた。
私は閉鎖を通じて、私がしたものを他のものの多くを保存する必要性を排除するには、次のnewButton
機能を変更:
function newButton(buttonId, offImg, onImg, group, on, off) {
var b = document.getElementById(buttonId);
offImg = img(offImg);
onImg = img(onImg);
var btnImg = document.createElement('img');
btnImg.src = offImg.src;
b.appendChild(btnImg);
data(b.id, 'group', group);
var toggle = 0;
var click = function(event) {
switch(toggle) {
case 0:
turnGroupOff(data(this.id,'group'));
if(on(event)) {
toggle = 1;
btnImg.src = onImg.src;
}
break;
case 1:
if(off(event)) {
toggle = 0;
btnImg.src = offImg.src;
}
break;
}
}
b.onclick = click;
if(!isset(typeof window.button_groups[group]))
window.button_groups[group] = [];
window.button_groups[group].push(b);
b = null;
}
jQueryはJavaScriptで_written_です。 [how they do it](https://github.com/jquery/jquery/blob/master/src/data.js)、特に 'data()'関数を見てください。 – voithos