Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   $(this) в теле плагина (https://javascript.ru/forum/jquery/35400-%24-v-tele-plagina.html)

prison47 10.02.2013 02:43

$(this) в теле плагина
 
Помогите пожалуйста разобраться. Есть тело плагина. В html он вызывается на определенном элементе, допустим див с классом box. Соответственно если в плагине обращаться так $(this) нас приведет на див с классом box. А вот в чем проблема: а например хочу найти див с классом too, и на нем вызвать функцию. Например:
$('.too').click(function(){

$(this).действие;

});

Так вот проблема в том что и внутри функции $(this) вызывает класс box. Так вот как мне повесить действия на этот элемент на котором вызван click.

prison47 10.02.2013 05:04

<script type="text/javascript">

$(window).load(function(){

$(".box").plugin(


	);
});
</script>

<div class="box">Click</div> // нажимаем получаем действие, например добавляем в DOM еще один див с классом too при клике на котором он же и закроется.

$('.too').click(function(){

$(this).hide(); // но хайд естественно не сработает потому как this возвратит див с классом бокс

});

danik.js 10.02.2013 05:48

Внутри обработчика собития this ссылается на элемент, в котором возникло событие, то есть на .too

<button class="too">Клик ми</button>
<script src="//code.jquery.com/jquery-latest.min.js"></script>
<script>
    $('.too').click(function(e){
        alert( this.className );
    });
</script>

prison47 10.02.2013 06:10

То что this возвращает это я знаю. Но дело в том что возвращает его как объект, тоесть так уже не получится сделать this.hide();

danik.js 10.02.2013 06:25

this ссылается на чистый DOM-элемент.
Если нужны плюшки из jquery-обертки, просто оборачиваем его в нее:
$(this).hide(). Это же так просто.

<button class="too">Клик ми</button>
<script src="//code.jquery.com/jquery-latest.min.js"></script>
<script>
    $('.too').click(function(e){
        $(this).hide();
    });
</script>

prison47 10.02.2013 06:30

Да но вы забыли что мы все это делаем в теле плагина, а там $(this) выдаст .box

danik.js 10.02.2013 07:22

$('.too').click(fn) регистрирует функцию fn в качестве обработчика события click. При наступлении события click, jQuery вызывает данную функцию, устанавливая в качестве контекста dom-элемент, на котором сработало событие.
И не имеет значения где эта функция находится. Хоть на луне.
В примере выше обработчик регистрировали в глобальном контексте, тоесть window, тем не менее this внутри обработчика не указывает на window, верно?

Другой пример:

<button class="too">Клик ми</button>
<script src="//code.jquery.com/jquery-latest.min.js"></script>
<script>
    (function(){
        alert (this);

        $('.too').click(function(e){
            $(this).hide();
        });

    // вызываем, устанавливая контекстом строку 'Луна'
    }).call('Луна');
</script>

prison47 10.02.2013 16:54

Да получается я вызываю плагин на .box и в теле плагина $(this) всегда возвращает мне тот элемент на котором был вызван плагин. :(

рони 10.02.2013 17:00

prison47,
с каким плагином боритесь? и зачем внутри плагина дополнительная фунция нужна?

prison47 10.02.2013 18:00

Я разбираюсь с созданием плагина. Вот например я хочу вызвать появление дива .too при нажатии на .box. Подключаю плагин на .box
<script type="text/javascript">

$(window).load(function(){

$(".box").plugin(

    );

});

</script>

Все работает, кликаем на .box появляется див .too. А вот теперь я хочу повесить обработчик на див .too например .hide(). То есть при нажатии на .too он исчезает. Но ничего естественно не получается так $(this) даже внутри функции обработчика возвращает тот дом элемент на котором был вызван плагин, тоесть .box

рони 10.02.2013 22:43

Цитата:

Сообщение от prison47
кликаем на .box появляется див .too. А вот теперь я хочу повесить обработчик на див .too например .hide(). То есть при нажатии на .too он исчезает.

Не вижу проблемы ...
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
 .too{
   display: none;
 }
</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$.fn.plugin = function () {
        return this.each(function (index, self) {
        $(this).click(function (e) {
            $('.too').show();
        });
        $('.too').click(function (e) {
            $(this).hide();
        });
    })
}
</script>
<script type="text/javascript">
$(window).load(function(){
$(".box").plugin();
});
</script>
  <title></title>
</head>
<body>
<button class="box">is box</button>
<div class="too">is too</div>
</body>
</html>

не вижу проблемы

prison47 10.02.2013 23:59

Ничего не понимаю почему тогда у меня не работает как надо:
(function($) {

	$.fn.plugin2 = function(options) {
 	
 	return this.each(function() { 

		var $this = $(this);

		var setting = $.extend({ 

		}, options); 

	$this.click(function(){

	$('.too').show();
	});

	$('.too').click(function(e){

		$this.hide();
	});

});

	};
}) (jQuery);

Может тут я что-то пропустил?

рони 11.02.2013 00:25

prison47,
строка 20 там нет $(this) у вас.

prison47 11.02.2013 00:26

Как нет я же в 7 строке определил var $this = $(this);

рони 11.02.2013 00:40

prison47,
так значение переменной и есть в 20 строке а по новой this никто определять небудет

prison47 11.02.2013 00:47

Спасибо большое так заработало но я не совсем понял, почему именно $this не приняло $(this). Если не сложно не могли бы вы объяснить ?

рони 11.02.2013 01:02

prison47,
var $this = $(this);
эта строка равна для примера var $this = $('.box').eq(0);
$this.hide(); тогда станет $('.box').eq(0).hide(); может кто доходчивее обьяснит.
http://learn.javascript.ru/this

prison47 11.02.2013 01:23

Теперь кажется я понял. БОЛЬШОЕ вам спасибо:)

prison47 13.02.2013 06:16

Эх появилась еще одна дилемма. Помогите пожалуйста разобраться. Делаю плагин появления окон уведомления. Так вот появление этих окон вешаю на кнопку с определенным атрибутом, все работает. Добавляю в документ еще одну кнопку, тоже все работает. Но теперь $(this) уже дублирует элементы. То есть например стоит обработчик нажатия на кнопку, нажимаем, появляется окно(див) в него добавляется ново созданный див тоже с обработчиком клика. Так вот теперь новый див реагирует на this в двойне. То есть плагин как бы вызывается два раза. И не получается например повесить на него условие с проверкой такого плана:
if(!$(this).attr('data-toggle') || $(this).attr('data-toggle') == 'off'){

	$(this).attr('data-toggle','on');

	$(this).parent('[data-case]').css('height', ptopHeight).addClass('clear-p');

	} else if ($(this).attr('data-toggle') == 'on'){

	$(this).attr('data-toggle','off');

	 $(this).parent('[data-case]').css({'height': '200px', 'visibility': 'visible'});

};

Пo умолчание data-toggle стоит off Получается двойное срабатывание. Как то это можно обойти?

prison47 13.02.2013 07:18

Попробовал в таком случае обращаться до
return this.each(function() {

И все заработало как надо.
Но такое ощущение что это не правильно.

рони 13.02.2013 09:17

prison47,
мало что понятно в вашем описании,минимальный хтмл код дайте и опишите что должно открыватся а что нет в нём.

prison47 13.02.2013 22:51

Сотрите есть 4 кнопки на которые подключен плагин.
<script type="text/javascript">
$(document).ready(function(){
$("[data-btn]").plugin();
});
</script>

<div data-btn="w1">Click</div>
<div data-btn="w2">Click</div>
<div data-btn="w3">Click</div>
<div data-btn="w3">Click</div>

При нажатии на одну из кнопок предположим в бади вставляется еще один див, внутри которого еще один элемент играющий роль закрытия.
<div class="new_div"><span class="toggle">Close</span></div>

Так вот если поставить на этот спан обработчик например клик:
$('body').on('click', '.toggle' function(){

console.log($(this));

});

Выдаст 4 спана. А да и все это находится в конструкции :
return this.each(function() {

После выноса ха пределы this.each все работает как нужно. Но вот вопрос является ли это правильным? Такое подозрение что у меня получается кавардак.

И второй более запутанный вопрос внутри этой же конструкции this.each у меня имеется такой код:
casePress.on('click', '[data-open]', function(){ // open data-case open

		var thPheight = $(this).parent('[data-case]').innerHeight();
		var thPwidth = $(this).parent('[data-case]').innerWidth();

		var calHeight = $(window).height() / 2 - thPheight / 2;
		var calWidth = $(window).width() / 2 - thPwidth / 2;

		if(setting.autoResizeBox == true){ // if auto resize box open

			$(this).parent('[data-case]').appendTo('body').addClass('auto_center').css({'top': calHeight, 'right': calWidth, 'width': '30%'});
		
		} else {

			$(this).parent('[data-case]').appendTo('body').addClass('auto_center').css({'top': calHeight, 'right': calWidth});
		}; // auto resize box close

		$('html').css('overflow', 'hidden');

		genOverlay.stop(true).fadeTo(setting.overlayShowSpeed, setting.overlayOpacity);
		
	}); // open data-case close

Вкратце получается вот что: при нажатии на кнопку <div data-btn="w1">Click</div> на которую подключен плагин, появляется вновь созданный див со спаном внтури.
<div data-case="w1"><span data-open="da">Open</span></div>

При нажатии на спан, див data-case переносится в конец бади, меняет свой ширину и высоту, и выстраивается точно по центру экрана. Это все хорошо но если мы перенесем этот код за пределы return this each то он перестает правильно высчитывать высоту и ширину data-case, вернее высчитывает ее но до того как див поменял свои размеры при переносе в конец бади. По логике это как бы правильно поскольку расчет высоты и ширины идет до момента его переноса и изменения размеров. Но почему это работает внутри this each ?
Вообщем я видимо где то запутался :(

sotik 24.02.2013 08:38

Помогите,пожалуйста, разобраться.
Начал осваивать написание плагинов и вот попал...
Тело плагина примерно такое:
    var wos = document.getElementById("bamForm");
    wos.innerHTML = "<a href='#' onClick='Pipka()'>testik</a>";
function Pipka()
{
alert('порядок')
}
То есть в dom есть div, куда вставляется ссылка, у которой есть обработчик.Но при клике на ссылку функция не вызывается.

danik.js 24.02.2013 13:19

onClick -> onclick для xhtml. В html можно хоть oNcLiCk писать - будет работать. Но уверен дело не в в этом.
sotik, а зачем вам jQuery?

sotik 24.02.2013 17:22

а я разве писал,что мне нужно jQuery ?! :)
я не совсем вас понял насчет onClick.
Как мне сделать,чтоб по клике на ссылку запускалась функция из плагина?

danik.js 24.02.2013 17:50

Цитата:

Сообщение от sotik
а я разве писал,что мне нужно jQuery

Тогда объясните зачем вы полезли в этот топик? Здесь речь о плагинах к jQuery. Создайте тему в соответствующем разделе, опишите ясно и понятно проблему, используйте теги для форматирования кода и тд и тп. Ну прям как маленький, ей богу..

sotik 24.02.2013 18:57

Да я и есть маленький в плане скриптов для плагинов.Не думал что так все серьезно,смотрю речь про плагины идет.
В соответствующих топиках и темах писал- мне никто не ответил :(
Вы не могли бы мне помочь? пожалуйста.

prison47 03.03.2013 06:26

Снова здравствуйте. Помогите пожалуйста в такой вот проблеме:
Подключаем плагин с параметрами:
$(document).ready(function(){

$('#div_id').pluginName({
	mainTitle:'aa  aaaaaaaaa aaaaaaaaaa    aaaaaa'
});

 });

Если в параметре передать значение без переноса строки то все в порядке.
Но если так:
$(document).ready(function(){

$('#div_id').pluginName({
	mainTitle:'aa 
 aaaaaaaaa aaaaaaaaaa    aaaaaa'
});

 });

То все вылетает ошибка. Объясните пожалуйста как решить эту проблему.Я догадываюсь что есть для этого регулярное выражение, но не совсем понимаю как с его помощью обработать.
Заранее большое спасибо!

danik.js 03.03.2013 07:16

Тут непричем ни jquery ни плагины, ни регулярки. Это синтаксическая ошибка. Если нужно объявить строку с переносами, то это делается либо:
var string = 'aa\
bbb';

либо
var string = 'aaa\nbbb';

prison47 03.03.2013 07:25

Понимаете у меня в параметры передается значение из <textarea> тоесть если кто-то вбивая значение в textarea сделает перенос строки, то скрипт не будет выполнятся. Так вот как мне отловить эти переносы и например заменить их на пробел или <br>

danik.js 03.03.2013 07:51

alert("abc\ndef\ngh".replace(/\n/g, ' '))

prison47 03.03.2013 08:00

Угу понятно теперь. Значит мне нужно перехватить это значение обработать при помощи replace и отправить в параметры.
Спасибо большое.

prison47 03.03.2013 23:50

Не получается никак справится, в чем ошибка?
получаю текст в переменную из php:
var convert_main = '".get_option('main_content')."';

пытаюсь обработать через replace:
convert_main.replace(/\n/g, ' ');
]
Uncaught SyntaxError: Invalid regular expression: missing /

Решил только средствами php а потом уже передал в javascropt:
$convert_main_content = str_replace(array("\r","\n"), ' ',get_option('main_content'));
mainContent:' {$convert_main_content} '


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