|
|
|
[JQUERY] Помогите с проблемой дублирования функции
|
|||
|---|---|---|---|
|
#18+
Всем привет, только начинаю изучать программирование, поэтому для кого-то мой вопрос может показаться нубским и очень простым в решении, но я на него уже убил 3 дня своего времени и у меня все не получается с ним разобраться. Решил спросить у Вас чтобы совсем с ума не сойти. Ситуация следующая. Я делаю сайт с динамической подгрузкой новостей (т.е. прокрутил страничку до низа, автоматом подгрузились еще новости, итак по кругу до окончания новостей в базе). Далее мне нужно прикрутить функцию наводки мышки на изображение новости с последующим её "умным" ресайзом (сдвиг влево и вверх исходя из её оригинальных размеров). Все сделал, настроил, все работает, НО после каждой подгрузки новых новостей, нужно вызывать эту функцию еще раз (иначе новые новости не увеличиваются). Вот собственно с этим и загвоздка! Когда функция вызывается еще раз (подключил ее вызов после каждой подгрузки новостей) она "плюсуется" к ранее уже вызванным подобным функциям и получается какая то жесть. Картинки скачут, прыгают при наводке, меняются в размерах по нескольку раз и т.п. В общем нужно как то при каждом новом вызове одной и той же функции гасить работу предыдущей, причем как мне видется вообще ее обнулять в идеале, а не просто переставать на нее реагировать, так как при прокрутке/подгрузке примерно 100-150 страницы новостей, мне кажется что браузер начнет глючить от такого количества обрабатываемого кода (если я правильно понимаю как это все работает). Вот сама функция ховера (к сожалению не знаю как ее в теги кода у Вас засовывать): авторfunction demHover(){ $(".mDem").hover(function () { var $startWidth = $(this).width(); var $startHeight = $(this).height(); var $origWidth = $(this).attr('width'); var $origHeight = $(this).attr('orh'); $sdvigLeft = (($origWidth - $startWidth)/2)*(-1); $sdvigTop = (($origHeight - $startHeight)/2)*(-1); $(this).css({'marginLeft': $sdvigLeft + 'px', 'marginTop': $sdvigTop + 'px', 'width': $origWidth + 'px', 'position': 'absolute', 'maxWidth': '900px'}); }, function () { $(this).css({'marginLeft': '0', 'marginTop': '0', 'width': '310px', 'position': 'absolute', 'maxWidth': '100%'}); }); } А вот функция подгрузки новостей: автор//Custom JS - All custom front-end jQuery jQuery(document).ready(function() { // ################################# // Menu // ################################# var $menuli = $('#navi ul.menu').children("li"); var $current = $(".current-menu-item,.current-menu-parent,.current-menu-ancestor"); var $menuunit = $("#navi ul.menu li"); //add tri when submenu $menuli.children("a").each(function(i){ $(this).siblings("ul.sub-menu").parent().children("a").children("span.subtitle").before("<div class='nav_tri nav_tri_original'></div>"); }); //add hover block hidden $menuunit.prepend("<div class='navhover'></div>"); //hover on menu $menuunit.hover(function(){ $(this).not("ul ul li").children(".navhover").slideDown(100); $(this).children("a").children(".nav_tri").removeClass('nav_tri_original').addClass('nav_tri_active'); $(this).children("a").addClass('menu_active'); $("#navi li li").removeClass("navhover"); $(this).find('ul:first').delay(150).slideDown(200); },function(){ $(this).not($current).children("a").children(".nav_tri").removeClass('nav_tri_active').addClass('nav_tri_original'); $(this).children(".navhover").delay(100).slideUp(100); $(this).not($current).children("a").removeClass('menu_active'); $(this).find('ul:first').slideUp(100); }) $current.children("a").addClass('menu_active'); $current.children("a").children(".nav_tri").removeClass('nav_tri_original').addClass('nav_tri_active'); // ################################# // Search form // ################################# $(" input.textboxsearch ").focus(function(){ //$(this).siblings('.boxborder').fadeIn(500); $(this).parent().addClass("search-formhover"); }).focusout(function(){ //$(this).siblings('.boxborder').fadeOut(200); $(this).parent().removeClass("search-formhover"); }); $(".textboxsearch_header").focus(function(){ $(this).parent().removeClass("search-form_header").addClass("search_header_over"); $(this).parent().animate({width:"175px"},300); }).focusout(function(){ $(this).parent().removeClass("search_header_over").addClass("search-form_header"); $(this).parent().animate({width:"120px"},300); }); demHover(); // ################################# // Show - Hide // ################################ // Respond form $(".respondbtn").click(function () { $("#respondwrap").slideToggle(500, function() { if ($(this).is(":visible")) { $('html, body').animate({scrollTop: $(this).offset().top}, 500) } }); }); // Shortcode Fold - Unfold $(".job_title").click(function () { $(this).siblings('.job_desc').slideToggle(500, function() { if ($(this).is(":visible")) { $('html, body').animate({scrollTop: $(this).offset().top}, 500) } }); }); // Footer Contact info. $("#footer_trggle").click(function () { $("#footunder").slideToggle(500, function() { if ($(this).is(":visible")) { $('html, body').animate({scrollTop: $(this).offset().top}, 300) $("#footer_trggle").removeClass('footer_open').addClass('footer_close'); }else{ $("#footer_trggle").removeClass('footer_close').addClass('footer_open'); } }); }); // ################################# // Back Top // ################################ /**/ $("#top").hide(); $(function () { $(window).scroll(function(){ if ($(window).scrollTop()>100){ $("#top").fadeIn(300); }else{ $("#top").fadeOut(300); } }); $("#top").click(function(){ $('body,html').animate({scrollTop:0},500); return false; }); }); // ################################# // Verification Form // ################################ //verification Footer-contact-form jQuery(document).ready(function($){ $('form#contact-form').submit(function() { //$('form#contact-form .error').remove(); //$('form#contact-form .required').remove(); var hasError = false; $('.requiredField').each(function() { if(jQuery.trim($(this).val()) == '' || jQuery.trim($(this).val()) == 'Name*' || jQuery.trim($(this).val()) == 'Email*' || jQuery.trim($(this).val()) == 'Required' || jQuery.trim($(this).val()) == 'Invalid email') { $(this).attr("value","Required"); hasError = true; }else if($(this).hasClass('email')) { var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/; if(!emailReg.test(jQuery.trim($(this).val()))) { $(this).attr("value","Invalid email"); hasError = true; } }else{ } }); //After verification , print some infos. if(!hasError) { $('form#contact-form #idi_send').fadeOut('normal', function() { $(this).parent().append('<p class="sending">Sending...</p>'); }); var formInput = $(this).serialize(); $.post($(this).attr('action'),formInput, function(data){ $('form#contact-form').slideUp("fast", function() { $(this).before('<p class="success">Thanks, Your email was successfully sent.</p>'); $('.sending').fadeOut(); }); }); } return false; }); }); //verification Comment jQuery(document).ready(function($){ $('form#commentform').submit(function() { var hasError = false; $('.requiredFieldcomm').each(function() { if(jQuery.trim($(this).val()) == '' || jQuery.trim($(this).val()) == 'Name*' || jQuery.trim($(this).val()) == 'Email*' || jQuery.trim($(this).val()) == 'Required' || jQuery.trim($(this).val()) == 'Invalid email') { $(this).attr("value","Required"); hasError = true; } else if($(this).hasClass('email')) { var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/; if(!emailReg.test(jQuery.trim($(this).val()))) { $(this).attr("value","Invalid email"); hasError = true; } }else{ } }); //After verification , print some infos. if(!hasError) { $('form#commentform .send_btn').fadeOut('normal', function() { $(this).parent().append('<span class="sending">Sending...</span>'); }); var formInput = $(this).serialize(); $.post($(this).attr('action'),formInput, function(data){ $('form#commentform').slideUp("fast", function() { $(this).before('<p class="success">Thanks, Your comment was successfully sent.</p>'); $('.sending').fadeOut(); }); }); } return false; }); }); // ###################################### // //Responsive Layout - isotope trigger // ##################################### /**/ $(window).load(function(){ var $container = $('#list_wrap'); $container.imagesLoaded(function(){ $container.isotope({ //transformsEnabled: false, itemSelector : '.list_box' }); }); //Filterable $('#filterable a').click(function(){ $(this).css('outline','none'); $('ul#filterable .current').removeClass('current'); $(this).parent().addClass('current'); var selector = $(this).attr('data-filter'); $container.isotope({ filter: selector }); return false; }); //Resize screen $(window).bind('smartresize.isotope',function(){ $container.isotope({ itemSelector : '.list_box' }); }); //Infinits Scroll $container.infinitescroll({ navSelector : '#page-nav', // selector for the paged navigation nextSelector : '#page-nav a', // selector for the NEXT link (to page 2) itemSelector : '.list_box', // selector for all items you'll retrieve loading: { finishedMsg: '', img: '' } }, // call Isotope as a callback function( newElements ) { var newElems = jQuery(newElements).css({ opacity: 0 }); newElems.imagesLoaded(function(){ $container.isotope('appended', newElems); //projectThumbInit(); }); //After infi-fresh, need-run-js again: //click img-in-list to prettyphtot if(navigator.platform != "iPhone" || navigator.platform != 'iPod'){ $("a[rel^='prettyPhoto']").prettyPhoto({ animation_speed: 'fast', /* fast/slow/normal */ slideshow: false, /* false OR interval time in ms */ autoplay_slideshow: false, /* true/false */ opacity: 0.80, /* Value between 0 and 1 */ show_title: false, /* true/false */ allow_resize: true, /* Resize the photos bigger than viewport. true/false */ default_width: 500, default_height: 344, counter_separator_label: '/', /* The separator for the gallery counter 1 "of" 2 */ theme: 'light_square', /* light_rounded / dark_rounded / light_square / dark_square / facebook */ hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */ wmode: 'opaque', /* Set the flash wmode attribute */ autoplay: true, /* Automatically start videos: True/False */ modal: false, /* If set to true, only the close button will close the window */ overlay_gallery: false, /* If set to true, a gallery will overlay the fullscreen image on mouse over */ keyboard_shortcuts: true, /* Set to false if you open forms inside prettyPhoto */ social_tools:false }); } //jQuery(window).unbind('.infscr'); //hovoer on img-in-list demHover(); // need-run-js over }); //Infinits Scroll end }); // ################################# // Responsive Menus // ################################ (function($){ //variable for storing the menu count when no ID is present var menuCount = 0; //plugin code $.fn.mobileMenu = function(options){ //plugin's default options var settings = { switchWidth: 930, topOptionText: 'Menu', indentString: '---' }; //function to check if selector matches a list function isList($this){ return $this.is('ul, ol'); } //function to decide if mobile or not function isMobile(){ return ($(window).width() < settings.switchWidth); } //check if dropdown exists for the current element function menuExists($this){ //if the list has an ID, use it to give the menu an ID if($this.attr('id')){ return ($('#mobileMenu_'+$this.attr('id')).length > 0); } //otherwise, give the list and select elements a generated ID else { menuCount++; $this.attr('id', 'mm'+menuCount); return ($('#mobileMenu_mm'+menuCount).length > 0); } } //change page on mobile menu selection function goToPage($this){ if($this.val() !== null){document.location.href = $this.val()} } //show the mobile menu function showMenu($this){ $this.css('display', 'none'); $('#mobileMenu_'+$this.attr('id')).show(); } //hide the mobile menu function hideMenu($this){ $this.css('display', ''); $('#mobileMenu_'+$this.attr('id')).hide(); } //create the mobile menu function createMenu($this){ if(isList($this)){ //generate select element as a string to append via jQuery var selectString = '<select id="mobileMenu_'+$this.attr('id')+'" class="mobileMenu">'; //create first option (no value) selectString += '<option value="">'+settings.topOptionText+'</option>'; //loop through list items $this.find('li').each(function(){ //when sub-item, indent var levelStr = ''; var len = $(this).parents('ul, ol').length; for(i=1;i<len;i++){levelStr += settings.indentString;} //get url and text for option var link = $(this).find('a').attr('href'); var text = levelStr + $(this).clone().find('ul, ol, span').remove().end().text(); //add option selectString += '<option value="'+link+'">'+text+'</option>'; }); selectString += '</select>'; //append select element to ul/ol's container $this.parent().append(selectString); //add change event handler for mobile menu $('#mobileMenu_'+$this.attr('id')).change(function(){ goToPage($(this)); }); //hide current menu, show mobile menu showMenu($this); } else { alert('mobileMenu will only work with UL or OL elements!'); } } //plugin functionality function run($this){ //menu doesn't exist if(isMobile() && !menuExists($this)){ createMenu($this); } //menu already exists else if(isMobile() && menuExists($this)){ showMenu($this); } //not mobile browser else if(!isMobile() && menuExists($this)){ hideMenu($this); } } //run plugin on each matched ul/ol //maintain chainability by returning "this" return this.each(function() { //override the default settings if user provides some if(options){$.extend(settings, options);} //cache "this" var $this = $(this); //bind event to browser resize $(window).resize(function(){run($this);}); //run plugin run($this); }); }; })(jQuery); // ################################# // Triggle - Responsive Menus // ################################ $('#menu-navi').mobileMenu(); // ################################# // Triggle - flexslider // ################################ $('.flexslider').flexslider(); // ################################# // Reponsive sidebar open // ################################ $(".clum2_sidebar_unit h3 span").click(function () { $(this).parent().siblings('.widget_con').slideToggle(500, function() { /**/if ($(this).is(":visible")) { $(this).siblings('h3').children('span').removeClass('widget_open').addClass('widget_close'); }else{ $(this).siblings('h3').children('span').removeClass('widget_close').addClass('widget_open'); } }); }); // ################################# // Client for image in list // ################################# if(navigator.platform == "iPhone" || navigator.platform == "iPad" || navigator.platform == 'iPod') { $('img').css('margin-bottom','-6px'); } /*if(navigator.platform == "Linux armv71") { $('img').css('margin-bottom','-7px'); }*/ }); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2014, 12:59 |
|
||
|
[JQUERY] Помогите с проблемой дублирования функции
|
|||
|---|---|---|---|
|
#18+
Alex1233, куча-куча кода :) Его перелопачивать не хочется (на новой работе простыня похуже... потому за 4 дня уже в печёнках сидит перелопачивание чужого ). А вообще проблема решается просто. Есть такое понятие, как делегирование события (вроде так). БОльшая часть событий "всплывает" по элементам, пока не будет встречен последний обработчик. Так вот, делегирование - это обработка события не на самом элементе, а на элементе-родителе (прародителя etc.). Для этого в jquery сначала был введён метод live, а в последующем разработан метод on. Вот они то какраз и нужны... вешаем обработчики (методами выше) на элементы-родители нужных... И получаем нормальную обработку событий, при этом они присоединяются единожды (так как элемент-родитель не меняется... потому изначально повесили обработчик, и тот висит и ждёт событий :) ). Вроде так... не будет получаться - пишите :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2014, 13:18 |
|
||
|
[JQUERY] Помогите с проблемой дублирования функции
|
|||
|---|---|---|---|
|
#18+
ПрограмёрAlex1233, куча-куча кода :) Его перелопачивать не хочется (на новой работе простыня похуже... потому за 4 дня уже в печёнках сидит перелопачивание чужого ). А вообще проблема решается просто. Есть такое понятие, как делегирование события (вроде так). БОльшая часть событий "всплывает" по элементам, пока не будет встречен последний обработчик. Так вот, делегирование - это обработка события не на самом элементе, а на элементе-родителе (прародителя etc.). Для этого в jquery сначала был введён метод live, а в последующем разработан метод on. Вот они то какраз и нужны... вешаем обработчики (методами выше) на элементы-родители нужных... И получаем нормальную обработку событий, при этом они присоединяются единожды (так как элемент-родитель не меняется... потому изначально повесили обработчик, и тот висит и ждёт событий :) ). Вроде так... не будет получаться - пишите :) Ну код представлен на всякий случай, в принципе и описания я думаю достаточно. А второй (длиннющий) так и вовсе на всякий, всякий). Мне главное понять как гасить ту же самую функцию вызванную ранее, при повторном ее вызове. По поводу Вашего совета, к сожалению ничего не понял... Я только начинаю в этом деле разбираться и еще много чего не понимаю.. Можете какой то пример привести, хотя бы из нескольких строк? PS: Если вы имеете в виду обращение через родителя такого вида: автор$(this).children().children().('.mDem') или автор$(this).find('img') То так тоже пробовал, результат тот же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2014, 13:26 |
|
||
|
[JQUERY] Помогите с проблемой дублирования функции
|
|||
|---|---|---|---|
|
#18+
Alex1233, нееее )) не так... В кратце :) вот как мы обычно вешаем событие на элемент... например Код: javascript 1. и потому, если появляется новый элемент с классом myEl, то на него данный обработчик уже не подцепится... а в случае повторного вызова произойдёт именно то, о чём Вы говорили... то есть на ранее существующие элементы будет навешан ещё один обработчик... ну и начнётся косяк... во избежания этого, представим, что мы вставляем какие-то элементы в контейнер... например: Код: html 1. 2. 3. 4. 5. 6. потому учитывая, что контейнер не меняется, а меняются только child'ы, мы вешаем обработчик именно на контейнер и делаем это так (только один раз... повторно ничего уже не делаем): Код: javascript 1. 2. 3. Вот и всё... событие делегируется и всё работает как надо. P.S. Вам будет полезно почитать об обработке событий :) С ними всё просто, и если понять как это работает, то всё станет логично и просто :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2014, 13:39 |
|
||
|
[JQUERY] Помогите с проблемой дублирования функции
|
|||
|---|---|---|---|
|
#18+
Програмёр, да, судя по Вашему описанию и примеру это тог что нужно, я просто даже и не знал что так можно! =)) Ранее с этим "on" еще нигде не встречался, да и сейчас гуглю, как то не очень понятно по нему информация дается (как он работает и что делает). Сейчас попробую по Вашему примеру и отпишусь тут, помогло ли =) Но рассказано и показано все очень хорошо и понятно, спасибо Вам, прям как мини урок =) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2014, 13:47 |
|
||
|
[JQUERY] Помогите с проблемой дублирования функции
|
|||
|---|---|---|---|
|
#18+
Сууууууууууууууууупер! Работает! =)) То что нужно! Лучше и не придумаешь! Програмёр , спасибо Вам огромное за помощь и науку! Думаю мне это еще не раз пригодится! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.04.2014, 13:59 |
|
||
|
|

start [/forum/topic.php?fid=22&msg=38606402&tid=1447240]: |
0ms |
get settings: |
9ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
165ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
35ms |
get tp. blocked users: |
1ms |
| others: | 246ms |
| total: | 480ms |

| 0 / 0 |
