我正在创建一个接收选择器作为参数的对象,它有一个名为 stylise
的方法,用于更改HTML元素的CSS(s )选中。
代码:
/* ----- JavaScript ----- */
function get(selector) {
var
self = {},
elements = Array.from(document.querySelectorAll(selector));
this.stylise = function(object) {
Object.keys(object).forEach(function(propertyName) {
for (var index = 0; index < elements.length; index++) {
elements[index].style[propertyName] = object[propertyName];
};
});
};
return Object.setPrototypeOf(self, this.prototype);
};
<!----- HTML ----->
<input id = "text" type = "text" style = "padding: .5em .7em;"/>
如果跳过 return Object.setPrototypeOf(self, this.prototype);
行,则上述代码将按预期工作,如下所示:
var a = new get("#text");
a.stylise({
backgroundColor: "yellow",
borderRadius: "5px"
});
但是,我希望通过调用它来实现上述目的:
get("#text").stylise({
backgroundColor: "yellow",
borderRadius: "5px"
});
我尝试使用 Object.setPrototypeOf(self, this.prototype)
来实现这一目标,但无效,因为我在控制台中收到以下错误: Object doesn't support property or method 'stylise'
。
我的代码的哪一部分导致了这个问题,我该如何解决?
答案 0 :(得分:5)
您不需要setPrototypeOf
(非常非常少的情况,这是您要达到的目标),只需让get
返回您创建并分配给{的对象{1}}并分配给self
而不是self.stylise
:
this.stylise
/* ----- JavaScript ----- */
function get(selector) {
var
self = {},
elements = Array.from(document.querySelectorAll(selector));
self.stylise = function(object) {
Object.keys(object).forEach(function(propertyName) {
for (var index = 0; index < elements.length; index++) {
elements[index].style[propertyName] = object[propertyName];
};
});
};
return self;
}
get("#text").stylise({
backgroundColor: "yellow",
borderRadius: "5px"
});
实际上,您可以在对象初始值设定项中创建<!----- HTML ----->
<input id = "text" type = "text" style = "padding: .5em .7em;"/>
。您还可以在stylise
上使用forEach
:
elements
/* ----- JavaScript ----- */
function get(selector) {
var elements = Array.from(document.querySelectorAll(selector));
return {
stylise: function(object) {
Object.keys(object).forEach(function(propertyName) {
elements.forEach(function(element) {
element.style[propertyName] = object[propertyName];
});
});
}
};
}
get("#text").stylise({
backgroundColor: "yellow",
borderRadius: "5px"
});
你在其他地方已经说过要在构造函数之外定义<!----- HTML ----->
<input id="text" type="text" style="padding: .5em .7em;" />
(将stylise
放在对象上就好了)。如果是这样,您可以使用elements
创建由特定原型对象支持的对象(在我们的示例中为Object.create
);这样做get.prototype
在调用构造函数之前创建对象时所执行的操作,但是您已经说过不想使用new
。
请注意,此示例首先通过new
创建两个对象,然后在其上调用get
;在这种情况下,您发布尝试执行此操作的各种尝试都将失败:
stylise
/* ----- JavaScript ----- */
// The builder function
function get(selector) {
// Create a new object we'll return, backed by `get.prototype`
var obj = Object.create(get.prototype);
// Put the elements matching the selector on it
obj.elements = Array.from(document.querySelectorAll(selector));
// Return it
return obj;
}
// Add `stylise` to the prototype `get` assigns objects
get.prototype.stylise = function(object) {
// Get our elements, so we don't have to worry about `this` in the callbacks below
var elements = this.elements;
// Style them
Object.keys(object).forEach(function(propertyName) {
elements.forEach(function(element) {
element.style[propertyName] = object[propertyName];
});
});
};
// Using it
var t1 = get("#text1");
var t2 = get("#text2");
t1.stylise({
backgroundColor: "yellow",
borderRadius: "5px"
});
t2.stylise({
backgroundColor: "green",
borderRadius: "10px"
});
旁注:函数声明后面不需要<!----- HTML ----->
<input id="text1" type="text" style="padding: .5em .7em;" />
<input id="text2" type="text" style="padding: .5em .7em;" />
(虽然把它放在那里是无害的)。 ;
用于终止语句。声明不是声明。