带有JQuery的javascript模块导致模块函数未定义

时间:2016-07-10 08:13:31

标签: javascript jquery

我试图创建一个名为ScrollToAnchor的模块,其中包含一个名为goToTarget的函数,我可以像ScrollToAnchor.goToTarget(target);一样调用

然而它说

  

ScrollToAnchor.goToTarget不是函数

我认为ScrollToAnchor属于jQuery类型,因为$我是如何拥有它的。这是代码:

var ScrollToAnchor = $(function() {
  var headerHeight = 70;

  $('a[href*="#"]:not([href="#"])').click(function() {
    if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
      if (goToTarget(this.hash))
        return false;
    }
  });

  /*$('input[data-target]').click(function() {
          if (gotoTarget($(this).data("target")))
          return false;
  })*/

  var goToTarget = function(targetName) {
    var target = $(targetName);
    target = target.length ? target : $('[name="' + targetName.slice(1) + '"]');
    if (target.length) {
      $('html,body').animate({
        scrollTop: target.offset().top - headerHeight
      }, 1000);

      return true;
    }
    return false;
  }

  return {
    goToTarget: goToTarget
  }
});

我做错了什么?如果我从$中移除var ScrollToAnchor = $(function () {,那么ScrollToAnchor中的jQuery就不起作用了。

但如果我离开$那么它会认为ScrollToAnchor是jQuery类型而ScrollToAnchor.goToTarget不是函数。

2 个答案:

答案 0 :(得分:1)

将ScrollToAnchor变为普通功能。此功能将在全球范围内:

window.ScrollToAnchorFactory = function () {
    var headerHeight = 70;
    $('a[href*="#"]:not([href="#"])').click(function () {
        if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
            if (goToTarget(this.hash))
                return false;
        }
    });

    /*$('input[data-target]').click(function() {
            if (gotoTarget($(this).data("target")))
            return false;
    })*/

        var goToTarget = function (targetName) {
            var target = $(targetName);
            target = target.length ? target : $('[name="' + targetName.slice(1) + '"]');
            if (target.length) {
                $('html,body').animate({
                    scrollTop: target.offset().top - headerHeight
                }, 1000);

                return true;
            }   

            return false;
        }

    return {
        goToTarget: goToTarget
    }
};

如果您想使用此代码创建commonJS模块,也可以使用module.export而不是将其放在全局范围内。这将允许您将()它需要()到其他文件中(使用Browserify进行编译)。

如果您决定将ScrollToAnchorFactory保留在全局范围内,无论您何时需要使用scrollToAnchor.goToTarget(在同一个文件中或不同的文件中)......

$(function() {
    var scrollToAnchor = window.ScrollToAnchorFactory();
    // you can now use scrollToAnchor.goToTarget(target)
});

您希望jQuery的DOM就绪函数包含在此部分中,以便ScrollToAnchorFactory在您的锚点在DOM中完全形成之前不会尝试初始化。

答案 1 :(得分:1)

$(function() {...})$( document ).ready( handler )的简写。

因此$(function() {...})的结果是一个包含document元素的jQuery结果集。

您正在寻找活动授权:

$(document).on('click', 'a[href*="#"]:not([href="#"])', function() {
  if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
    if (goToTarget(this.hash))
      return false;
  }
});

这将确保click事件将用于所有a元素,无论它们何时被添加到DOM并允许您在全球范围内使用goToTarget范围很简单。您的最终代码将以这种方式显示:

var ScrollToAnchor = (function() {
  var headerHeight = 70;

  // event handler with delegation
  $(document).on('click', 'a[href*="#"]:not([href="#"])', function() {
    if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
      if (goToTarget(this.hash))
        return false;
    }
  });

  function goToTarget(targetName) {
    var target = $(targetName);
    target = target.length ? target : $('[name="' + targetName.slice(1) + '"]');
    if (target.length) {
      $('html,body').animate({
        scrollTop: target.offset().top - headerHeight
      }, 1000);

      return true;
    }

    return false;
  }

  return {
    goToTarget: goToTarget
  }

}());

使用事件委派,无需将整个代码包装到$(function() {...})中,并且ScrollToAnchor是公开可用的。