Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Почему не видна переменная? (https://javascript.ru/forum/jquery/63483-pochemu-ne-vidna-peremennaya.html)

maxapet 10.06.2016 00:37

Почему не видна переменная?
 
Имеется такой фрагмент кода 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, объявленная во второй строке данного фрагмента?

Rise 10.06.2016 00:52

maxapet, где defaults?

maxapet 10.06.2016 04:23

Переменная defaults определена во внешней функции, в которой определена приведённая функция. С defaults нет проблем - эта переменная видна и работает нормально..

рони 10.06.2016 07:46

maxapet,
чем не устроил рабочий вариант? и вас же просили делать полностью а не кусками
http://javascript.ru/forum/jquery/63...tml#post418937

рони 10.06.2016 07:54

maxapet,
можно в data записать строка 24
$(this).data({settings:settings})
и потом брать из data в setColor

maxapet 10.06.2016 09:13

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

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

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

P.S. Проблема была в том, что переменная settings, объявленная как в приведённом примере, создаётся заново при каждом обращении к colorPicker.

рони 10.06.2016 09:44

Цитата:

Сообщение от 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' );
		}
   }


Часовой пояс GMT +3, время: 23:39.