Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 10.06.2016, 00:37
Аспирант
Отправить личное сообщение для maxapet Посмотреть профиль Найти все сообщения от maxapet
 
Регистрация: 27.08.2015
Сообщений: 43

Почему не видна переменная?
Имеется такой фрагмент кода jQuery-плагина:
$.fn.colorPicker = function(method){
		var settings;
		var methods = {
			setColor: function(color) {
				if (settings == undefined){
					alert("settings is undefined");
				} else if (settings == null){
					alert("settings is null");
				};
				if (color[0] != "#")
					color = "#" + color;
				this.find(".color-picker-tbl td").each(function(i) {
					if (settings.colors[i] == color) {
						$(this).trigger("click");
					}
				});
				alert();
			},
			init: function(options) {
				return this.each(function(){
					settings = $.extend({}, defaults, options);
					var lineCnt = 2;
					var cellsInLine = settings.colors.length / lineCnt;

					var tbl = $("<table class='color-picker-tbl'/>");
					for(l=0; l < lineCnt; l++){
						var tr = $("<tr />");
						tr.appendTo(tbl);
						for(c=0; c < cellsInLine; c++){
							var td = $("<td style='background-color: " + settings.colors[l * cellsInLine + c] + ";' class='color-picker-mask'></td>").appendTo(tr);
						}
					}
					$(this).append(tbl);
					var $cells = $(this).find(".color-picker-tbl td");
					$cells.each(function(i) {
						$(this).click(function() {
							if (i != settings.selectedColorIdx){
								$cells.eq(settings.selectedColorIdx).removeClass("selected").removeClass("selected-color-mask-1").removeClass("selected-color-mask-2");
								$(this).addClass("selected").addClass(isDark(settings.colors[i]) ? "selected-color-mask-1" : "selected-color-mask-2");
								settings.selectedColorIdx = i;
							}
							settings.click(settings.colors[i]);
						});
					});
					//$cells.eq(settings.selectedColorIdx).trigger("click");
				});
			}
		}
		// немного магии
		if ( methods[method] ) {
			// если запрашиваемый метод существует, мы его вызываем
			// все параметры, кроме имени метода придут в метод
			// this так же перекочует в метод
			return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			// если первым параметром идет объект, либо совсем пусто
			// выполняем метод init
			return methods.init.apply( this, arguments );
		} else {
			// если ничего не получилось
			$.error( 'Метод "' +  method + '" не найден в плагине jQuery.colorPicker' );
		}
   }


Во время работы сначала вызывается функция init, которая, казалось бы, должна инициализировать переменную settings, заданную во второй строке, но этого не происходит. При последующем вызове функции setColor выдаётся сообщение "settings is undefined". Почему? Ведь settings определена во внешней для init и setColor функции, значит, по правилам видимости Javascript, должна быть в них видима и доступна.
Если же задать какое-то начальное значение для settings, то при вызове init оно не меняется. Получается, что при вызове init в строке
settings = $.extend({}, defaults, options);
создаётся новая переменная settings, Но почему?! И как сделать так, чтобы работала именно переменная settings, объявленная во второй строке данного фрагмента?
Ответить с цитированием
  #2 (permalink)  
Старый 10.06.2016, 00:52
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

maxapet, где defaults?
Ответить с цитированием
  #3 (permalink)  
Старый 10.06.2016, 04:23
Аспирант
Отправить личное сообщение для maxapet Посмотреть профиль Найти все сообщения от maxapet
 
Регистрация: 27.08.2015
Сообщений: 43

Переменная defaults определена во внешней функции, в которой определена приведённая функция. С defaults нет проблем - эта переменная видна и работает нормально..
Ответить с цитированием
  #4 (permalink)  
Старый 10.06.2016, 07:46
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

maxapet,
чем не устроил рабочий вариант? и вас же просили делать полностью а не кусками
Что делать с options
Ответить с цитированием
  #5 (permalink)  
Старый 10.06.2016, 07:54
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

maxapet,
можно в data записать строка 24
$(this).data({settings:settings})
и потом брать из data в setColor
Ответить с цитированием
  #6 (permalink)  
Старый 10.06.2016, 09:13
Аспирант
Отправить личное сообщение для maxapet Посмотреть профиль Найти все сообщения от maxapet
 
Регистрация: 27.08.2015
Сообщений: 43

В рабочем варианте settings, объявленная в функции init недоступна из функции setColor.

Я не понимаю, как связаны видимость переменной и css, например.

А вот идея с использованием data сработала, спасибо большое.

P.S. Проблема была в том, что переменная settings, объявленная как в приведённом примере, создаётся заново при каждом обращении к colorPicker.
Ответить с цитированием
  #7 (permalink)  
Старый 10.06.2016, 09:44
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

Сообщение от maxapet
Я не понимаю, как связаны видимость переменной и css, например.
в данном случае не хватало примера инициализации и остального кода скрипта.
если вы хотите именно так задавать вопрос то надо выкинуть всё лишнее , для локализации проблемы
будет примерно так:

$.fn.colorPicker = function(method){
				var methods = {
			setColor: function(color) {

			},
			init: function(options) {
				return this.each(function(i,el){
					var settings = $.extend({}, defaults, options);
//как сделать обьект  settings сделать доступным в методе setColor для каждого el

				});
			}
		}
		// немного магии
		if ( methods[method] ) {
			// если запрашиваемый метод существует, мы его вызываем
			// все параметры, кроме имени метода придут в метод
			// this так же перекочует в метод
			return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			// если первым параметром идет объект, либо совсем пусто
			// выполняем метод init
			return methods.init.apply( this, arguments );
		} else {
			// если ничего не получилось
			$.error( 'Метод "' +  method + '" не найден в плагине jQuery.colorPicker' );
		}
   }
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему некоторые операторы возвращают значения, а не ссылки? dump Общие вопросы Javascript 15 25.07.2012 17:28
Почему переменная не может быть глобальной? LeD4eG Общие вопросы Javascript 4 25.04.2012 05:51
Свойства объекта, методы и this. Почему свойство вызывается с () ? jsuse Общие вопросы Javascript 2 04.11.2011 20:39
Prototype. Одноблочное определение псевдокласса. Литеральная форма не робит. Почему? GuardCat Общие вопросы Javascript 6 03.10.2011 13:46
Почему не определяется втарая переменная? Арман Общие вопросы Javascript 3 09.04.2011 11:14