Почему объекты jQuery в инициализации свойств пусты?

'use strict';
var Controller = function Controller() {};

Controller.init = function() {
  if (!Controller.PROPERTIE.element || !Controller.PROPERTIE.indicator) {
    return 'Expected to find [data-controller] and [data-controller-to]';
  }

  Controller._start();
};

Controller.PROPERTIE = {
  element: $('[data-controller]'),
  indicator: $('[data-controller-to]'),
  state: false
};

Controller._start = function() {
  Controller.PROPERTIE.indicator.bind('click', Controller._toggle);
};

Controller._toggle = function() {
  Controller.PROPERTIE.element
    .animate({
      bottom: (Controller.PROPERTIE.state = !Controller.PROPERTIE.state) ? '-110' : '0'
    });
};

очевидно, что элементы в свойстве объекта не существуют, но они существуют! Может ли кто-нибудь сказать мне, если я не могу использовать Javascript, как это?

Может быть, что-то с подъемом ломает сценарий?

Я уже пытаюсь поставить объект перед инициализацией, и результат тот же.

Я знаю, что могу расширить прототип, но у меня есть свои причины использовать это.

Благодарю.

2 ответа

Решение

Я могу думать о трех возможных причинах:

  1. Код инициализируется перед анализом DOM.
  2. Ваш HTML фактически не содержит элементов, которые будут соответствовать этим селекторам.
  3. Желаемые элементы создаются динамически после инициализации этого кода.

В этой декларации:

Controller.PROPERTIE = {
  element: $('[data-controller]'),
  indicator: $('[data-controller-to]'),
  state: false
};

два выражения jQuery будут оцениваться сразу же при разборе этого кода. Если этот код не находится в самом конце тела, то эти элементы, скорее всего, еще не будут существовать.

Обычное решение этого состоит в том, чтобы не инициализировать эти элементы в статическом объявлении, а инициализировать их, вызывая функцию после загрузки страницы.

Если вы действительно хотите, чтобы они были глобальными, то вы можете просто сделать это:

$(document).ready(function() {
    Controller.PROPERTIE = {
      element: $('[data-controller]'),
      indicator: $('[data-controller-to]'),
      state: false
    };
});

Но вы также должны убедиться, что не пытаетесь использовать их до тех пор, пока не запустится этот код.


Единственная возможная причина, о которой я могу подумать, это то, что ваша DOM не содержит элементов, которые соответствуют вашим двум селекторам. Кажется, что это одна из этих двух проблем. Поскольку вы не указали нам ни общую структуру страниц HTML-кода, который вы намереваетесь сопоставить, мы не можем ничего сказать, кроме как объяснить, по каким причинам это может быть.

У меня такое чувство, что вы думаете, что объект jQuery не определен из-за этого:

if (!Controller.PROPERTIE.element || !Controller.PROPERTIE.indicator) {
    return 'Expected to find [data-controller] and [data-controller-to]';
  }

Вы должны помнить, что конструктор jQuery $() всегда будет возвращать объект. Если вы действительно хотите проверить, есть ли выбранный элемент, вы должны использовать свойство length объекта jQuery.

if (!Controller.PROPERTIE.element.length || !Controller.PROPERTIE.indicator.length) {
    //element or indicator not there.
    return 'Expected to find [data-controller] and [data-controller-to]';
  }
Другие вопросы по тегам