简体   繁体   中英

Not able to call a javascript function using onclick event

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Getting Started With PubNub</title>
  </head>
  <body>

    HotelName: <input type="text" id="rname"/> <br/>
    <input type = "button" value = "Submit" onclick = "publish()"/>

    <script src="https://cdn.pubnub.com/pubnub.min.js"></script>
    <script charset="utf-8">
      (function(){

        var PUBNUB_demo = PUBNUB.init({
          publish_key: 'demo',
          subscribe_key: 'demo'
        });

        PUBNUB_demo.subscribe({
          channel: 'b',
          message: function(m){console.log(m)},
          connect : publish
        });

        function publish() {
          var hn = document.getElementById('rname').value
          var hname = JSON.stringify(hn);
          PUBNUB_demo.publish({
            channel: 'a',
            message: {"text":hn}
          });
        }

      })();

    </script>

  </body>
</html>

In this the onclick='publish()' is not getting executed. The error shown is Uncaught ReferenceError: publish is not defined . Although I have already defined the publish function. The publish function should get the value of the text box and add it the JSON that I am sending to the publish function.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Getting Started With PubNub</title>
  </head>
  <body>
    <script src="https://cdn.pubnub.com/pubnub.min.js"></script>
    <script charset="utf-8">


        var PUBNUB_demo = PUBNUB.init({
          publish_key: 'demo',
          subscribe_key: 'demo'
        });

        PUBNUB_demo.subscribe({
          channel: 'b',
          message: function(m){console.log(m)},
          connect : publish
        });

        function publish(hn) {
          hnaam = JSON.stringify(hn);
          PUBNUB_demo.publish({
            channel: 'a',
            message: {"text":hnaam}
          });

        }

        function getName(){
          var hname= document.getElementById("rname").value;
          document.getElementById("printname").innerHTML = hname;
          publish(hname);
        }



    </script>
    <br/>
    <span id ='printname'></span>
    <br/>
    <input type ="text" id="rname"/><br>
    <input type ="button" value="Submit" onclick="getName()"/>



  </body>
</html>

Your publish() function is not working because it is not available in the global context as you're attempting to access it. Because your named functions are defined within a self-invoked function, they are also destroyed by the time your runtime is finished. By the time you click your button, your code has finished running and the context of your self-invoked function is no longer accessible.

It looks like the reason you're using an IIFE is because you don't want to pollute the global context, and while your motivations are right, you are not properly exposing your functions to the DOM.

The Quick Solution

You could simply remove your code from inside your self-invoked function:

    var PUBNUB_demo = PUBNUB.init({
      publish_key: 'demo',
      subscribe_key: 'demo'
    });

    PUBNUB_demo.subscribe({
      channel: 'b',
      message: function(m){console.log(m)},
      connect : publish
    });

    function publish() {
      var hn = document.getElementById('rname').value
      var hname = JSON.stringify(hn);
      PUBNUB_demo.publish({
        channel: 'a',
        message: {"text":hn}
      });
    }

The Modular Approach

You'll want to write modular code. There are many different methods to do this, but the quickest and most vanilla way is called the Revealing Module Pattern.

Because we don't want to pollute the global namespace, but still need to access our code, we'll create global variables called Modules, and we'll choose which functions get exposed

  var MyModule = (function(){

    var PUBNUB_demo = PUBNUB.init({
      publish_key: 'demo',
      subscribe_key: 'demo'
    });

    PUBNUB_demo.subscribe({
      channel: 'b',
      message: function(m){console.log(m)},
      connect : publish
    });

    function publish() {
      var hn = document.getElementById('rname').value
      var hname = JSON.stringify(hn);
      PUBNUB_demo.publish({
        channel: 'a',
        message: {"text":hn}
      });
    }

    return {
      publish: publish()
    }

  })();

Now, in your HTML you should be able to call the following function inside your onclick attribute:

MyModule.publish()

The problem is that you have your functions in ()... just get out those functions and the problem is out.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <script src="https://cdn.pubnub.com/pubnub.min.js"></script>
    <title>Getting Started With PubNub</title>
  </head>
  <body>
    HotelName: <input type="text" id="rname"/> <br/>
    <input type = "button" value = "Submit" onclick = "publish()"/>    
    <script charset="utf-8">
        var PUBNUB_demo = PUBNUB.init({
          publish_key: 'demo',
          subscribe_key: 'demo'
        });

        PUBNUB_demo.subscribe({
          channel: 'b',
          message: function(m){console.log(m)},
          connect : publish
        });

        function publish() {
          var hn = document.getElementById('rname').value
          var hname = JSON.stringify(hn);
          PUBNUB_demo.publish({
            channel: 'a',
            message: {"text":hn}
          });
        }
    </script>
  </body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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