简体   繁体   中英

Defining Javascript/JQuery functions

What is the proper way of defining javascript functions, inside

$(document).ready(function () {
});

or just outside.

What I have is this :

$(function() {
  var html = '<div class ="new1" ><img id = "new2" onclick = "showPage(' + id + 
      ');" class = "' + id + 
      '" src="@Url.Content("~/Images/blankpageQ.jpg")" />' + 
      i + '</div>');
  $(".pageListQuiz")
    .children('div')
    .eq(numOfPages - 1)
    .append(html);

  function showPage() {
    //some actions
  }
});

and clicking on the appended image throws an exception :

Unhandled exception at line 3, column 1 in script block

0x800a1391 - JavaScript runtime error: 'showPage' is undefined

If there is a handler for this exception, the program may be safely continued.

(The js code is embedded from my c# code.). Everything works fine if I place showPage() outside anyway. I just wonder why its not working when I put it inside because I also have functions placed inside that are just working fine.

Function delarations are scoped just like var statements.

If you define a function inside another function, then you can only access it within the scope of that function.

If you want to access it as a global (which is what an intrinsic event attribute like onclick= does), then you either need to define it as a global or copy it into the global scope.

In this case, however, you should avoid using globals. You should also avoid using intrinsic event attributes and building HTML by mashing together strings.

This is untested but should give you the idea.

$(function () {

  var id = "something";
  var numOfPages = 2;

  var html = $("<div/>")
    .addClass("new1")
    .append(
      $("<img/>")
        .attr("id", "new2")
        .on("click", showPage.bind(null, id))
        .addClass(id)
        .attr("src", '@Url.Content("~/Images/blankpageQ.jpg")')
    );
  $(".pageListQuiz")
    .children('div')
    .eq(numOfPages - 1)
    .append(html);

  function showPage(id) { 
  }

});

@Tushar's Approach

Idea: Create functions and use $(document).ready() to execute necessary functions.

JSFiddle

$(document).ready(function(){
    ...
})

function showPage(el){
  console.log(el);
}

My Approach

Idea: You can have a event handler, instead of setting onclick attribute. Benefit of this approach is, you can have your markup generation logic clean.

JSFiddle


Note, you can merge both approaches. Its better to declare all functions and then use $(document).ready() as an initialization function. This will just call different functions. If you choose to use event handlers/delegates , you can export all events to different file as well and just call it.

In your example, you create an <img> element in the HTML of the page. When it is clicked, showPage() is called. Since the function is called from the global scope (as it is called from a click on the HTML, which goes into the global scope), the global scope is looked up for the existence of the showPage() function. However, it does not exist inside the global scope; it exists only in the scope of your $(function() {}) function.

If you want to access showPage() from the global scope, you need to make sure it is available there. You can either do that by defining it outside your $(function() {}) construction (a function declaration creates a new scope), or by defining a var outside your $(function() {}) construction and assigning the showPage() function to that var. For example:

var showPage;

$(function() {
    // Assign the function showPage() to the var showPage:
    showPage = function showPage() {
        // You function body.
    }
});

// showPage is now available in the global scope.

Either solution is OK. Maybe you could read up a bit on Javascript scopes and closures . That will help you understand what's happening here.

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