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

时间:2017-07-06 20:27:28

标签: javascript json ajax

所以我创建了一个在AJAX请求成功时启动的函数(onSuccess)。问题是我的功能在浏览器加载时启动,我只想在单击id为myButton的按钮时调用该函数。我正在使用document.getElementById("myButton");找到我的按钮,但是当我在浏览器控制台中运行console.log(document.getElementById("myButton"));时,我得到一个Null结果。

我环顾四周并得到一些建议,说明当我的脚本运行时,我的元素不在DOM中。我可以理解,但当我移动脚本的位置并移动document.getElementById...我的脚本仍然无法正常工作。我在Stackoverflow上查看了一些建议,但它们主要是JQuery解决方案。我正在寻找一个纯JavaScript解决方案。我的代码在

之下

JSFiddle Example

            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);
            };

3 个答案:

答案 0 :(得分:3)

你在这里犯了一点错误,但我想我知道你需要做什么。

您希望将函数引用传递给onclick属性,而是执行该函数并将onclick设置为该函数返回的任何内容。

这就是浏览器加载时您的函数正在运行的原因。你需要传递参考;不执行它并传递函数的输出。

那么你如何解决呢?

在函数式编程中有一种很酷的做法叫做Currying Functions。它在这种情况下非常有用,当你需要传递一些参数但是你想延迟执行时。在这种情况下,您可以执行以下操作:

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

然后,将按钮设置为等于buildAddUser ..

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

这会将onclick属性设置为等于调用addUser函数的函数。

为什么不使用匿名函数?

我更喜欢将这些内容包装在命名函数中,以使代码更易于阅读。遍布各处的匿名函数可能让事情变得混乱。

额外阅读

Javascript中的函数式编程是最令人兴奋的新开发之一,并提供了大量工具来帮助解决这样的问题。您应该阅读some of the material available

答案 1 :(得分:2)

出现问题的是,当您尝试设置onClick侦听器时,您正在调用addUser。试试这个。



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>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

创建包装函数的匿名函数调用

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

有关详细说明,请参阅here