喂,
我在Javascript中有3个不同的功能,第一个替换用UL创建的HTML Selectboxs宽度自定义选择框。
,另外2个分别替换Checkbox和Radio按钮。
现在我想从这些函数中派生出类,并且需要你的建议,将这些函数组织到课堂中的最佳方法是什么,是否可以实现?
我非常感谢你的帮助。
感谢。
以下是一些示例代码。
function replaceSelect(formid) {
var form = $(formid);
if (!form) return;
invisibleSelectboes = document.getElementsByClassName("optionsDivInvisible");
if (invisibleSelectboes.length > 0) {
for (var i = 0; i < invisibleSelectboes.length; i++) {
document.body.removeChild(invisibleSelectboes[i]);
}
}
var selects = [];
var selectboxes = form.getElementsByTagName('select');
var selectText = "Bitte auswählen";
var selectRightSideWidth = 21;
var selectLeftSideWidth = 8;
selectAreaHeight = 21;
selectAreaOptionsOverlap = 2;
// Access all Selectboxes in Search mask.
for (var cfs = 0; cfs < selectboxes.length; cfs++) {
selects.push(selectboxes[cfs]);
}
// Replace the select boxes
for (var q = 0; q < selects.length; q++) {
if (selects[q].className == "") continue;
var onchangeEvent = selects[q].onchange;
//create and build div structure
var selectArea = document.createElement('div');
var left = document.createElement('div');
var right = document.createElement('div');
var center = document.createElement('div');
var button = document.createElement('a');
// var text = document.createTextNode(selectText);
var text = document.createTextNode('');
center.id = "mySelectText" + q;
if ( !! selects[q].getAttribute("selectWidth")) {
var selectWidth = parseInt(selects[q].getAttribute("selectWidth"));
} else {
var selectWidth = parseInt(selects[q].className.replace(/width_/g, ""));
}
center.style.width = selectWidth + 'px';
selectArea.style.width = selectWidth + selectRightSideWidth + selectLeftSideWidth + 'px';
if (selects[q].style.display == 'none' || selects[q].style.visibility == 'hidden') {
selectArea.style.display = 'none';
}
button.style.width = selectWidth + selectRightSideWidth + selectLeftSideWidth + 'px';
button.style.marginLeft = -selectWidth - selectLeftSideWidth + 'px';
// button.href = "javascript:toggleOptions( + q + ")";
Event.observe(button, 'click', function (q) {
return function (event) {
clickObserver(event, q)
}
}(q));
button.onkeydown = this.selectListener;
button.className = "selectButton"; //class used to check for mouseover
selectArea.className = "selectArea";
selectArea.id = "sarea" + q;
left.className = "left";
right.className = "right";
center.className = "center";
right.appendChild(button);
center.appendChild(text);
selectArea.appendChild(left);
selectArea.appendChild(right);
selectArea.appendChild(center);
//hide the select field
selects[q].style.display = 'none';
//insert select div
selects[q].parentNode.insertBefore(selectArea, selects[q]);
//build & place options div
var optionsDiv = document.createElement('div');
if (selects[q].getAttribute('width')) optionsDiv.style.width = selects[q].getAttribute('width') + 'px';
else optionsDiv.style.width = selectWidth + 8 + 'px';
optionsDiv.className = "optionsDivInvisible";
optionsDiv.id = "optionsDiv" + q;
optionsDiv.style.left = findPosX(selectArea) + 'px';
optionsDiv.style.top = findPosY(selectArea) + selectAreaHeight - selectAreaOptionsOverlap + 'px';
//get select's options and add to options div
for (var w = 0; w < selects[q].options.length; w++) {
var optionHolder = document.createElement('p');
if (selects[q].options[w].className == "informal") {
var optionLink = document.createElement('a');
var optionTxt = document.createTextNode(selects[q].options[w].getAttribute('text'));
optionLink.innerHTML = selects[q].options[w].getAttribute('text');
optionLink.className = "informal";
cic.addEvent(optionLink, 'click', function (event) {
Event.stop(event);
});
Event.observe(optionLink, 'mouseover', function (event) {
Event.stop(event);
});
Event.observe(optionLink, 'mouseout', function (event) {
Event.stop(event);
});
}
else {
var optionLink = document.createElement('a');
var optionTxt = document.createTextNode(selects[q].options[w].text);
optionLink.appendChild(optionTxt);
cic.addEvent(optionLink, 'click', function (id, w, q, onchangeEvent) {
return function () {
showOptions(q);
selectMe(selects[q].id, w, q, onchangeEvent);
}
}(selects[q].id, w, q, onchangeEvent));
}
//optionLink.href = "javascript:showOptions(" + q + "); selectMe('" + selects[q].id + "'," + w + "," + q + ");";
optionHolder.appendChild(optionLink);
optionsDiv.appendChild(optionHolder);
if (selects[q].options[w].selected) {
selectMe(selects[q].id, w, q);
}
}
document.getElementsByTagName("body")[0].appendChild(optionsDiv);
Event.observe(optionsDiv, 'mouseleave', function (submenuid) {
optionsDiv.className = 'optionsDivInvisible'
});
cic.addEvent(optionsDiv, 'click', function (event) {
if (event.stopPropagation) event.stopPropagation();
else event.cancelBubble = true;
});
}
form.setStyle({
visibility: 'visible'
});
}
答案 0 :(得分:3)
从它的声音来看,您希望创建一个统一的API来封装所有这些“表单增强”功能。可能是这样的:
var formEnhancement = {
SelectBox: function(){ /* ... */ },
CheckBox: function(){ /* ... */ },
RadioButton: function(){ /* ... */ }
};
formEnhancement.SelectBox.prototype = { /* ... define methods ... */ };
// etc. (other prototypes)
// Call something:
var myEnhancedSelectBox = new formEnhancement.SelectBox(
document.getElementById('id-of-a-select-box')
);
这是否可以回答您的问题?
答案 1 :(得分:3)
我会去
var Library = (function()
{
function _selectBox()
{
// stuff
}
function _checkBox()
{
// stuff
}
function _radioButton()
{
// stuff
}
return {
SelectBox : _selectBox,
CheckBox : _checkBox,
RadioButton : _radioButton
};
})();
或
var Library = (function()
{
return {
SelectBox : function()
{
// stuff
},
CheckBox : function()
{
// stuff
},
RadioButton : function()
{
// stuff
}
};
})();
[编辑]
通过这种方式,您实际上可以声明只能从库本身访问的“私有”变量,只需在var foo="bar";
的声明中声明Library
,创建一个无法从外部访问的foo变量,但是可以通过库中的任何东西访问,这就是为什么像我的例子中的_selectBox这样的函数保持私有,但仍然可以通过Library.SelectBox访问,这将是“公共getter”
[/编辑]
也是,而不是
var Library = (function(){})();
你可以这样做:
var Library = Library || {};
Library.UI = (function(){})();
这样,您可以保留代码库的单独部分,可以将它们保存在单独的文件中,这些文件不关心它们的加载顺序,只要它们有
var Library = Library || {};
在他们之上
然后会像这样调用函数:
Library.SelectBox();
或者您选择使用“子类”
Library.UI.SelectBox();
答案 2 :(得分:1)
将函数放在命名空间中:
声明如下:
FormUtils = {};
并添加其属性,这将是您的功能
FormUtils.replaceSelect = function () {/*your code*/};
FormUtils.replaceCheckbox = function () {/*your code*/};
FormUtils.replaceRadio = function () {/*your code*/};
然后用它们的命名空间调用这个函数:
FormUtils.replaceSelect();
这是一个简单且非常公认的javascript设计模式
答案 3 :(得分:1)
所有答案都是一般模式,我认为它们都没有真正有用。仅仅因为你将3个巨大的函数放入对象中并不会使代码模块化,可重用,可维护。
所以我的第一个建议是使用 function decomposition 。你提到了继承。现在,如果您的代码基本上由这3个巨型函数组成,则无法继承或共享任何内容。您应该将功能逻辑按目的分成更小,更直接的功能逻辑。
一个很好的例子就是你提到替换一词在所有情况下都是相关的。也许你可以设置一个独立于元素类型负责DOM替换的函数。这些功能可以在您的模块之间共享,使您的代码更加健壮,并允许您 DRY 。
组织此过程的最佳方式称为一厢情愿,当您使用直观且有用的功能解决您的问题时,即使它们甚至可能不存在。这与您如何设计有效的相互作用有关。