如果函数名称在字符串中,我如何 JavaScript 向 "onClick" 事件添加值?

How can I JavaScript add a value to the "onClick" event if the function name is in a string?

此问题已解决

注:解题后的解答和我进行的测评,大家可以看一下问题的解答

我正在尝试创建一个小的 JavaScript 脚本来解决用户的一些需求(UserLand 脚本)。

操作非常简单,为了尽可能简单,我需要在DOM中添加一些元素,有CSS、文本、函数等

这样脚本就知道要创建什么元素、要应用什么 CSS、什么文本等。我​​创建了一个具有以下形式的对象:

    options: {
      /* Button */
      'button': {
        'tagName'   : 'button',
        'innerHTML' : 'X',
        'css'       : {
          'position'          : 'fixed',
          'z-index'           : '9999999',
          'bottom'            : '20px',
          'left'              : '20px',
          'background-color'  : 'black',
          'cursor'            : 'pointer',
          'color'             : 'white',
          'width'             : '60px',
          'height'            : '60px',
          'border'            : 'none',
          'border-radius'     : '50%',
          'font-weight'       : 'bold',
          'font-size'         : '1.5rem'
        },
        'onClick'   : 'objectName.method()'
      }
    }

我的脚本通过循环执行以下代码:

    createElement: (element) => {
      
      /* Create element */
      const createElement = document.createElement( element.tagName );
      /* Add innerHTML */
      createElement.innerHTML = element.innerHTML;
      /* Add CSS */
      objectName.addCSStoElement( createElement, element.css );
      /* Add onClick event*/
      createElement.addEventListener( 'click', element.onClick, false );
      /* Add to DOM */
      document.body.appendChild ( createElement );

    }

一切正常,除了指令:

createElement.addEventListener( 'click', element.onClick, false );

我猜是因为它是一个字符串,这就是它被 JS 附加到“onClick”事件的方式。

假设我没记错的话,我该如何添加函数的名称,以便在单击创建的元素时可以执行它?

我希望我表达得很好,我糟糕的英语不会导致混乱。

感谢您的宝贵时间和帮助,向大家问好!

此致, 亚历克斯

解决方案:

我发现我在暴露问题时提供的信息并不完整,例如,我没有指出它是全局对象还是本地对象,我非常抱歉。

它是一个本地对象t,在这种情况下,它是可以信任的代码,因为它是可以信任的代码我自己在浏览器中注入 每次它进入一个网站,目的是在某些任务中支持我。

考虑到这一点,我们可以继续,如果无论如何这不是你的情况,请考虑同事在他们的答案中添加的信息,它们非常有趣和重要。

我必须做出的改变是: 首先,在“options”中修改“onClick”的值如下:

'onClick'   : '(function(){objectName.method();})'

最后我修改了事件添加到HTML元素的方式如下:

createElement.addEventListener( 'click',eval(element.onClick), false );

并且,通过这些简单的更改,我设法解决并理解了问题所在!

非常感谢所有回复并给予我帮助和时间的人,祝你一切顺利!

由于您具体询问有关使用字符串为字符串创建 HTML 事件处理程序的问题,并且你 知道 你可以信任字符串的内容(它没有恶意内容),你可以使用 setAttribute:

createElement.setAttribute("onclick", element.onClick);

实例:

const objectName = {
    method() {
        console.log("objectName.method() called");
    }
};

const btn = document.createElement("button");
btn.textContent = "Click Me";
const onClick = "objectName.method()";
btn.setAttribute("onclick", onClick);
document.body.appendChild(btn);

请注意 objectName 必须是全局变量,而不是执行此操作的代码的局部变量。


或者,您可以按照 this question's answers show 的方式进行操作,我在意识到我应该寻找副本之前写在下面(现在根据评论取消了 dupehammered):

由于您可以信任包含该代码的字符串的来源,因此您可以使用 new Function 创建一个使用该代码作为其主体的函数:

createElement.addEventListener( 'click', new Function(element.onClick), false );

不要使用您不信任的字符串。

请注意,代码引用的任何变量都必须是全局变量。

实例:

const objectName = {
    method() {
        console.log("objectName.method() called");
    }
};

const btn = document.createElement("button");
btn.textContent = "Click Me";
const onClick = "objectName.method()";
btn.addEventListener("click", new Function(onClick), false);
document.body.appendChild(btn);

如果你需要引用本地变量,你可以使用eval(再次强调:不要如果你不能相信文本的来源!你 evaling!):

createElement.addEventListener( 'click', eval("(function() { " + element.onClick + "})"), false );

实例:

{ // A block so the code isn't at global scope
    const objectName = {
        method() {
            console.log("objectName.method() called");
        }
    };

    const btn = document.createElement("button");
    btn.textContent = "Click Me";
    const onClick = "objectName.method()";
    btn.addEventListener("click", eval("(function() { " + onClick + "})"), false);
    document.body.appendChild(btn);
}

我已经复制了您的示例并进行了必要的修改,它现在可以正常工作了。单击按钮时调用函数。

<html>
    <head><title>Example for string as function call</title></head>
    <body>
        <script type="text/javascript">
            let options = {
            /* Button */
            'button': {
                'tagName'   : 'button',
                'innerHTML' : 'X',
                'css'       : {
                    'position'          : 'fixed',
                    'z-index'           : '9999999',
                    'bottom'            : '20px',
                    'left'              : '20px',
                    'background-color'  : 'black',
                    'cursor'            : 'pointer',
                    'color'             : 'white',
                    'width'             : '60px',
                    'height'            : '60px',
                    'border'            : 'none',
                    'border-radius'     : '50%',
                    'font-weight'       : 'bold',
                    'font-size'         : '1.5rem'
                },
                //check how onClick method is changed
                'onClick'   : '(function(){console.log("hello");objectName.method();})'
            }
            };
            
            function createElement(element) {
                /* Create element */
                const createElement = document.createElement( element.tagName );
                /* Add innerHTML */
                createElement.innerHTML = element.innerHTML;
                /* Add CSS */
                objectName.addCSStoElement( createElement, element.css );
                /* Add onClick event*/
                //check how I am passing eval(element.onClick) instead of just element.onClick
                createElement.addEventListener( 'click',eval(element.onClick), false );
                /* Add to DOM */
                document.body.appendChild ( createElement );
            }

            createElement(options['button']);
        </script>
    </body>
</html>

As T.J. Crowder has pointed out: please make sure that objectName is a global variable

您可以通过添加 onclick 属性并传递用于调用配置对象中提供的方法的代码字符串来为按钮添加点击处理程序。

下面的示例将 event 对象添加为调用参数,因此该方法可以查看 event.targetevent.currentTarget 以获取有关单击内容的更多信息。

使用按钮并省略所有其他配置细节的示例:

// dummy object for testing:
const object = {
   name: {
      method: function(event) {
         alert(`You clicked '${event.target.textContent}'`)
      }
   }
}

// Create a button and add an "onclick" attribute set to a code string.
// This example adds the click event object as an argument for the method call


const button = document.createElement("button");
button.textContent = "click me";
button.setAttribute("onclick", "object.name.method(event)");
document.body.appendChild(button);

这是通过让 HTML 解析器将代码字符串转换为函数对象来实现的,该函数对象通过单击 event 对象作为其参数来调用,就像将 [= HTML 源中的 11=] 属性。

切勿使用不受信任的代码执行此操作,但我假设配置数据来自应用程序代码,而不是来自用户或未经验证的输入。

设置属性不适合将多个事件处理程序添加到单个元素,但它会在内部创建一个函数来执行作为属性值提供的代码(字符串),并为您调用 addEventListener