简体   繁体   English

当加载浏览器时,如何阻止JavasScript函数启动?

[英]How do I prevent a JavasScript function from launching when the browser loads?

So I created a function (onSuccess) that launches when an AJAX request is successful. 因此,我创建了一个函数(onSuccess),该函数在AJAX请求成功时启动。 The problem is that my function launches when my browser loads and I would only like for the function only to be called when a button with id myButton is clicked. 问题是我的函数在加载浏览器时启动,并且我只希望单击ID为myButton的按钮时才能调用该函数。 I am locating my button using document.getElementById("myButton"); 我正在使用document.getElementById("myButton");找到我的按钮 but when I run console.log(document.getElementById("myButton")); 但是当我运行console.log(document.getElementById("myButton")); in my browser console I get a Null result. 在我的浏览器控制台中,我得到一个Null结果。

I've looked around and gotten a few suggestions stating that my element wasn't in the DOM when my script ran. 我环顾四周,得到了一些建议,说明脚本运行时我的元素不在DOM中。 I can understand that but when I moved the location of my script and moved the document.getElementById... my script still doesn't work. 我可以理解,但是当我移动脚本的位置并移动document.getElementById...我的脚本仍然不起作用。 I viewed a few suggestions on Stackoverflow but they were mostly JQuery solutions. 我查看了一些关于Stackoverflow的建议,但大多数都是JQuery解决方案。 I'm looking for a pure JavaScript solution. 我正在寻找一个纯JavaScript解决方案。 My code is below 我的代码如下

JSFiddle Example JSFiddle示例

            var el = document.getElementById("myButton");
            el.onclick = addUser("username", "email", onSuccess);

            function onSuccess(result){
               alert ('successful');
            }



            // Do not modify this function. Add user service wrapper.
            function addUser(username, email, callback) {
                var xhr = new XMLHttpRequest();
                var response;
                var success = (!!Math.round(Math.random()));

                if (!success){
                    response = JSON.stringify({
                        success: success,
                        error: "Oups, something went wrong!"
                    });
                } else {
                    response = JSON.stringify({
                        success: success,
                        user: {
                            username: username,
                            email: email
                        }
                    });   
                }

                xhr.open("POST", "/echo/json/");
                xhr.onload = function () {
                        if (xhr.status === 200) {
                            callback(JSON.parse(xhr.responseText));
                    }
                }
                xhr.send("json=" + response);
            };

You've gone a little wrong here, but I think I know what you need to do. 您在这里出错了,但是我想我知道您需要做什么。

You want to pass a function reference to the onclick attribute, but instead you're executing the function and setting onclick to be whatever that function returns. 将函数引用传递给onclick属性,但是您要执行该函数并将onclick设置为该函数返回的值。

This is why your function is running when the browser loads. 这就是为什么在加载浏览器时运行您的函数的原因。 You need to pass the reference; 您需要通过参考; not execute it and pass the output of the function. 不执行它并传递函数的输出。

So how do you solve it? 那么您如何解决呢?

There is a cool practice in functional programming called Currying Functions . 函数编程中有一种很酷的实践,称为Currying Functions It's very useful in situations like this, when you need to pass in some parameters but you want to delay execution. 在需要传递一些参数但想要延迟执行的情况下,这种方法非常有用。 In this case, you could do something like this: 在这种情况下,您可以执行以下操作:

function buildAddUser(username, email, callback) { 
    return function() {
        addUser(username, email, callback)
    }
}

Then, you set your button to be equal to the output of buildAddUser .. 然后,将按钮设置为等于buildAddUser的输出。

el.onclick = buildAddUser("username", "email", onSuccess);

This will set the onclick attribute to be equal to a function that invokes the addUser function. 这会将onclick属性设置为等于调用addUser函数的函数。

Why not just use an anonymous function? 为什么不只使用匿名功能?

I prefer to wrap these things in named functions, to make your code easier to read. 我更喜欢将这些东西包装在命名函数中,以使您的代码更易于阅读。 Anonymous functions flying all over the place can make things confusing. 到处都是匿名函数会使事情变得混乱。

Extra Reading 额外阅读

Functional Programming in Javascript is one of the most exciting new developments and offers a wide array of tools to help solve problems just like this. Java语言中的函数式编程是最令人兴奋的新开发之一,它提供了各种各样的工具来帮助解决此类问题。 You should have a read through some of the material available 您应该通读一些可用的材料

The thing that is going wrong is that you are calling addUser when you try to set the onClick listener. 出问题的是,当您尝试设置onClick侦听器时,您正在调用addUser。 Try this instead. 试试这个吧。

 var el = document.getElementById("myButton"); el.onclick = function() { var username = document.getElementById("username").value; var email = document.getElementById("email").value addUser(username, email, onSuccess) } function onSuccess(result){ alert ('successful'); } // Do not modify this function. Add user service wrapper. function addUser(username, email, callback) { var xhr = new XMLHttpRequest(); var response; var success = (!!Math.round(Math.random())); if (!success){ response = JSON.stringify({ success: success, error: "Oups, something went wrong!" }); } else { response = JSON.stringify({ success: success, user: { username: username, email: email } }); } xhr.open("POST", "/echo/json/"); xhr.onload = function () { if (xhr.status === 200) { callback(JSON.parse(xhr.responseText)); } } xhr.send("json=" + response); }; 
 <h2>Add a User:</h2> <input id="username" type="text" name="username" placeholder="name"> <input id="email" type="email" name="email" placeholder="email"> <button id="myButton">add user</button> <h2>Users:</h2> <ul id="users"></ul> 

Create anonymous function call which wraps the function 创建包装函数的匿名函数调用

el.onclick = function() { addUser("username", "email", onSuccess); };

For more detailed explanation you can refer here 有关更详细的解释,您可以在这里参考

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

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