Onsen-ui combining carousel with range input & act

2019-06-24 05:42发布

I have a onsen-ui project and I'm using Monaca Cloud IDE to build it. I'm still struggling with a few key concepts when it comes to onsen-ui, but I can't figure it out from readying the docs.

At the moment I'm trying to implement a "range" input on a onsen carousel-item. The range input is rendered just fine, but I can't slide it. When I try to slide it, I actually scroll the carousel. My current idea to solve this problem is to set the entire carousel to "disabled", since it's not that important for the user to scroll back to the previous page (although that would be nice). One of my biggest issues is the action listeners and how to call methods pertaining to ons-.. components.

<ons-page>
  <ons-carousel fullscreen swipeable auto-scroll auto-scroll-ratio ="0.2">
    <ons-carousel-item>
      <img class="custom_logo_top_welcome" src="images/Leaf_PNG.png"/>
      <br />
      <br />
      <br />
      <p class="custom_p_welcome">Start saving today and see the likely value when you retire.</p>
      <div class="custom_bottom_div_welcome"><p class="custom_bottom_p_welcome">Swipe left</p></div>

    </ons-carousel-item>
    <ons-carousel-item >
      <p class="custom_dateOfBirth_p_setup">Please enter your date of birth:</p>
      <div class="custom_datePicker_div_setup"><p>Test Div</p></div>
      <p class="custom_dateOfRetirement_p_setup">What is your expected retirement age?</p>
      <input type="range" class="range custom_range_setup" />

      <div class="custom_bottom_div_setup"><ons-button class="custom_bottom_button_setup" onclick = "navToIndex()">Done</ons-button></div>

    </ons-carousel-item>
  </ons-carousel>
</ons-page>

So basically what I'm thinking about doing here is to set the carousel to "disabled" when the user swipes to the second carousel item.

How do I do this? If there's a better way to solve the issue, please feel free to share.

Thanks in advance!

4条回答
Lonely孤独者°
2楼-- · 2019-06-24 05:44

Here is the code that solves the issue in the question. It is a combination of the other two answers given, so I can't take all the credit for this.

Code in index.html:

document.addEventListener('ons-carousel:postchange', function(event){
  if (event.activeIndex === 1) {
    rangeTouchEvents();
  }
});

Function called in above code are as follows:(Note: In my project, this code is in an external .js file which is loaded in index.html)

function rangeTouchEvents()
  {
    ons.ready(function() {
      var range = document.getElementById("range");
      range.addEventListener('touchstart', function () {
        document.querySelector("ons-        carousel").removeAttribute("swipeable");
      });
      range.addEventListener('touchend', function () {
        document.querySelector("ons-carousel").setAttribute("swipeable", "");
      });
    });
  }

Code Explained:

The first snippet of code is where you add an action listener to the <ons-carousel> This listens for any changes, and if a change occurs, it tests to see whether or not the active index of the carousel is 1. Index 1 is the index on which the range element is displayed (in my application). If the carousel is on index 1, it will call the function, otherwise nothing will happen.

The function is simply adding action listeners to the "range" element. The first action listener fires when a user touches the range element, and switches the scrollable attribute to "false". As soon as the user releases the range element, the second action listener fires. The second action listener sets the scrollable attribute back to "true".

The reason why you can't simply add the "touchStart" and "touchEnd" action listeners to the range element is because of the onsen framework. It doesn't allow you to run scripts from within <ons-page> (at least that's what I've experienced.) You can run the code to add the action listeners in index.html, but it won't work, since the "range" element only gets created when the carousel reaches index 1, thus the action listeners have nothing to bind to yet. That is why you first have to put an action listener on the <ons-carousel> to check when index 1 is active. When it is active, the range element will be created, and the action listeners can be bound to it.

Credit to @AndiPavlio and @FranDios

查看更多
Lonely孤独者°
3楼-- · 2019-06-24 05:44

For Onsen UI 2.x you should listen to 'postchange' not 'ons-carousel:postchange'.

Like so:

document.addEventListener('postchange', function(event){
  // Handle the event
});
查看更多
放荡不羁爱自由
4楼-- · 2019-06-24 05:56

Is there a reason why you use a carousel to show page/form information instead of a navigator? It's usually more convenience for this kind of use case.

In any case, for Onsen UI 1.x what you want to do is like this:

document.addEventListener('ons-carousel:postchange', function(event){
  if (event.activeIndex === 1) { // Second item
    event.carousel.setSwipeable(false);
  }
});

Hope it helps!

查看更多
萌系小妹纸
5楼-- · 2019-06-24 06:11

If you want to be able to use the range element but still be able to swipe the carousel, you can do something like this:

HTML

Add id="range" to the range element, like this:

<input id="range" style="position: absolute; top: 300px" type="range" class="range custom_range_setup" /></div>

JS

ons.ready(function() {
  var range = document.getElementById("range");
  range.addEventListener('touchstart', function () {
    document.querySelector("ons-carousel").removeAttribute("swipeable");
  });
  range.addEventListener('touchend', function () {
    document.querySelector("ons-carousel").setAttribute("swipeable", "");
  });
});

When you'll touch the range element, the carousel swipeable attribute will be removed, until the touch action ends. This will allow you to have both the functionalities working.

Hope it helps!

查看更多
登录 后发表回答