admin管理员组

文章数量:1417664

I'm having issues with onclick, specifically the onclick="Foo()" seen in the code below. When clicked, I'm getting undefined, yet I have included the function at the top and even out of the function.

$( document ).ready(function() {
    function Foo() {
        console.log('clicky click click');
        document.getElementById('categoryBubble').style.display = 'none';
    }
    $('.mutliSelect select').on('change', function() {
        var title = $(this).closest('.mutliSelect').find('option').val();
        title = $(this).val() + "";
        if ($(this).is(':selected')) {
            // the code for if goes here
        } else {
            console.log('im working here #2');
            var html = '<span id="categoryBubble" title="' + title + '">' + title + '</span>' + '<span onclick="Foo()" class="Xout">x</span>';
            $('.multiSel').append(html);
            $(".hida").hide();
        }
    });
});

I'm having issues with onclick, specifically the onclick="Foo()" seen in the code below. When clicked, I'm getting undefined, yet I have included the function at the top and even out of the function.

$( document ).ready(function() {
    function Foo() {
        console.log('clicky click click');
        document.getElementById('categoryBubble').style.display = 'none';
    }
    $('.mutliSelect select').on('change', function() {
        var title = $(this).closest('.mutliSelect').find('option').val();
        title = $(this).val() + "";
        if ($(this).is(':selected')) {
            // the code for if goes here
        } else {
            console.log('im working here #2');
            var html = '<span id="categoryBubble" title="' + title + '">' + title + '</span>' + '<span onclick="Foo()" class="Xout">x</span>';
            $('.multiSel').append(html);
            $(".hida").hide();
        }
    });
});
Share Improve this question edited Jan 22, 2019 at 21:46 gaetanoM 42.1k6 gold badges44 silver badges63 bronze badges asked Jan 22, 2019 at 21:33 droidnoobdroidnoob 3355 silver badges17 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

Foo() (which isn't a constructor function so it shouldn't be named starting with a capital letter) is locally scoped to the anonymous function you pass to ready.

Then the onclick event handler goes looking for something called Foo, it can't find it because it isn't in the right scope.

Don't use intrinsic event attributes, they have all sorts of nasty issues, one of which is that you're pretty much forced to use globals with them.

Generate your HTML with jQuery functions instead of mashing strings together. Bind your event handler with the jQuery on method and not an onclick attribute.

$(function() {
  function foo() {
    console.log("clicky click click");
    document.getElementById("categoryBubble").style.display = "none";
  }

  $(".mutliSelect select").on("change", function() {
    var title = $(this)
      .closest(".mutliSelect")
      .find("option")
      .val();

    title = $(this).val() + "";

    if ($(this).is(":selected")) {
      // the code for if goes here
    } else {
      console.log("im working here #2");

      var span = $("<span />")
        .attr("id", "categoryBubble")
        .attr("title", title)
        .text(title);

      var other_span = $("<span />")
        .on("click", foo)
        .addClass("Xout")
        .text("x");

      $(".multiSel").append(span);
      $(".multiSel").append(other_span);

      $(".hida").hide();
    }
  });
});

Your foo is defined inside the document).ready - it's not on the top level, so when the inline handler tries to find a global function named Foo to call, it fails.

Either put Foo outside:

function Foo() {
  console.log('clicky click click');
  document.getElementById('categoryBubble').style.display = 'none';
}

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

Or, even better, avoid inline handlers entirely, and attach the listener properly using Javascript instead, allowing you to reference other variables and functions inside the current scope:

const span1 = $('<span></span>')
  .prop({
    id: 'categoryBubble',
    title
  })
  .text(title);
const span2 = $('<span></span>')
  .prop('class', 'xOut')
  .on('click', Foo);
$('.multiSel').append(span, span2);

Also note that, in modern versions of jQuery, rather than $( document ).ready(), you can use

$(() => {
  // code here

instead. In addition, having multiple IDs in a single document is invalid HTML; appending

<span id="categoryBubble" 

multiple times (if that's a possibility, given other code you may have) will not be valid. Consider using a class instead.

<span class="categoryBubble"

If you do indeed want to append a span multiple times, and you want clicking on the created span to remove the categoryBubble associated with that span, then the ID selector won't work - instead, you can reference the span created earlier in the closure, and hide it:

const span2 = $('<span></span>')
  .prop('class', 'xOut')
  .on('click', () => {
    span1.hide();
  });

本文标签: javascriptjQuery onClick UndefinedStack Overflow