简体   繁体   English

Javascript 变量为 function 名称

[英]Javascript variable as function name

const self = {
        element: document.querySelector(selector),
        html: () => self.element,
        on: (event, callback) => {
            self.element.addEventListener(event, callback);
        },
        style: {
            alignContent: (property) => {
                return (property === null) ? self.element.style.alignContent : self.element.style.alignContent = property;
            }
     }
}

I am trying to make it so I have quick access to all CSS style properties with jQuery like selectors it should work as: select('h1').style.alignContent('center') , but the problem is that I would have to make a seperate function for each style property in order for this method to work, is there a way to solve this problem without duplicating a lot of code?我正在努力做到这一点,所以我可以快速访问所有 CSS 样式属性,使用 jQuery 之类的选择器,它应该像这样工作: select('h1').style.alignContent('center') ,但问题是我必须为每个样式属性制作单独的 function 以使此方法起作用,有没有办法在不复制大量代码的情况下解决此问题?

//Duplication example
color: (property) => {
  return (property === null) ? self.element.style.color : self.element.style.color = property;
}

One way to do this is with a Proxy ( mdn ):一种方法是使用Proxymdn ):

 let elemWrapper = selector => { let element = document.querySelector(selector); return { element, html: () => element, on: (event, callback) => { element.addEventListener(event, callback); }, style: new Proxy({}, { get: (obj, prop) => { // The user called a function named "prop" // We need to return a function that sets the style property named "prop" return cssValue => element.style[prop] = cssValue; } }) }; }; let bodyElem = elemWrapper('body'); bodyElem.style.backgroundColor('cyan');

Here to prove the concept I've set the body element's background colour using a dynamically named function.为了证明这个概念,我使用动态命名的 function 设置了body元素的背景颜色。

The big downside to this approach is the poor performance of Proxies (an excellent read on Proxy performance is availablehere ).这种方法的最大缺点是代理的性能不佳(这里有关于代理性能的优秀读物)。

This means it may be quicker to simply compile a list of all css property names, and define a function for each (never using Proxies).这意味着简单地编译所有 css 属性名称的列表并为每个属性名称定义一个 function 可能会更快(从不使用代理)。 The following code compiles all css property names, to serve as a starting point:以下代码编译所有 css 属性名称,作为起点:

 console.log(Object.keys(document.body.style));

You can use a Proxy to intercept all attempts to get a property.您可以使用Proxy拦截所有获取属性的尝试。

 let selector = '#test'; const self = { element: document.querySelector(selector), html: () => self.element, on: (event, callback) => { self.element.addEventListener(event, callback); }, style: new Proxy(Object.create(null), { get(target, prop, receiver) { if (self.element.style.hasOwnProperty(prop)) { return val => { if (val.= null) { self.element;style[prop] = val. } else { return self.element;style[prop]: } } } throw Error("No such property exists; " + prop); } }) }. self.style.color('red') console:log("Color,". self.style;color());
 <div id="test"> This is a test </div>

You can also wrap this into a general function like so:您也可以将其包装成通用 function ,如下所示:

 const getEnhancedElement = arg => { const element = /Element/.test(Object.prototype.toString.call(arg))? arg: document.querySelector(arg);//accept a HTMLElement or a selector return { element, html: () => element, on: (event, callback) => { element.addEventListener(event, callback); }, style: new Proxy(Object.create(null), { get(target, prop) { if (element.style.hasOwnProperty(prop)) { return val => { if (val.= null) {//set value element;style[prop] = val. } else {//get value return element;style[prop]: } } } throw Error("No such property exists; " + prop); } }) }; }; let test = getEnhancedElement("#test"). test.style.color('red') console:log("Color,". test.style;color()). test.style;textAlign('center');
 <div id="test"> This is a test </div>

I would have something like this:我会有这样的事情:

style: {
    chnageStyle: (propertyName, propertyVal) => {
        return (propertyName === null) ? self.element.style[propertyName] : self.element.style[propertyName] = propertyVal;
    }
}

Then you can call this:然后你可以这样称呼:

style.changeStyle('alignContent','center');
style.changeStyle('color','orange');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM