【问题标题】:Difference between init events in js file or html templatejs文件或html模板中init事件的区别
【发布时间】:2016-03-19 01:19:07
【问题描述】:

在页面加载后声明的同一个 JS 文件或 html 模板中的 lauch js 函数之间有区别吗?当双方都登录$(document).ready(function () {...})时。

我认为不是,但是在将我的 ExampleService.init() 函数从模板替换为单独的 JS 文件时遇到了问题。 例如我有这样的结构:

common.js

var ExampleService= {
    catalogSpinner: '',

    init: function() {
      this.initEvents();
    },

    initEvents: function() {
      var self = this;

      $('.example-button').on('click', function() {
          //do some logic, append spinner...
          self.removeSpinner();
      });
    },

    removeSpinner: function() {
        $(this.catalogSpinner).fadeOut('slow', function() {
            $(this).remove().css({display: 'block'});
        });
    }
}

index.html

<script src="js/common.js"></script>
<script>
  $(document).ready(function () {
      ExampleService.catalogSpinner = '<div class="spinner"></div>'; // css3 animation

      ExampleService.init();
  });
</script>

这样一切都很完美,我的 catalogSpinner 从模板中覆盖,我可以像使用 DOM 元素一样使用它们。


但是! 如果我将 ExampleService.init(); 移动到 common.js 文件,就像这样:

common.js

var ExampleService= {
    ...
    // all the same...
    ...
};

$(document).ready(function () {
    'use strict';

    ExampleService.init();
});

index.html

<script src="js/common.js"></script>
<script>
  $(document).ready(function () {
     ExampleService.catalogSpinner = '<div class="spinner"></div>';     
  });
</script>

这样就行不通了。并抛出控制台错误Uncaught TypeError: this.catalogSpinner.fadeOut is not a function

为什么会这样?毕竟在这两种情况下,init 函数仅在整个页面加载后才启动,无论我在启动基本函数后覆盖我的变量。我做错了什么?


关于 inits 的执行顺序。我怎么理解它没关系。无论如何,在点击事件发生之前,模板文件中的第二个 document.ready 总是覆盖 JS 文件中的空 catalogSpinner 变量

【问题讨论】:

  • 您是否检查过调用这些事件的顺序?在我看来,common.js 中的调用在 index.html 之前被调用。
  • 首先,你必须有有效的jQuery选择器才能使用jQuery方法..

标签: javascript jquery html oop


【解决方案1】:

几乎可以肯定是时间问题。你有什么保证 $(document).ready in common.js 将在你的 html 文件中的相同事件处理程序之后触发(根据你的实现,这是需要发生的)?

或者,您需要确保当它出现在 common.js 中时,该代码可以以某种方式检索 catalogSpinner 值。

此外,catalogSpinner 必须是有效的 jQuery 对象,而不是字符串。

【讨论】:

  • 是的,这可能就是答案。但是我的事件在点击时起作用,虽然它会发生,但第二个 document.ready 已经覆盖了catalogSpinner 变量,以获得正确的值。 P.S 是的,对不起类型,我已经有了让他们纠正 jQuery 对象的功能。
【解决方案2】:

在这两种情况下都会而且确实有效。要在 DOM 元素上使用 jQuery 方法,您必须具有有效的 jQuery 选择器,它将返回与 jQuery 方法绑定的对象。

试试这个:

案例 1:

common.js

var ExampleService= {
  catalogSpinner: '',

  init: function() {
    this.initEvents();
  },

  initEvents: function() {
    var self = this;

    $('.example-button').on('click', function() {
      //do some logic, append spinner...
      self.removeSpinner();
    });
  },

  removeSpinner: function() {
    this.catalogSpinner.fadeOut('slow', function() {
      $(this).remove().css({display: 'block'});
    });
  }
};

index.html

<!doctype html>
<html>
<head>
  <script src="jquery.min.js"></script>
  <script src="common.js"></script>
  <style>
  </style>
</head>
<body>
<div class="spinner">Spinner</div>
<button type="button" class="example-button">Remove</button>
<script type="text/javascript">
  $(document).ready(function () {
    ExampleService.catalogSpinner = $('.spinner');
    ExampleService.init();
  });
</script>
</body>
</html>

案例 2:

common.js

var ExampleService = {
  catalogSpinner: '',

  init: function () {
    this.initEvents();
  },

  initEvents: function () {
    var self = this;

    $('.example-button').on('click', function () {
      //do some logic, append spinner...
      self.removeSpinner();
    });
  },

  removeSpinner: function () {
    this.catalogSpinner.fadeOut('slow', function () {
      $(this).remove().css({display: 'block'});
    });
  }
};

$(document).ready(function () {
  'use strict';
  ExampleService.init();
});

index.html

<!doctype html>
<html>
<head>
  <script src="jquery.min.js"></script>
  <script src="common.js"></script>
  <style>
  </style>
</head>
<body>
<div class="spinner">Spinner</div>
<button type="button" class="example-button">Remove</button>
<script type="text/javascript">
  $(document).ready(function () {
    ExampleService.catalogSpinner = $('.spinner');
  });
</script>
</body>
</html>

【讨论】:

  • 谢谢,但这种方式不适合我。我也可以直接在 JS 文件 catalogSpinner: '&lt;div class="spinner"&gt;&lt;/div&gt;', 中设置 catalogSpinner,它会起作用。但我很好奇为什么上面描述的例子不起作用。无论如何,模板中的第二个 document.ready 必须在点击事件之前覆盖变量。
  • 是的,您也可以在 JS 中使用 catalogSpinner: '&lt;div class="spinner"&gt;&lt;/div&gt;',,但是在选择它时,您必须使用 $('.spinner') 作为选择器。试试这个方法。
  • 但我不想在我的模板中渲染元素,只能直接设置为变量。 :( 我知道我可以从模板中选择它们并使用,但我不想这样做,只能直接设置为变量。
  • 是的,当然你可以这样做,但在ExampleService.catalogSpinner = $('.spinner'); 时,该元素应该存在于 DOM 中,还请注意ExampleService.catalogSpinner = $('.spinner'); 必须用于选择该元素而不是ExampleService.catalogSpinner = '&lt;div class="spinner"&gt;&lt;/div&gt;';如果您不想在模板中使用它,请使用ExampleService.catalogSpinner = $('&lt;div class="spinner"&gt;&lt;/div&gt;');
猜你喜欢
  • 1970-01-01
  • 2016-12-17
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多