Slider with dynamic addition / removal of slides does not work - Uncaught TypeError: Cannot read property 'offsetLeft' of undefined. An error is somewhere here:

_slide: function() { this.animate = 1; this.$slider.css('overflow', 'hidden'); this.showAllTabs(); this.$wrapper.css('left', this.$tabs[this.current_position].offsetLeft*-1); // смещение текущего слайда в px this.arrowAction(); var self = this; var tmt = setTimeout(this.hideTabs.bind(self), 600); }, 

Full jsfiddle code

UPD html

 <div id="multiSelection" class="tabs-slider"> <ul class="tabs-slider-wrapper nav nav-tabs js_order_service_tabs"> <? $active = 'active'; ?> <? foreach($this->getServicesTabsFromRequestServiceInfo() as $tab_id => $tab_title): ?> <li class="js_order_request_service_tab_<?=$tab_id;?> js_order_request_service_tab <?=$active;?>" tabid="order_service_<?=$tab_id;?>"> <a href="#order_service_<?=$tab_id;?>" data-toggle="tab"><?=$tab_title;?> <i class="icon icon-remove js_remove_service_tab" data-order-service-tab-id="<?=$tab_id;?>"></i> </a> </li> <? if($active) $active = ''; ?> <? endforeach; ?> <li id="TabAdded" class="dropdown js_order_add_service_tab"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <i class="icon icon-plus"></i>&nbsp;Добавить услугу<b class="caret"></b> </a> <ul class="dropdown-menu order-add-service-dropdown-menu"> <? foreach($this->services as $code => $title): ?> <li><a data-service-id="<?=$code;?>" href="#"><?=$title;?></a></li> <? endforeach; ?> </ul> </li> <div class="clear"></div> </ul> <div class="border-bottom"></div> <div class="tabs-slider-nav"> <div id="moveTabsLeft" class="roller roller-wrap-style-left slider-previous"> <i class="icon icon-chevron-left icon-position-left "></i> </div> <div id="moveTabsRight" class="roller roller-wrap-style-right slider- next"> <i class="icon icon-chevron-right icon-position-right"></i> </div> </div> </div> <div class="request-service-tab-content tab-content"> <? $active = 'active'; ?> <? foreach($this->getServicesTabsContentFromRequestServiceInfo() as $tab_id => $tab_content): ?> <div class="order-service-tab tab-pane <?=$active;?>" id="order_service_<?=$tab_id;?>"><?=$tab_content;?></div> <? if($active) $active = ''; ?> <? endforeach; ?> 

Closed due to the fact that off-topic participants Grundy , Abyx , LEQADA , Saidolim , user194374 Jan 24 '16 at 12:19 .

It seems that this question does not correspond to the subject of the site. Those who voted to close it indicated the following reason:

  • “Questions asking for help with debugging (“ why does this code not work? ”) Should include the desired behavior, a specific problem or error, and a minimum code for playing it right in the question . Questions without an explicit description of the problem are useless for other visitors. See How to create minimal, self-sufficient and reproducible example . " - Grundy, Abyx, LEQADA, Saidolim, Community Spirit
If the question can be reformulated according to the rules set out in the certificate , edit it .

  • obviously this.$tabs[this.current_position] - undefined - Grundy
  • there is no html in the full code, therefore it doesn’t help much in reproducing the problem - Grundy
  • Marina, as in the past case, we can’t just delete a question if it has already been answered. But I rediscovered the second question to which a solution was found. - Nick Volynkin
  • @Grundy: maybe, on the basis of the answer to this question, you will write the answer to another question of Marina, and delete this one? - Nick Volynkin
  • thanks) ideally, it is better to remove this question, because it cannot be answered correctly. The answer is already in another similar (BUT non-duplicative) question - Marina Voronova

1 answer 1

Uncaught TypeError: Cannot read property 'offsetLeft' of undefined.

This error indicates that the offsetLeft property is attempted to be taken from an object that is undefined .

In this case, this expression

 this.$tabs[this.current_position] 

may return undefined for several reasons:

  1. this.current_position not defined
  2. this.$tabs - empty array (jQuery Object)
  3. in this.$tabs there is no field corresponding to this.current_position

Therefore, the first thing to do: check the values ​​of these variables at run time, either by debugging or by outputting them using console.log

 console.log('current position', this.current_position, 'tabs', this.$tabs, 'element',this.$tabs[this.current_position]); this.$wrapper.css('left', this.$tabs[this.current_position].offsetLeft*-1); // смещение текущего слайда в px 

After that, you can look further in specific directions.

For example, the log reads that this.$tabs is empty, therefore you need to check where this property is filled.

In the code it is filled in two places.

 init: function(options) { ... this.$tabs = $('.js_order_service_tabs > li'); ... } 

and

 getTabsWidth: function() { this.$tabs = $('.js_order_service_tabs > li'); ... } 

Since more in the code this property does not change - then you need to check whether there are elements in the markup that satisfy the specified selector, namely

 <!-- предположим что это все таки список, хотя может быть любой элемент с указанным классом --> <ul class="js_order_service_tabs"> <li><li><!-- выбираются все дочерние элементы li, не выбирая те которые могут быть на более низком уровне вложенности --> <li> <!-- данный элемент выберется --> <ul> <li></li> <!-- Данные не выберется --> ... </ul> </li> ... </ul> 

If items are present, then the problem is with the meter. Since the borders are not checked anywhere, and the counter is simply increased or decreased, it is quite possible that at some moment its value becomes either greater than the maximum index this.$tabs , or less than 0 .

  • Thanks for the detailed explanation! problem with this.current_position at some point it is not correctly determined - Marina Voronova
  • @MarinaVoronova, on the given piece it is hardly possible to add something. In principle, in the last paragraph about the problem with the counter described a little bit, maybe this is just your case - Grundy