ionic实现A-Z城市选择

本文介绍如何在Ionic项目中实现城市选择器,包括A-Z字母索引列表和搜索功能。通过计算屏幕高度确保字母索引在不同设备上的适配性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:
http://blog.youkuaiyun.com/lishihong108/article/details/53422950

在ionic项目中怎么实现城市选择A-Z字母索引列表呢?效果图如下所示:
  这里写图片描述

可以看到搜索框可以直接过滤搜索对应的城市;右侧点击或滑动对一个的字母,左侧滚动到对应的位置,接下来详细介绍怎么实现。
首先说下布局:
右边的字母栏是绝对定位过去的,通过计算屏幕高度来做适配,保证在任意屏幕的手机上都会均等显示。
html代码如下:

<ion-view view-title="城市选择" style="background:#fff;">
	<ion-nav-buttons side="left">
	    <div style="width:32px;padding-left:2px;" ng-click="$ionicGoBack()">
	      <i class="icon ion-ios-arrow-left" style="color:#828a99;font-size:32px;line-height:32px;"></i>
	    </div>
	</ion-nav-buttons>
	<ion-nav-title>
	    <form style="width:100%;height:44px;">
			<div class="item-input-inset" style="border:0;height:100%;width:100%;">
				<div class="item-input-wrapper" style="background-color:#fff;height:32px;border:solid 1px #E1E1E1;width:100%;">
					<i class="icon ion-android-search placeholder-icon" style="color: #CCCCCC;font-size:20px;cursor:pointer;"></i>
					<input type="search" placeholder="请输入城市名称" style="font-size:14px;color:#262626;height:22px;width:100%;" ng-change="startDot()" ng-model="$parent.cityName">
					<i class="ion-close-circled" ng-click="searchEmpty()" style="color: #CCCCCC;display:{{searchEmptyShow ? 'block' : 'none'}};"></i>
				</div>
			</div>
		</form>
  	</ion-nav-title>

    <ion-content scroll="true">
    	 <div style="padding-bottom:120px;">
    	 	<div id="city_{{d.iniData}}" style="margin-right:30px;" ng-repeat="d in cityDatas | filter:cityName">
    	 		<div class="choose_city_abc" style="font-size: 18px;background:#F5F5F5;padding:8px 10px;">{{d.iniData}}</div>
				<div class="choose_city_data">
					<div class="choose_city_border" style="padding:7px 0px" ng-repeat="city in d.datas | filter:cityName" ng-click="confirmCity('{{city.zoneCityId}}','{{city.zoneCity}}')">{{city.zoneCity}}</div>
					<div class="choose_city_border" style="padding:7px 0px;border-bottom:0;" ng-show="{{d.datas.length==0}}">暂无城市</div>
				</div>
    	 	</div>
    	 </div>
    </ion-content> 
    <div style="width:28px;text-align:center;position:absolute;right:0;top:{{44+dis_ios}}px;margin:2px 0;color:#458AFF;" > 
 		<div ng-repeat="c in indexs" style="width:100%;height:{{hIndex}}px;" ng-touchmove="mTouch('{{c}}')" ng-touchend="mRelease()" ng-click="mTouch('{{c}}')">
 			{{c}}
 		</div> 
 	</div>
	
 	<div style="position:fixed;left:47%;top:47%;width:40px;height:40px;background:#ddd;display:flex;justify-content:center;align-items:center;font-size:20px;color:#262626;" ng-show="showMiddle">
        {{hint}}
    </div>
</ion-view>

用到的css代码如下:

.choose_city_abc{
	border-bottom:solid 1px #e1e1e1;
	border-right:solid 1px #e1e1e1;
	border-top:solid 1px #e1e1e1;
}
.choose_city_border{
	border-bottom:solid 1px #e1e1e1;
	border-right:solid 1px #e1e1e1;
}
.choose_city_data{
	padding-left: 22px;
}
.choose_city_border:nth-last-child(2){
	border-bottom:0;
	border-right:solid 1px #e1e1e1;
}

controller里面的如下:

$scope.searchEmptyShow=false;//是否显示清除输入的图标
$scope.showMiddle=false; //是否在屏幕中央显示选中的字母索引
$scope.hIndex=($(window).height()-44-4)/26;//右边侧边栏每个字母的高度,是屏幕高度减去标题栏的44,减去页面样式中的margin-top:2px,margin-bottom:2px,再除以26,这样以保证在各个手机屏幕上的字母的距离的均等性
var chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$scope.indexs=[];
loadData();
for(var i=0;i<chars.length;i++){
	$scope.indexs.push(chars.charAt(i));//获取字母数组
}
$scope.startDot=function(){//判断清除输入框的图标是否显示
	if($scope.cityName.length=0 || $scope.cityName==""){
		$scope.searchEmptyShow=false;
	}else{
		$scope.searchEmptyShow=true;
	}
};
$scope.searchEmpty=function(){//点击清除输入框的图标的点击事件
	$scope.searchEmptyShow=false;
	$scope.cityName="";
};
$scope.mTouch=function(c){
$scope.showMiddle=true;  
$scope.hint=c;

/*var scroll = document.getElementById("city_"+$scope.hint).offsetTop - $ionicScrollDelegate.getScrollPosition().top; 
$ionicScrollDelegate.scrollBy(0,scroll,false); */ //方式一

$location.hash("city_"+$scope.hint);
$ionicScrollDelegate.anchorScroll(true); //方式2
//如果发现左侧不能滚动,把此处的true改成false
};

