Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 11.11.2019, 01:14
Интересующийся
Отправить личное сообщение для Luther Посмотреть профиль Найти все сообщения от Luther
 
Регистрация: 11.11.2019
Сообщений: 12

Как заставить сработать условие, после добавление класса
Доброго времени суток. Проблема следующая: есть блок, изначально его позиция скрыта от визуального контакта right: -300, при клике, к блоку подключается class "mobile-menu--active", после чего его позиция должна равняться right: 0, но этого не происходит. Как исправить это, условие вроде написано правильно, но мне кажется оно срабатывает один раз и дальше не проверяется, как отследить добавление нового класса и проиграть условие повторно? Не судите строго, я только учусь
(function($) {
    
    $.fn.mobileMenu = function(options) {

        //Defaults to extend options
        var settings = {
            side: 'right',
            width: 300,
            animationSpeed: 600
        };

        //Extend those options
        var options = $.extend(settings, options);

        return this.each(function () {

            var mob = $(this),
                mobMenu = $('.mobile-menu');

            mob.on('click touchend', function () {

                if(mobMenu.is('.mobile-menu--active')) {
                    mobMenu.removeClass('mobile-menu--active');
                    $('.hamburger--active').removeClass('hamburger--active');
                } else {
                    mobMenu.addClass('mobile-menu--active');
                    mob.addClass('hamburger--active');
                }
                return false;
            });


/////// ANIMATION
            var rightSide = 'mobile-menu--right-side',
                leftSide = 'mobile-menu--left-side',
                topSide = 'mobile-menu--top-side';

            if(options.side == "right") {
                mobMenu
                    .addClass(rightSide)
                    .css({"right": - options.width, "z-index" : 3});
                if (mobMenu.is('mobile-menu--active')) {
                    mobMenu
                        .animate({"right": 0}, options.animationSpeed);
                }
            }
        }); //each call
    }; //mobileMenu plugin

})(jQuery);

Последний раз редактировалось Luther, 11.11.2019 в 02:46.
Ответить с цитированием
  #2 (permalink)  
Старый 11.11.2019, 03:33
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

Luther,
строки 29 - 30 перенести в начало строки 47, если не поможет, делайте макет.

