10.11.2014, 22:07
|
Кандидат Javascript-наук
|
|
Регистрация: 16.02.2012
Сообщений: 109
|
|
Вопрос по эвенту во встроенной функции.
Добрый день.
Решил немного упростить код, скрывания объектов, но тут появилась небольшая загвоздка.
Вот код.
$('.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) Вариант более тупой - через таймаут.
|
|
11.11.2014, 02:12
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
vuler,
а макет сделать? и ещё раз попробовать обьяснить попроще что творите и что не получается
|
|
11.11.2014, 13:40
|
Кандидат Javascript-наук
|
|
Регистрация: 16.02.2012
Сообщений: 109
|
|
Да в принципе подправил код. Кому интересно, можно вместе улучшить код.
К любому элементу на страницы применяем метод .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, поэтому приходится применять эту конструкцию. Может есть попроще вариант?
|
|
11.11.2014, 13:58
|
Профессор
|
|
Регистрация: 12.12.2012
Сообщений: 1,398
|
|
function full_null(elem){//Проверка на полный ноль. отстутсвие или несуществование.
if (elem=='undefined' || elem==null || elem==""){
return true;
}else return false;
}
Можно заменить на:
function full_null(elem){
return !(!!elem);
}
|
|
11.11.2014, 16:09
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
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>
|
|
11.11.2014, 16:25
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
дубль два добавлено отключение слежения при пустом списке.
<!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>
|
|
11.11.2014, 18:26
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
дубль 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>
|
|
11.11.2014, 18:38
|
Профессор
|
|
Регистрация: 23.10.2010
Сообщений: 2,718
|
|
Сообщение от vuler
|
метод .hide_by_click(e); и при клике в любою область отличную от этого элемента
|
Значит hide_if_unclick()
Чем-то похоже на теорию несуществования. И на практике применяется?
|
|
11.11.2014, 21:08
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
Как написать плагин для jquery или закрыть по клику вне элемента
изменён формат опций, добавлена возможность установить свою функцию исчезновения
<!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>
Последний раз редактировалось рони, 28.02.2015 в 21:22.
|
|
|
|