Вопрос по эвенту во встроенной функции.
Добрый день.
Решил немного упростить код, скрывания объектов, но тут появилась небольшая загвоздка. Вот код. $('.js_show_sferi').on('click',sferi_change_visible); function sferi_change_visible(e){ sferi_block=$(this).parent().find('.sferi_block_wrap').children(); sferi_block.stop(); if (sferi_block.is(':visible')) sferi_block.fadeOut(1000); else { //e.preventDefault(); sferi_block.fadeIn(1000); sferi_block.hide_by_click(); } } jQuery.fn.hide_by_click=function(){ array_list=$('body').data('hide_by_click_list'); if (!full_null(array_list)){ array_list.push($(this)); }else{ array_list=[$(this)]; } $('body').data('hide_by_click_list',array_list); //setTimeout(function(){ $('body').on('click',function (event){ //if (event.isDefaultPrevented()==true) return; array_list=$('body').data('hide_by_click_list'); array_list[0].remove(); }) //},300); } Тут для теста.Объект не стирается, а удаляется. Проблема в том, что объект появляется и одновременно удаляется. Т.е. $('.js_show_sferi').on('click',sferi_change_visibl e) срабатывает и за ним сразу задается обработчик и запускается $('body').on('click',function (event). Т.е. объект появляется и удаляется одновременно. Нашел 2 варианта решения. - 1) добавить. e.preventDefault(); в основную функцию и event.isDefaultPrevented()во встроеную. Так все работает, но проблема в том, что прописывать e.preventDefault(); приходится прописывать в основной фунции, чего мне бы не хотелось. Нужно чтобы просто в коде можно запускать метод .hide_by_click(); и не заботится больше ни о чем. Встроенная функция jQuery.fn.hide_by_click=function(e) - эвент не обрабатывает, выдает ошибку. Возможно как-нибудь это обойти? 2) Вариант более тупой - через таймаут. |
vuler,
а макет сделать? и ещё раз попробовать обьяснить попроще что творите и что не получается |
Да в принципе подправил код. Кому интересно, можно вместе улучшить код.
К любому элементу на страницы применяем метод .hide_by_click(e); и при клике в любою область отличную от этого элемента - он будет скрываться с экрана(нужно для всплывающих окон и меню). Не нравится мне, что в этот метод нужно передавать обязательно event, во внутрь самой функции поместить не удается. Вот сам код этой функции: jQuery.fn.hide_by_click=function(e){ e.preventDefault(); array_list=$('body').data('hide_by_click_list'); if (array_list instanceof Array){ for (key in array_list){ if (array_list[key]==$(this)) return; } array_list.push($(this)); }else{ array_list=[$(this)]; } $('body').data('hide_by_click_list',array_list); $('body').off('click.hide_by_click'); $('body').on('click.hide_by_click',function (event){ if (event.isDefaultPrevented()==true) return; array_list=$('body').data('hide_by_click_list'); for (key in array_list){ array_list[key].stop(); if(!$(event.target).closest(array_list[key]).length){ array_list[key].fadeOut(); array_list.splice(key,1);} } if (full_null(array_list)) $('body').off('click.hide_by_click'); else $('body').data('hide_by_click_list',array_list); }) } Она запоминает все элементы конторые нужно скрыть в переменной 'hide_by_click_list' у элемента body. При клике на любую область, она перебирает все элементы из этого списка и если клик не был по нему - он удаляется. В конце, если список hide_by_click_list пуст, то обработчик удаляется с body. Также для точности прменяю следующую функцию. function full_null(elem){//Проверка на полный ноль. отстутсвие или несуществование. if (elem=='undefined' || elem==null || elem==""){ return true; }else return false; } Разные браузеры по разному видят переменные, если их нет, кто-то undefined, кто-то null, поэтому приходится применять эту конструкцию. Может есть попроще вариант? |
function full_null(elem){//Проверка на полный ноль. отстутсвие или несуществование. if (elem=='undefined' || elem==null || elem==""){ return true; }else return false; } Можно заменить на: function full_null(elem){ return !(!!elem); } |
jQuery plugin Скрытие по клику вне элемента
vuler,
<!DOCTYPE HTML> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> .orange { background: #FFCC00; } .orange + div{ display: block; } span { cursor: pointer; } </style> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script> jQuery.fn.hide_by_click = (function() { var arrSelector = []; $(document).on('click', function(event) { $.map(arrSelector, function(el) { if (event.target != el && !$(el).has(event.target).length) $(el).fadeOut() }) }); return function(add) { this.each(function(indx, el) { if (add) arrSelector.push(el); else { var indx = $.inArray(el, arrSelector); if (indx != -1) arrSelector.splice(indx, 1) } }); return this } }()) $(function() { $(".block_info_main span").hide_by_click(true); //добавить все span для контроля $(".orange").hide_by_click(false); // убрать оранжевый из списка слежения }); </script> </head> <body> <div class='block_info_main' id='test'>1111 <div class='first'> <span class='info orange'>Информация</span> <div class='main'> <span class='info_show show '>текст1</span> </div> </div> <div class='first'> <span class='info'>Информация2</span> <div class='main'> <span class='info_show '><b style="color: rgb(51, 51, 255)">текст2</b></span> </div> </div> <div class='first'> <span class='info'>Информация3</span> <div class='main'> <span class='info_show '>текст3</span> </div> </div> </div> </body> </html> |
:write: дубль два добавлено отключение слежения при пустом списке.
<!DOCTYPE HTML> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> .orange { background: #FFCC00; } .orange + div{ display: block; } span { cursor: pointer; } </style> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script> jQuery.fn.hide_by_click = (function() { var arrSelector = [], tracking = function(event) { $.map(arrSelector, function(el) { if (event.target != el && !$(el).has(event.target).length) $(el).fadeOut() }) } return function(add) { $(document).off({'click' : tracking }); this.each(function(indx, el) { if (add) arrSelector.push(el); else { var indx = $.inArray(el, arrSelector); if (indx != -1) arrSelector.splice(indx, 1) } }); arrSelector.length && $(document).on({'click' : tracking }); return this } }()) $(function() { $(".block_info_main span").hide_by_click(true); //добавить все span для контроля $(".orange").hide_by_click(false); // убрать оранжевый из списка слежения }); </script> </head> <body> <div class='block_info_main' id='test'>1111 <div class='first'> <span class='info orange'>Информация</span> <div class='main'> <span class='info_show show '>текст1</span> </div> </div> <div class='first'> <span class='info'>Информация2</span> <div class='main'> <span class='info_show '><b style="color: rgb(51, 51, 255)">текст2</b></span> </div> </div> <div class='first'> <span class='info'>Информация3</span> <div class='main'> <span class='info_show '>текст3</span> </div> </div> </div> </body> </html> |
:write: дубль 3 добавлена защита от повторного добавления элемента в список слежения
<!DOCTYPE HTML> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> .orange { background: #FFCC00; } .orange + div{ display: block; } span { cursor: pointer; } </style> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script> jQuery.fn.hide_by_click = (function() { var listSelector = $(), tracking = function(event) { listSelector.each(function(i,el) { if (event.target != el && !$(el).has(event.target).length) $(el).fadeOut() }) } return function(add) { $(document).off({'click' : tracking }); this.each(function(indx, el) { listSelector = listSelector[add ? 'add' : 'not'](el); }); listSelector.length && $(document).on({'click' : tracking }); return this } }()) $(function() { $(".block_info_main span").hide_by_click(true); //добавить все span для контроля $(".orange").hide_by_click(false); // убрать оранжевый из списка слежения }); </script> </head> <body> <div class='block_info_main' id='test'>1111 <div class='first'> <span class='info orange'>Информация</span> <div class='main'> <span class='info_show show '>текст1</span> </div> </div> <div class='first'> <span class='info'>Информация2</span> <div class='main'> <span class='info_show '><b style="color: rgb(51, 51, 255)">текст2</b></span> </div> </div> <div class='first'> <span class='info'>Информация3</span> <div class='main'> <span class='info_show '>текст3</span> </div> </div> </div> </body> </html> |
Цитата:
Чем-то похоже на теорию несуществования. И на практике применяется? |
Как написать плагин для jquery или закрыть по клику вне элемента
изменён формат опций, добавлена возможность установить свою функцию исчезновения :write: :thanks:
<!DOCTYPE HTML> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> .orange { background: #FFCC00; } .orange + div { display: block; } span { cursor: pointer; } .red { background: rgb(255, 20, 20); } </style> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script> jQuery.fn.hide_by_click = (function() { var defaults = { add: true, done: function() { $(this).fadeOut() } } var listSelector = $(), tracking = function(event) { listSelector.each(function(i, el) { if (event.target != el && !$(el).has(event.target).length) defaults.done.call(el) }) } return function(options) { defaults = $.extend({}, defaults, options); $(document).off({ 'click': tracking }); this.each(function(indx, el) { listSelector = listSelector[defaults.add ? 'add' : 'not'](el); }); listSelector.length && $(document).on({ 'click': tracking }); return this } }()) $(function() { $(".block_info_main .info").hide_by_click(); //добавить все span.info для контроля $(".orange").hide_by_click({ 'add': true, 'done': function() { $(this).addClass("red").fadeOut(2000) } }); // добавить оранжевый, изменить функцию исчезновения }); </script> </head> <body> <div class='block_info_main' id='test'>1111 <div class='first'> <span class='orange'>Информация</span> <div class='main'> <span class='info_show show '>текст1</span> </div> </div> <div class='first'> <span class='info'>Информация2</span> <div class='main'> <span class='info_show '><b style="color: rgb(51, 51, 255)">текст2</b></span> </div> </div> <div class='first'> <span class='info'>Информация3</span> <div class='main'> <span class='info_show '>текст3</span> </div> </div> </div> </body> </html> |
Часовой пояс GMT +3, время: 06:45. |