【问题标题】:Programmatically scroll ion-segment以编程方式滚动离子段
【发布时间】:2019-11-24 15:20:10
【问题描述】:

有什么方法可以控制段的滚动吗?在我的情况下,滑块和段相互依赖,当您滑动幻灯片时,overflowwing 段不会滑动,但会正确选择活动段

我的视图和控制器代码:

<ion-segment scrollable mode="md" (ionChange)="segmentChanged()" [(ngModel)]="segment" color="warning">
  <ion-segment-button mode="md" value="0">
    <p>Description</p>
  </ion-segment-button>
  <ion-segment-button mode="md" value="1">
    <p>Interconnections</p>
  </ion-segment-button>
  <ion-segment-button mode="md" value="2">
    <p>Declensions</p>
  </ion-segment-button>
</ion-segment>

<ion-slides (ionSlideDidChange)="slideChanged()" pager="true">
  <ion-slide>
    First
  </ion-slide>
  <ion-slide>
    second
  </ion-slide>
  <ion-slide>
    third
  </ion-slide>
</ion-slides>

segmentChanged() {
    this.slider.slideTo(this.segment);
}

async slideChanged() {
    this.segment = await this.slider.getActiveIndex();
}

片段本身可以正常工作,但是当滑动活动片段时,它会移到屏幕后面。

【问题讨论】:

  • 这实际上可能是可能的,但您还没有给我一个工作示例来重新创建您的场景。我不想花时间试图弄清楚如何启动并运行一个工作示例,请您扩展您的 sn-ps 以便我可以将某些内容复制并粘贴到像动画一样工作的测试环境中?示例是缺少幻灯片高度的样式,segment 是什么,您如何定义this.slider 等。我很快就开始了,但我只想测试一个理论,而不是花一个小时研究如何获得可测试的版本:)
  • 有人刚刚在another question提供了一个可能对你有用的解决方案
  • 感谢您指出这个解决方案,就像一个魅力!

标签: ionic-framework ionic4


【解决方案1】:

对于任何正在寻找 Ionic + React + TypeScript 解决方案的人:-

const [selectedTab, setSelectedTab] = useState<string>("0");
const sliderRef = useRef<HTMLIonSlidesElement>(null);

function onTabChange(value: string) {
    if (value === "" || value == null || value === undefined) return;

    sliderRef.current?.slideTo(parseInt(value));
}

async function onSlideChange() {
    let slideIndex = await sliderRef?.current?.getActiveIndex();

    if(slideIndex == null || slideIndex === undefined)
    return;

    setSelectedTab(slideIndex.toString());
    
    document.getElementById("tab-" + slideIndex)?.scrollIntoView({
        behavior: "smooth",
        block: "center",
        inline: "center",
    });
}

<IonSegment scrollable value={selectedTab} onIonChange={(e) => onTabChange(e.detail.value ?? "")}>
    <IonSegmentButton value="0" id="tab-0">
        <IonLabel>Tab 0</IonLabel>
    </IonSegmentButton>
    ....
</IonSegment>

<IonSlides ref={sliderRef} options={slideOpts} onIonSlideDidChange={() => {onSlideChange();}}>
    <IonSlide>
        <h1>Slide 0</h1>
    </IonSlide>
   ....
</IonSlides>