[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.
Ответить с цитированием
  #3 (permalink)  
Старый 11.11.2019, 13:04
Интересующийся
Отправить личное сообщение для Luther Посмотреть профиль Найти все сообщения от Luther
 
Регистрация: 11.11.2019
Сообщений: 12

Перенес как вы сказали, не помогло, прикрепляю код, надеюсь все правильно сделал.

<!DOCTYPE html>
<html lang="ru">
<html>
    <head>
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.hamburger {width: 20px;height: 20px;background-color: red}
.hamburger--active {background-color: green}

.mobile-menu {position: fixed;width: 100%;max-width: 300px;height: 100%; top: 0}
</style>
</head>
<body>
<div class="hamburger">
</div>
<div class="mobile-menu">
<h1>Заголовок блока</h1>
<p>Далеко-далеко за словесными горами в стране, гласных и согласных живут рыбные тексты. Проектах знаках переулка курсивных снова журчит жизни все приставка безопасную!</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
(function($) {
    
    $.fn.mobileMenu = function(options) {

        //Defaults to extend options
        var settings = {
            side: 'right',
            width: 300,
            animationSpeed: 600
        };

        //Extend those options
        var options = $.extend(settings, options);

        return this.each(function () {

            var mob = $(this),
                mobMenu = $('.mobile-menu');

            mob.on('click touchend', function () {

                if(mobMenu.is('.mobile-menu--active')) {
                    mobMenu.removeClass('mobile-menu--active');
                    $('.hamburger--active').removeClass('hamburger--active');
                } else {
                    mobMenu.addClass('mobile-menu--active');
                    mob.addClass('hamburger--active');
                }
                return false;
            });


/////// ANIMATION
            var rightSide = 'mobile-menu--right-side',
                leftSide = 'mobile-menu--left-side',
                topSide = 'mobile-menu--top-side';

            if(options.side == "right") {
                mobMenu
                    .addClass(rightSide)
                    .css({"right": - options.width, "z-index" : 3});
                if (mobMenu.is('mobile-menu--active')) {
                    mobMenu
                        .animate({"right": 0}, options.animationSpeed);
                }
            }
        }); //each call
    }; //mobileMenu plugin

})(jQuery);

$('.hamburger').mobileMenu({
    });
</script>
</body>
</html>

Последний раз редактировалось Luther, 11.11.2019 в 13:06.
Ответить с цитированием
  #4 (permalink)  
Старый 11.11.2019, 14:24
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Luther, у вас же не css анимация, а изменение класса, это асинхронное событие. Тогда сразу по смене класса и выполняйте анимацию:

(function($) {
    
    $.fn.mobileMenu = function(options) {

        var settings = {
            side: 'right',
            width: 300,
            animationSpeed: 600
        };

        //Extend those options
        var options = $.extend(settings, options);

        return this.each(function () {

            var mob = $(this),
                mobMenu = $('.mobile-menu');

            mob.on('click touchend', function () {

                mobMenu.toggleClass('mobile-menu--active');
                mob.toggleClass('hamburger--active');
                mobMenu.animate({right: -options.width + mob.is('.hamburger--active') * options.width}, options.animationSpeed);
                
            });
        });
    };
})(jQuery);

$('.hamburger').mobileMenu();
Ответить с цитированием
  #5 (permalink)  
Старый 11.11.2019, 15:27
Интересующийся
Отправить личное сообщение для Luther Посмотреть профиль Найти все сообщения от Luther
 
Регистрация: 11.11.2019
Сообщений: 12

Сообщение от laimas Посмотреть сообщение
Luther, у вас же не css анимация, а изменение класса, это асинхронное событие. Тогда сразу по смене класса и выполняйте анимацию:

(function($) {
    
    $.fn.mobileMenu = function(options) {

        var settings = {
            side: 'right',
            width: 300,
            animationSpeed: 600
        };

        //Extend those options
        var options = $.extend(settings, options);

        return this.each(function () {

            var mob = $(this),
                mobMenu = $('.mobile-menu');

            mob.on('click touchend', function () {

                mobMenu.toggleClass('mobile-menu--active');
                mob.toggleClass('hamburger--active');
                mobMenu.animate({right: -options.width + mob.is('.hamburger--active') * options.width}, options.animationSpeed);
                
            });
        });
    };
})(jQuery);

$('.hamburger').mobileMenu();

Оказывается это было проще, чем то что я варганил, спасибо большое за помощь, все работает
Ответить с цитированием
  #6 (permalink)  
Старый 11.11.2019, 15:46
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Luther
все работает
Странно как-то у вас это работает (определяется). В CSS задается макс ширина, и в опциях можно передать ширину и надо полагать позицию (side: 'right'). Если так, то ведь придется менять и CSS. Если параметры меню можно определять опциями, значит в CSS нужно задать только основные, то есть до инициализации, все остальное в плагине. К тому же странно плагин определять не основному, то есть меню, а кнопке. По идее блоку нужно определять, а кнопку можно переопределять также через опции, при этом блок скрывается изначально, чтобы "не моргал" при загрузке страницы.

<!DOCTYPE html>
<html lang="ru">
<html>
    <head>
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.hamburger-button {width: 20px;height: 20px;background-color: red}
.hamburger--active {background-color: green}

.hamburger {
    position: fixed;
    top: 20px;
    height: 100%;
    display: none; 
}
</style>
</head>
<body>
<div class="hamburger-button">
</div>
<div class="hamburger">
<h1>Заголовок блока</h1>
<p>Далеко-далеко за словесными горами в стране, гласных и согласных живут рыбные тексты. Проектах знаках переулка курсивных снова журчит жизни все приставка безопасную!</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
(function($) {
    
    $.fn.mobileMenu = function(options) {

        var settings = {
            side: 'right',
            width: 300,
            animationSpeed: 600,
            button: $('div.hamburger-button') 
        };

        var options = $.extend(settings, options), mobMenu = $(this);
        
        mobMenu.css({maxWidth: options.width, [options.side]: -options.width}).show(); //так определить в литеральном объекте свойство через переменную можно в ES6
        
        return this.each(function () {

            options.button.on('click touchend', function () {
                options.button.toggleClass('hamburger--active');
                 //и только так определить в литеральном объекте свойство через переменную можно для старичков
                var opt = {};
                opt[options.side] = -options.width + options.button.is('.hamburger--active') * options.width; 
                mobMenu.animate(opt, options.animationSpeed);
                
            });
        });

    };
})(jQuery);

$('div.hamburger').mobileMenu({side: 'left', width: 600});
</script>
</body>
</html>
Ответить с цитированием
  #7 (permalink)  
Старый 11.11.2019, 15:57
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

потом будет вопрос как закрыть по клику вне меню.
Ответить с цитированием
  #8 (permalink)  
Старый 11.11.2019, 15:58
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

рони,
Ответить с цитированием
  #9 (permalink)  
Старый 12.11.2019, 00:51
Интересующийся
Отправить личное сообщение для Luther Посмотреть профиль Найти все сообщения от Luther
 
Регистрация: 11.11.2019
Сообщений: 12

Сообщение от laimas Посмотреть сообщение
Странно как-то у вас это работает (определяется). В CSS задается макс ширина, и в опциях можно передать ширину и надо полагать позицию (side: 'right'). Если так, то ведь придется менять и CSS. Если параметры меню можно определять опциями, значит в CSS нужно задать только основные, то есть до инициализации, все остальное в плагине. К тому же странно плагин определять не основному, то есть меню, а кнопке. По идее блоку нужно определять, а кнопку можно переопределять также через опции, при этом блок скрывается изначально, чтобы "не моргал" при загрузке страницы.

<!DOCTYPE html>
<html lang="ru">
<html>
    <head>
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.hamburger-button {width: 20px;height: 20px;background-color: red}
.hamburger--active {background-color: green}

.hamburger {
    position: fixed;
    top: 20px;
    height: 100%;
    display: none; 
}
</style>
</head>
<body>
<div class="hamburger-button">
</div>
<div class="hamburger">
<h1>Заголовок блока</h1>
<p>Далеко-далеко за словесными горами в стране, гласных и согласных живут рыбные тексты. Проектах знаках переулка курсивных снова журчит жизни все приставка безопасную!</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
(function($) {
    
    $.fn.mobileMenu = function(options) {

        var settings = {
            side: 'right',
            width: 300,
            animationSpeed: 600,
            button: $('div.hamburger-button') 
        };

        var options = $.extend(settings, options), mobMenu = $(this);
        
        mobMenu.css({maxWidth: options.width, [options.side]: -options.width}).show(); //так определить в литеральном объекте свойство через переменную можно в ES6
        
        return this.each(function () {

            options.button.on('click touchend', function () {
                options.button.toggleClass('hamburger--active');
                 //и только так определить в литеральном объекте свойство через переменную можно для старичков
                var opt = {};
                opt[options.side] = -options.width + options.button.is('.hamburger--active') * options.width; 
                mobMenu.animate(opt, options.animationSpeed);
                
            });
        });

    };
})(jQuery);

$('div.hamburger').mobileMenu({side: 'left', width: 600});
</script>
</body>
</html>

Только щас увидел и чет не очень понятно, но я сделал следующем образом, если интересно:


<!DOCTYPE html>
<html lang="ru">
<html>
    <head>
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.hamburger {width: 20px;height: 20px;background-color: red}
.hamburger--active {background-color: green}
.mobile-menu {position: fixed;height: 100%;top: 0;background-color: yellow}
.overlay {
    left: 0;
    width: 100%;
    background-color: rgba(0,0,0,.4);
    position: fixed;
    top: 0;
    height: 100%;
}

</style>
</head>
<body>
<div class="hamburger">
</div>
<div class="mobile-menu">
   <h1>Заголовок</h1>
   <p>  Далеко-далеко за словесными горами в стране, гласных и согласных живут рыбные тексты. Запятой lorem текста, первую ему ее, над родного. Если, алфавит ручеек коварный там города образ великий маленькая текстов вопроса он.</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
(function($) {
    
    $.fn.mobileMenu = function(options) {

        //Defaults to extend options
        var settings = {
            side: 'left',
            butClass: 'hamburger',
            butClassActive: 'hamburger--active',
            width: 300, // if puted (side: 'top'), there must be 100
            zIndex: 99,
            exit: true,
            overlay: true,
            animationSpeed: 400,
            // afterChange: function(){}
        };

        //Extend those options
        var options = $.extend(settings, options);

        return this.each(function () {
            var mob = $(this),
                btn = $('.' + options.butClass),
                mobMenu = $('.mobile-menu'),
                mobMenuActive = 'mobile-menu--active';

            var rightSide = 'mobile-menu--right-side',
                leftSide = 'mobile-menu--left-side',
                topSide = 'mobile-menu--top-side';


            if (options.side == 'right') {
                mobMenu.addClass(rightSide).css({right: -options.width, width: options.width, 'z-index': options.zIndex});
            }
            if (options.side == 'left') {
                mobMenu.addClass(leftSide).css({left: -options.width, width: options.width, 'z-index': options.zIndex});
            }
            if (options.side == 'top') {
                mobMenu.addClass(topSide).css({top: -options.width+'%', width: options.width+'%', 'z-index': options.zIndex});
            }

            function moveMenu() {
                if (options.side == 'right') {
                    $('.' + rightSide).animate({right: -options.width + mob.hasClass(options.butClassActive) * options.width}, options.animationSpeed);
                }
                if (options.side == 'left') {
                    $('.' + leftSide).animate({left: -options.width + mob.hasClass(options.butClassActive) * options.width}, options.animationSpeed);
                }
                if (options.side == 'top') {
                    $('.' + topSide).animate({top: -options.width + mob.hasClass(options.butClassActive) * options.width+'%'}, options.animationSpeed);
                }
            }

            if (options.overlay) {
                if (options.overlay == "false") { return false; }
                var directionalOverlayHTML = '<div class="overlay"></div>';
                mobMenu.before(directionalOverlayHTML);

                var bgOverlay = $('div.overlay');
                bgOverlay.hide().css({'z-index': options.zIndex - 1});
            }


            mob.on('click touchend', function () {
                mobMenu.stop().toggleClass(mobMenuActive);
                btn.stop().toggleClass(options.butClassActive);
                if (options.overlay) {
                    if(options.overlay == "false") { return false; }

                    if (mobMenu.hasClass(mobMenuActive)) {
                        if (btn.hasClass(options.butClassActive)) {
                            bgOverlay.fadeIn(options.animationSpeed);
                            bgOverlay.on('click touchend', function () {
                                mobMenu.stop().removeClass(mobMenuActive);
                                btn.stop().removeClass(options.butClassActive);
                                bgOverlay.fadeOut(options.animationSpeed);
                                moveMenu();
                            });
                        }
                    }
                }
                moveMenu();
            });

            if (options.exit) {

                if(options.exit == "false") { return false; }

                var directionalExitHTML = '<div class="mobile-menu-inner"><span class="mobile-menu__exit">exit</span></div>';

                mobMenu.append(directionalExitHTML);

                var exitBtn = mobMenu.children('div.mobile-menu-inner').children('span.mobile-menu__exit');

                exitBtn.on('click touchend', function () {
                    mobMenu.stop().removeClass(mobMenuActive);
                    btn.stop().removeClass(options.butClassActive);
                    moveMenu();
                    if (options.overlay) {
                        if(options.overlay == "false") { return false; }
                        bgOverlay.fadeOut(options.animationSpeed);
                    }
                });
            }

            $(document).keyup(function(esc) {
                if (esc.keyCode === 27) {
                    if (mobMenu.hasClass(mobMenuActive)) {
                        if (btn.hasClass(options.butClassActive)) {
                            mobMenu.stop().removeClass(mobMenuActive);
                            btn.stop().removeClass(options.butClassActive);
                            moveMenu();
                            if (options.overlay) {
                                if(options.overlay == "false") { return false; }
                                bgOverlay.fadeOut(options.animationSpeed);
                            }
                        }
                    }
                }
            });
        }); //each call
    }; //mobileMenu plugin

})(jQuery);

$('.hamburger').mobileMenu();
</script>
</body>
</html>
[/quote]

Да, я думаю код в некоторых местах некорректный, ну как получается, сейчас пытаюсь настроить анимацию так чтоб она не прыгала, при многократном нажатии, добавил .stop(), но работает не очень привлекательно, как можно сделать, чтоб анимация проигрывалась до конца, а не постоянно обрабатывалась? + еще надо , чтобы на .hamburger вешался класс .hamburger--active только после того как анимация проигралась, ну т.е. Зеленой, кнопка должна стать, только когда меню окончательно выдвинулось

Последний раз редактировалось Luther, 12.11.2019 в 02:06.
Ответить с цитированием
  #10 (permalink)  
Старый 12.11.2019, 01:10
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Зачем 'z-index': options.zIndex все время определять, а не единожды? Выполните для позиции лево/верх, и сразу будет виден баг. И почему вы упорно определяете кнопку управления как целевой объект для плагина вместо самого меню?

И лишнего много.
Ответить с цитированием
Ответ


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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
переманную как условие в if блок xas Общие вопросы Javascript 3 02.02.2016 21:17
Добавление класса всем родительским элементам списка Torawhite Элементы интерфейса 0 01.05.2015 22:06
Сохранение данных после закрытия страницы HekracoB AJAX и COMET 12 02.01.2015 12:41
как заставить событие при resize сработать с небольшой задержкой один раз? mitiya Общие вопросы Javascript 3 21.10.2012 20:00
Как заставить выполняться обработчик после всех имеющихся обработчиков данного элемен Анатолий Саратовцев jQuery 2 08.10.2012 18:49