jssor / slider

Touch swipe image slider/slideshow/gallery/carousel/banner mobile responsive bootstrap

Home Page:https://www.jssor.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Jssor slider in Angular2 not working properly when fetching images from .json file using http

estradamarkie opened this issue · comments

I'm having a problem with the slider when I requests the images via HTTP, the images doesn't appear on the page it looks like its hidden for some reason and when you inspect the source code jssor-slider="true" isn't in the div element.

I managed to replicate my issue on Plnkr, if you inspect the page it shows that my images are being fetched correctly but the slider isn't working as expected.
image

Template view

 <div id="jssor_1" style="position:relative;margin:0 auto;top:0px;left:0px;width:450px;height:450px;overflow:hidden;visibility:hidden;">
      <div data-u="slides" style="cursor:default;position:relative;top:0px;left:0px;width:450px;height:450px;overflow:hidden;">
        <div *ngFor="let img of data">
          <img data-u="image" src="{{img.image}}" alt="">
        </div>
      </div>
      <span data-u="arrowleft" class="jssora08l arrowUp" style="top:8px;left:8px;width:50px;height:50px;" data-autocenter="1"></span>
      <span data-u="arrowright" class="jssora08r arrowDown" style="bottom:8px;right:8px;width:50px;height:50px;" data-autocenter="1"></span>
    </div>

DOM tree when inspected

<my-app ng-version="2.3.0">
    <div id="jssor_1" style="position:relative;margin:0 auto;top:0px;left:0px;width:450px;height:450px;overflow:hidden;visibility:hidden;">
      <div data-u="slides" style="cursor:default;position:relative;top:0px;left:0px;width:450px;height:450px;overflow:hidden;">
        <!--template bindings={
  "ng-reflect-ng-for-of": "[object Object],[object Object]"
}--><div>
          <img alt="" data-u="image" ng-reflect-src="http://www.jssor.com/demos/img/landscape/01.jpg" src="http://www.jssor.com/demos/img/landscape/01.jpg">
        </div><div>
          <img alt="" data-u="image" ng-reflect-src="http://www.jssor.com/demos/img/landscape/03.jpg" src="http://www.jssor.com/demos/img/landscape/03.jpg">
        </div>
      </div>
      <span class="jssora08l arrowUp" data-autocenter="1" data-u="arrowleft" style="top:8px;left:8px;width:50px;height:50px;"></span>
      <span class="jssora08r arrowDown" data-autocenter="1" data-u="arrowright" style="bottom:8px;right:8px;width:50px;height:50px;"></span>
    </div>
  </my-app>

https://plnkr.co/edit/Bhk2t2RxggKw9a0vVckG?p=preview

@jssor Any idea about this? :)

commented

I checked https://plnkr.co/edit/Bhk2t2RxggKw9a0vVckG?p=preview
Nice coding, great job!
The DOM tree looks correct, but jssor slider was not initialized.

commented

It seems jssor_1_slider_init does not run.

So, where is the statement jssor_1_slider_init();?

commented

You can write log to observe the execution of the function jssor_1_slider_init.

        function jssor_1_slider_init() {
          console.log("jssor-initialization");
          var jssor_1_options = {
              $AutoPlay: 1,
              $DragOrientation: 2,
              $PlayOrientation: 2,
              $ArrowNavigatorOptions: {
                  $Class: $JssorArrowNavigator$
              }
          };
      
          var jssor_1_slider = new $JssorSlider$("jssor_1", jssor_1_options);
      
          /*responsive code begin*/
          /*remove responsive code if you don't want the slider scales while window resizing*/
          function ScaleSlider() {
              var refSize = jssor_1_slider.$Elmt.parentNode.clientWidth;
              if (refSize) {
                  refSize = Math.min(refSize, 600);
                  jssor_1_slider.$ScaleWidth(refSize);
              }
              else {
                  window.setTimeout(ScaleSlider, 30);
              }
          }
          ScaleSlider();
          $(window).bind("load", ScaleSlider);
          $(window).bind("resize", ScaleSlider);
          $(window).bind("orientationchange", ScaleSlider);
          /*responsive code end*/
      }

It seems jssor_1_slider_init does not run. So, where is the statement jssor_1_slider_init();?

This should be being initiated in the ngAfterInit() in the app.component.ts

even moving the function jssor_1_slider_init() to ngOnInit it's still not initiating the jssor_slide.

Updated plnkr: https://plnkr.co/edit/JovrnM9ooTvgnB5h8ZxN?p=preview