【讨论】:

    【解决方案2】:
    document.getElementById("your-id").scrollIntoView({
      behavior: 'smooth',
      block: 'center',
      inline: 'center'
    });
    
    <ion-segment scrollable [(ngModel)]="currentTab">
      <ion-segment-button value="subject" id="subject">
        <ion-label>ASSUNTO</ion-label>
      </ion-segment-button>
      <ion-segment-button value="book" id="books">
        <ion-label>LIVROS</ion-label>
      </ion-segment-button>
    </ion-segment>
    

    效果很好!

    【讨论】:

    • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
    【解决方案3】:

    我也遇到了同样的问题,最后用下面的代码解决了这个问题。

    您必须为每个“ion-segment-button”定义唯一的“id”

    <ion-segment-button SwipedTabs *ngFor="let category of tabs ; let i = index"
            value={{category}} (click)="selectTab(i)" **id="segment-{{i}}**">
            <ion-label>{{category}}</ion-label>
          </ion-segment-button>
    
    .ts code 
    async slideChanged() {
        this.activeIndex= await this.slider.getActiveIndex();
          document.getElementById("segment-" + activeIndex).scrollIntoView({
          behavior: 'smooth',
          block: 'center',
          inline: 'center'
        });
    }
    

    希望对你有帮助。

    【讨论】:

    • 是的,它有帮助:)
    【解决方案4】:

    看看这个,它应该对Ionic 4 Segments and Slides有帮助

    .html 可以是这样的:

    <ion-app>
      <ion-header>
       <ion-toolbar color="primary">
        <ion-title>Ionic 4 Segment</ion-title>
       </ion-toolbar>
      <ion-toolbar color="primary">
      <ion-segment scrollable>
        <ion-segment-button value="0" checked>
          <ion-icon name="call"></ion-icon>
          <ion-label>Call</ion-label>
        </ion-segment-button>
        <ion-segment-button value="1">
          <ion-icon name="cloud-upload"></ion-icon>
          <ion-label>Publish</ion-label>
        </ion-segment-button>
        <ion-segment-button value="2">
          <ion-icon name="paper"></ion-icon>
          <ion-label>Topic</ion-label>
        </ion-segment-button>
        <ion-segment-button value="3">
          <ion-icon name="code-working"></ion-icon>
          <ion-label>Query</ion-label>
        </ion-segment-button>
        <ion-segment-button value="4">
          <ion-icon name="open"></ion-icon>
          <ion-label>Open</ion-label>
        </ion-segment-button>
        <ion-segment-button value="5">
          <ion-icon name="search"></ion-icon>
          <ion-label>Search</ion-label>
        </ion-segment-button>
        <ion-segment-button value="6">
          <ion-icon name="create"></ion-icon>
          <ion-label>Write</ion-label>
        </ion-segment-button>
        <ion-segment-button value="7">
          <ion-icon name="book"></ion-icon>
          <ion-label>Read</ion-label>
        </ion-segment-button>
        <ion-segment-button value="8">
          <ion-icon name="trash"></ion-icon>
          <ion-label>Trash</ion-label>
        </ion-segment-button>
       </ion-segment>
      </ion-toolbar>
     </ion-header>
    
    <ion-content>
     <ion-slides>
      <ion-slide class="slide-1">
        Call
      </ion-slide>
      <ion-slide class="slide-2">
        Publish
      </ion-slide>
      <ion-slide class="slide-3">
        Topic
      </ion-slide>
      <ion-slide class="slide-1">
        Query
      </ion-slide>
      <ion-slide class="slide-2">
        Open
      </ion-slide>
      <ion-slide class="slide-3">
        Search
      </ion-slide>
      <ion-slide class="slide-1">
        Write
      </ion-slide>
      <ion-slide class="slide-2">
        Read
      </ion-slide>
      <ion-slide class="slide-3">
        Trash
      </ion-slide>
       </ion-slides>
      </ion-content>
     </ion-app>
    

    那么js是这样的

    var segment = document.querySelector('ion-segment');
    var slides = document.querySelector('ion-slides');
    
    segment.addEventListener('ionChange', (ev) => onSegmentChange(ev));
    slides.addEventListener('ionSlideDidChange', (ev) => 
     onSlideDidChange(ev));
    
    // On Segment change slide to the matching slide
    function onSegmentChange(ev) {
     slideTo(ev.detail.value);
    }
    
    function slideTo(index) {
     slides.slideTo(index);
    }
    
    // On Slide change update segment to the matching value
    async function onSlideDidChange(ev) {
     var index = await slides.getActiveIndex();
     clickSegment(index);
    }
    
    function clickSegment(index) {
      segment.value = index;
    }
    

    希望对大家有帮助

    【讨论】:

    • 是的,我已经看到了。在 ionic codepen 的示例中,没有段溢出。万一他们改变了,我想他们会遇到和我一样的问题
    • 是的,我遇到了同样的问题,如果当前段不在视图中,我只需要手动滑动到当前段。
    • 在滑动幻灯片时也滚动片段,将 clickSegment 函数替换为:function clickSegment(index) { segment.value = index; var active = segment.querySelectorAll('ion-segment-button')[index]; active.scrollIntoView({behavior: "smooth", inline: "center"}) }
    • @koMah 当我使用 active.scrollIntoView({behavior: "smooth", inline: "center"}) 内容进入上部。不适合我
    • 感谢@koMah,您的回答解决了我的对焦问题。完美!!!
    【解决方案5】:

    有趣的问题。

    不支持开箱即用。我不确定是否可以这样做,因为据我了解,除非暴露了 API,否则无法进入 ion-segment Web 组件的内部。

    这种封装是如何将组件放入页面而不与其他内容冲突的方式。

    如果它对您的项目非常重要,您可以考虑通过将片段和片段按钮组件的代码复制到您自己的单独版本中来创建自己的片段?

    【讨论】:

    猜你喜欢
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 2011-01-16
    • 2011-01-15
    • 2010-11-13
    • 2014-05-22
    • 2013-07-09
    相关资源
    最近更新 更多