$scope.mRelease=function(){  
	$timeout(function(){
		$scope.showMiddle=false;
	},300);
};
function loadData(){//从本地的一个包含全国各城市的json文件中加载数据
	$ionicLoading.show(); $http.get("json/city.json").success(function(data) {
   	$scope.cityDatas=data.dataList;
   	$ionicLoading.hide();
  });
} 

在计算右边滚动位置时候,可以用方式1,计算滚动条滚动位置后,再进行滚动,也可以用方式2,通过描点的方式滚动。
下载地址:http://download.youkuaiyun.com/detail/lishihong108/9718410


以上是之前的,有位很细心的撸友发现了几个bug,现在修改如下:
html代码:

<ion-view view-title="城市选择" style="background:#fff;">
    <ion-nav-buttons side="left">
        <div style="width:32px;padding-left:2px;" ng-click="$ionicGoBack()">
          <i class="icon ion-ios-arrow-left" style="color:#828a99;font-size:32px;line-height:32px;"></i>
        </div>
    </ion-nav-buttons>
    <ion-nav-title>
        <form style="width:100%;height:44px;">
            <div class="item-input-inset" style="border:0;height:100%;width:100%;">
                <div class="item-input-wrapper" style="background-color:#fff;height:32px;border:solid 1px #E1E1E1;width:100%;">
                    <i class="icon ion-android-search placeholder-icon" style="color: #CCCCCC;font-size:20px;cursor:pointer;"></i>
                    <input type="search" placeholder="请输入城市名称" style="font-size:14px;color:#262626;height:22px;width:100%;" ng-change="startDot()" ng-model="$parent.cityName">
                    <i class="ion-close-circled" ng-click="searchEmpty()" style="color: #CCCCCC;display:{{searchEmptyShow ? 'block' : 'none'}};"></i>
                </div>
            </div>
        </form>
    </ion-nav-title>

    <ion-content>
         <div style="padding-bottom:120px;">
            <div id="city_{{d.iniData}}" style="margin-right:30px;" ng-repeat="d in cityDatas | filter:cityName">
                <div class="choose_city_abc" style="font-size: 18px;background:#F5F5F5;padding:8px 10px;">{{d.iniData}}</div>
                <div class="choose_city_data">
                    <div class="choose_city_border" style="padding:7px 0px" ng-repeat="city in d.datas | filter:cityName" ng-click="confirmCity('{{city.zoneCityId}}','{{city.zoneCity}}')">{{city.zoneCity}}</div>
                    <div class="choose_city_border" style="padding:7px 0px;border-bottom:0;" ng-show="{{d.datas.length==0}}">暂无城市</div>
                </div>
            </div>
         </div>
    </ion-content> 
    <div ng-touchend="mRelease()" ng-touchmove="mTouch($event)" ng-click="mTouch($event)" style="width:28px;text-align:center;position:absolute;right:0;top:44px;margin:2px 0;color:#458AFF;"> 
        <div ng-repeat="c in indexs" style="width:100%;height:{{hIndex}}px;">
            {{c}}
        </div> 
    </div>

    <div style="position:fixed;left:47%;top:47%;width:40px;height:40px;background:#ddd;display:flex;justify-content:center;align-items:center;font-size:20px;color:#262626;" ng-show="showMiddle">
        {{hint}}
    </div>
</ion-view>

主要改变是把事件放在父层div,使边滑动边显示对应位置的字母,并且滚动到对应位置。

css代码未变

controller代码:

$scope.searchEmptyShow=false;//是否显示清除输入的图标
$scope.showMiddle=false; //是否在屏幕中央显示选中的字母索引
$scope.hIndex=(window.screen.height-44-4)/26;//右边侧边栏每个字母的高度,是屏幕高度减去标题栏的44,减去页面样式中的margin-top:2px,margin-bottom:2px,再除以26,这样以保证在各个手机屏幕上的字母的距离的均等性
var chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$scope.indexs=[];
loadData();
for(var i=0;i<chars.length;i++){
    $scope.indexs.push(chars.charAt(i));//获取字母数组 
}
$scope.startDot=function(){//判断清除输入框的图标是否显示
    if($scope.cityName.length=0 || $scope.cityName==""){
        $scope.searchEmptyShow=false;
    }else{
        $scope.searchEmptyShow=true;
    }
};
$scope.searchEmpty=function(){//点击清除输入框的图标的点击事件
    $scope.searchEmptyShow=false;
    $scope.cityName="";
};
 
$scope.mTouch=function(event){ 
  var positionX=event.pageX || event.touches[0].pageX;
  var positioinY=event.pageY || event.touches[0].pageY;
  var ele = document.elementFromPoint(positionX,positioinY);  
  if(!ele){
  	return;
  }
  var c=ele.innerText;
  if(!c || c==" " || c.length!=1){
  	return;
  }
  $scope.hint=c; 
  $scope.showMiddle=true;    

  var scroll = document.getElementById("city_"+$scope.hint).offsetTop -    $ionicScrollDelegate.getScrollPosition().top; 
  $ionicScrollDelegate.scrollBy(0,scroll,true);
  var ele = document.getElementsByTagName("ion-content");  
  ele[0].style.overflow="auto";  //解决滑动右边的导航字母后,左边不能再滚动的bug,可以试着注释这两句来测试这个问题

};

$scope.mRelease=function(){
    $timeout(function(){
        $scope.showMiddle=false;
    },300); 
};
function loadData(){//从本地的一个包含全国各城市的json文件中加载数据
    $ionicLoading.show(); 
    $http.get("json/city.json").success(function(data) {
     $scope.cityDatas=data.dataList;
     $ionicLoading.hide();
 });
} 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值