But, it's fine if the images are just coming from object literal within the app.component.ts

this.objLiteral= [
  {
    "image": "http://www.jssor.com/demos/img/landscape/01.jpg"
  },
  {
    "image": "http://www.jssor.com/demos/img/landscape/03.jpg"
  }  
]
commented

I logged the "jssor_1" and "jssor_2" element before jssor slider initializes,

    function jssor_1_slider_init() {
      console.log('testing this');
      var jssor_1_options = {
          $AutoPlay: 1,
          $DragOrientation: 2,
          $PlayOrientation: 2,
          $ArrowNavigatorOptions: {
              $Class: $JssorArrowNavigator$
          }
      };
      
      var jssor_1_element = document.getElementById("jssor_1");
      var jssor_2_element = document.getElementById("jssor_2");
      console.log(jssor_1_element.outerHTML);
      console.log(jssor_2_element.outerHTML);
  
      var jssor_1_slider = new $JssorSlider$("jssor_1", jssor_1_options);
      var jssor_2_slider = new $JssorSlider$("jssor_2", jssor_1_options);
  
      /*responsive code begin*/
      /*remove responsive code if you don't want the slider scales while window resizing*/
      function ScaleSlider() {
          var refSize = jssor_1_slider.$Elmt.parentNode.clientWidth;
          var refSize2 = jssor_2_slider.$Elmt.parentNode.clientWidth;
          if (refSize) {
              refSize = Math.min(refSize, 600);
              jssor_1_slider.$ScaleWidth(refSize);
              jssor_2_slider.$ScaleWidth(refSize);
          }
          else {
              window.setTimeout(ScaleSlider, 30);
          }
      }
      ScaleSlider();
      $(window).bind("load", ScaleSlider);
      $(window).bind("resize", ScaleSlider);
      $(window).bind("orientationchange", ScaleSlider);
      /*responsive code end*/
  }

And the following are html of the 2 element before jssor slider initializes.

<div id="jssor_1" style="position:relative;margin:0 auto;top:0px;left:0px;width:450px;height:450px;overflow:hidden;visibility:hidden;">
      <div data-u="slides" style="cursor:default;position:relative;top:0px;left:0px;width:450px;height:450px;overflow:hidden;">
        <!--template bindings={
  "ng-reflect-ng-for-of": null
}-->
      </div>
      <span class="jssora08l arrowUp" data-autocenter="1" data-u="arrowleft" style="top:8px;left:8px;width:50px;height:50px;"></span>
      <span class="jssora08r arrowDown" data-autocenter="1" data-u="arrowright" style="bottom:8px;right:8px;width:50px;height:50px;"></span>
    </div>
VM437 jssor-options.js:15 <div id="jssor_2" style="position:relative;margin:0 auto;top:0px;left:0px;width:450px;height:450px;overflow:hidden;visibility:hidden;">
        <div data-u="slides" style="cursor:default;position:relative;top:0px;left:0px;width:450px;height:450px;overflow:hidden;">
          <!--template bindings={
  "ng-reflect-ng-for-of": "[object Object],[object Object]"
}--><div>
            <img alt="" data-u="image" style="margin-top:0 !important; margin-left: 95px !important;" ng-reflect-src="http://www.jssor.com/demos/img/landscape/01.jpg" src="http://www.jssor.com/demos/img/landscape/01.jpg">
          </div><div>
            <img alt="" data-u="image" style="margin-top:0 !important; margin-left: 95px !important;" ng-reflect-src="http://www.jssor.com/demos/img/landscape/03.jpg" src="http://www.jssor.com/demos/img/landscape/03.jpg">
          </div>
        </div>
        <span class="jssora08l" data-autocenter="1" data-u="arrowleft" style="top:8px;left:8px;width:50px;height:50px;"></span>
        <span class="jssora08r" data-autocenter="1" data-u="arrowright" style="bottom:8px;right:8px;width:50px;height:50px;"></span>
      </div>

You can see slides of "jssor_1" is empty with no images filled.
As you say, it loads data via ajax. So, you'd wait for ajax call returns and fills images, and then run jssor_1_slider_init(); after that.

Thanks, I did try running jssor_1_slider_init() in the success callback but that didn't work however wrapping the slider_init() in a timeout setTimeout(() => { jssor_1_slider_init(); }) fixed it. Not a big fan of setTimeout for async call but unless there's another way this is fine for now.

Thanks :)