手機(jī)端 Demo
手機(jī)端主要使用了
touchstarttouchmovetouchend三個(gè)事件
html:
<div class="in_box">
<div class="in_list touch_list">
<div class="t">
<div class="l">
投資限額<span>(最大1000萬(wàn))</span>
</div>
<div class="r">
<span class="count" id="limit1">10</span>萬(wàn)
</div>
</div>
<div class="b">
<div class="ball">
<div class="touch"></div>
</div>
</div>
</div>
<div class="in_list touch_list">
<div class="t">
<div class="l">
扣款額度<span>(最大10萬(wàn))</span>
</div>
<div class="r">
<span class="count" id="limit2">5</span>萬(wàn)
</div>
</div>
<div class="b">
<div class="ball">
<div class="touch"></div>
</div>
</div>
</div>
<div class="in_list">
<div class="t">
<div class="l">
授權(quán)期限
</div>
<div class="r">
<span id="limit3">3</span>年
</div>
</div>
<div class="b">
<ul class="selyears">
<li>1年</li>
<li>2年</li>
<li class="cur">3年</li>
</ul>
</div>
</div>
</div>
css:
.bswmaim>.m2>.in_box>.in_list{margin-bottom:.05rem;padding:.2rem 0;}
.bswmaim>.m2>.in_box>.in_list>.t{line-height:.25rem;}
.bswmaim>.m2>.in_box>.in_list>.t>.l{float:left;color:#333;font-size:.15rem;}
.bswmaim>.m2>.in_box>.in_list>.t>.l>span{color:#666;font-size:.12rem;}
.bswmaim>.m2>.in_box>.in_list>.t>.r{float:right;width:.5rem;text-align:center;font-size:.15rem;color:#009fe8;position:relative;}
.bswmaim>.m2>.in_box>.in_list>.t>.r:before{content:" ";display:block;position:absolute;bottom:0;top:0;left:0;right:0;margin:auto auto 0 auto;height:1px;background-color:#ccc;}
.bswmaim>.m2>.in_box>.in_list>.b{position:relative;min-height:.25rem;padding:.05rem 0;}
.bswmaim>.m2>.in_box>.touch_list>.b{margin-right:.25rem;overflow:visible;}
.bswmaim>.m2>.in_box>.touch_list>.b:after{content:" ";display:block;position:absolute;left:0;top:0;right:0;bottom:0;height:.05rem;background-color:#cddae0;margin:auto;border-radius:.025rem;box-shadow:0 0 7px 1px #bdcdd5 inset;width:3.4rem;}
.bswmaim>.m2>.in_box>.touch_list>.b>.ball{position:absolute;left:0;top:.05rem;width:.25rem;height:.25rem;overflow:visible;}
.bswmaim>.m2>.in_box>.touch_list>.b>.ball>.touch{content:" ";display:block;position:absolute;width:.25rem;height:.25rem;border-radius:50%;background:url(/Images/Area/AccountMan/BSWarrant/icon1.png) center center no-repeat #009fe8;background-size:.115rem .115rem;left:0;top:0;z-index:10;}
.bswmaim>.m2>.in_box>.touch_list>.b>.ball:before{content:"";display:block;position:absolute;width:3.15rem;height:.05rem;background-color:#009fe8;border-radius:.025rem 0 0 .025rem;left:0;top:.1rem;z-index:9;left:-3.15rem;}
js:
//手指觸摸交互
$(function () {
var startXs = [], x = 0, endX = 0, startX = 0;
//數(shù)據(jù)初始化
initData();
//觸摸事件
$('.touch_list').each(function (index, element) {
$(element).find('.touch').on('touchstart', function (event) {
x = startXs[index];
//console.log(1);
event.preventDefault();
//console.log(event);
var touch = event.originalEvent.targetTouches[0];
startX = touch.pageX - x;
});
$(element).find('.touch').on('touchmove', function (event) {
event.preventDefault();
//console.log(event);
var touch = event.originalEvent.targetTouches[0];
endX = touch.pageX;
x = endX - startX;
var all = $(this).parent('.ball').parent('.b').css('width');
all = all.substr(0, all.length - 2) * 1;
x = x > all ? all : (x < 0 ? 0 : x);
var num = x / all * 100;
$(this).parent('.ball').css({ "left": num + '%' });
var money = parseInt(num / 100 * (index == 0 ? 1000 : 10));
$('#limit' + (index + 1)).html(money);
});
$(element).find('.touch').on('touchend', function (event) {
startXs[index] = x;
});
});
//期限 點(diǎn)擊交互
$('.selyears').find('li').click(function () {
$(this).addClass('cur').siblings('li').removeClass('cur');
$('#limit3').html($(this).index() + 1);
});
//投資人初始化數(shù)據(jù)函數(shù)
function initData() {
if ($('.touch_list').length) {
var money1 = $('#limit1').html() * 1;
var money2 = $('#limit2').html() * 1;
$('.touch_list').each(function (index, element) {
if (index == 0) {
var num = money1 / 1000 * 100;
} else if (index == 1) {
var num = money2 / 10 * 100;
}
var all = $(element).find('.b').css('width');
all = all.substr(0, all.length - 2) * 1;
var length = num / 100 * all;
startXs.push(length);
num = num > 100 ? 100 : (num < 0 ? 0 : num);
$(element).find('.ball').animate({ "left": num + '%' }, 500);
});
};
};
});
效果 GIF
GIF.gif
擴(kuò)展上面的 Demo
- 參考網(wǎng)易云音樂(lè)進(jìn)度條的設(shè)計(jì)、交互來(lái)實(shí)現(xiàn)
1.gif
- 主要修改的地方:使按鈕可以在進(jìn)度條的左右兩側(cè)各多出自身一半的寬度
源碼
- HTML 與上面之前的不變,修改的只是 JS && CSS
- CSS
.bswmaim>.m2>.in_box>.in_list{margin-bottom:.05rem;padding:.2rem 0;}
.bswmaim>.m2>.in_box>.in_list>.t{line-height:.25rem;}
.bswmaim>.m2>.in_box>.in_list>.t>.l{float:left;color:#333;font-size:.15rem;}
.bswmaim>.m2>.in_box>.in_list>.t>.l>span{color:#666;font-size:.12rem;}
.bswmaim>.m2>.in_box>.in_list>.t>.r{float:right;width:.5rem;text-align:center;font-size:.15rem;color:#009fe8;position:relative;}
.bswmaim>.m2>.in_box>.in_list>.t>.r:before{content:" ";display:block;position:absolute;bottom:0;top:0;left:0;right:0;margin:auto auto 0 auto;height:1px;background-color:#ccc;}
.bswmaim>.m2>.in_box>.in_list>.b{position:relative;min-height:.25rem;padding:.05rem 0;}
.bswmaim>.m2>.in_box>.touch_list>.b{overflow:visible;}
.bswmaim>.m2>.in_box>.touch_list>.b:after{content:" ";display:block;position:absolute;left:.125rem;top:0;right:.125rem;bottom:0;height:.05rem;background-color:#cddae0;margin:auto;border-radius:.025rem;box-shadow:0 0 7px 1px #bdcdd5 inset;}
.bswmaim>.m2>.in_box>.touch_list>.b>.ball{position:absolute;left:0;right:.25rem;top:.05rem;height:.25rem;overflow:visible;}
.bswmaim>.m2>.in_box>.touch_list>.b>.show:before{content:"";display:block;position:absolute;width:.125rem;background-color:#fff;border-radius:.025rem 0 0 .025rem;top:0;bottom:0;left:0;z-index:10;}
.bswmaim>.m2>.in_box>.touch_list>.b>.ball>.touch{position:absolute;width:.25rem;height:.25rem;border-radius:50%;background:url(/Images/Area/AccountMan/BSWarrant/icon1.png) center center no-repeat #009fe8;background-size:.115rem .115rem;left:0;top:0;z-index:1;overflow:visible;}
.bswmaim>.m2>.in_box>.touch_list>.b>.show>.touch:before{content:"";display:block;position:absolute;width:3.025rem;height:.05rem;background-color:#009fe8;border-radius:.025rem 0 0 .025rem;top:.1rem;z-index:0;left:-3.025rem;}
- JS (這里寫了較為詳細(xì)的注釋)
$(function () {
var startXs = [],//接收每個(gè)按鈕移動(dòng)距離的數(shù)組
x = 0,//移動(dòng)距離計(jì)算時(shí)所用的初始值
endX = 0,//接收手指移動(dòng)后位置的數(shù)值
startX = 0;//接收手機(jī)觸摸開(kāi)始時(shí)位置的數(shù)值 其實(shí)算的是元素的相對(duì)的起始位置的 0 0 點(diǎn)的坐標(biāo)
//數(shù)據(jù)初始化
initData();
//觸摸事件
$('.touch_list').each(function (index, element) {
//開(kāi)始觸摸事件
$(element).find('.touch').on('touchstart', function (event) {
x = startXs[index];//拿出移動(dòng)數(shù)值中當(dāng)前元素移動(dòng)的距離數(shù)值
//console.log(x);
event.preventDefault();//禁止瀏覽器的默認(rèn)事件
//console.log(event);
var touch = event.originalEvent.targetTouches[0];//獲取觸摸對(duì)象
startX = touch.pageX - x;//用當(dāng)前的觸摸位置減去之前移動(dòng)的距離 獲得的是 按鈕最初 `left = 0` 在頁(yè)面中的 pageX 的值
//console.log(startX);
});
//觸摸時(shí)移動(dòng)事件
$(element).find('.touch').on('touchmove', function (event) {
event.preventDefault();//禁止瀏覽器的默認(rèn)事件
//console.log(event);
var touch = event.originalEvent.targetTouches[0];//獲取觸摸對(duì)象
endX = touch.pageX;//獲取此時(shí)手指移動(dòng)時(shí)的位置
x = endX - startX;//用移動(dòng)時(shí)的數(shù)值減去手指從 `left = 0`的 pageX 的值得到按鈕需要移動(dòng)的距離
var all = all || parseInt($(this).parent('.ball').parent('.b').css('width')) - 2 * (parseInt($(this).css('width')));//按鈕 `left` 從 0 到 100 總需移動(dòng)的距離數(shù)值
//console.log(all);
x = x > all ? all : (x < 0 ? 0 : x);//容錯(cuò)
var num = x / all * 100;//獲取移動(dòng)距離所占的百分比
//判斷移動(dòng)距離的百分比距離是否超過(guò) .touch 一半的寬度所占的百分比
//1.25 為 .touch 一半的寬度 3.025 為 移動(dòng) 100% 的寬度
if (num > (.125 / 3.025 * 100)) {
$(this).parent('.ball').addClass('show');//在 css 中做相應(yīng)的轉(zhuǎn)換
} else {
$(this).parent('.ball').removeClass('show');//在 css 中做相應(yīng)的轉(zhuǎn)換
}
$(this).css({ "left": num + '%' });//移動(dòng)樣式
var money = parseInt(num / 100 * (index == 0 ? 1000 : 10));
$('#limit' + (index + 1)).html(money);//改變 相應(yīng)的元素的 html 數(shù)值
});
//觸摸事件結(jié)束后
$(element).find('.touch').on('touchend', function (event) {
event.preventDefault();//禁止瀏覽器的默認(rèn)事件
startXs[index] = x;//結(jié)束時(shí)更新數(shù)組中相應(yīng)的 手指從觸摸到移動(dòng)的距離
});
});
//期限 點(diǎn)擊交互
$('.selyears').find('li').click(function () {
$(this).addClass('cur').siblings('li').removeClass('cur');
$('#limit3').html($(this).index() + 1);
});
//投資人初始化數(shù)據(jù)函數(shù)
function initData() {
//判斷當(dāng)前用戶是否為 投資人
if ($('.touch_list').length) {
//獲取 html 中相應(yīng)的數(shù)值
var money1 = $('#limit1').html() * 1;
var money2 = $('#limit2').html() * 1;
$('.touch_list').each(function (index, element) {
//num 為 html 中的數(shù)值轉(zhuǎn)換為所占的相應(yīng)的寬度百分比數(shù)值
if (index == 0) {
var num = money1 / 1000 * 100;
} else if (index == 1) {
var num = money2 / 10 * 100;
}
var all = all || parseInt($(element).find('.b').css('width')) - 2 * (parseInt($(element).find('.touch').css('width')));//按鈕 `left` 從 0 到 100 總需移動(dòng)的距離數(shù)值
//console.log(all);
var length = num / 100 * all;//按鈕移動(dòng)的距離
startXs.push(length);//傳入移動(dòng)的距離至數(shù)組中
num = num > 100 ? 100 : (num < 0 ? 0 : num);//容錯(cuò)
//判斷移動(dòng)距離的百分比距離是否超過(guò) .touch 一半的寬度所占的百分比
//1.25 為 .touch 一半的寬度 3.025 為 移動(dòng) 100% 的寬度
if (num > (.125 / 3.025 * 100)) {
$(element).find('.ball').addClass('show');//在 css 中做相應(yīng)的轉(zhuǎn)換
}
$(element).find('.touch').animate({ "left": num + '%' }, 500);//移動(dòng)動(dòng)畫(huà)
});
};
};
});
- 效果圖
2.gif
總結(jié)
主要需要知道的是按鈕從
left從 0 ~ 100 所需要移動(dòng)的總距離是多少,然后算出手指在移動(dòng)時(shí)的距離占前面總距離的百分比
主要的難點(diǎn)是:我將按鈕和她左側(cè)的藍(lán)色的線條放在了一個(gè)元素上,在剛開(kāi)始移動(dòng)的時(shí)候會(huì)出現(xiàn)多出來(lái)的.125rem 的長(zhǎng)度的藍(lán)色線條,正常來(lái)說(shuō)他是不應(yīng)該顯示出來(lái)的
image.png
就是上圖這個(gè)地方會(huì)有問(wèn)題,后來(lái)我使用了一個(gè)遮罩的方法具體思路如下 :
在 css 中給 .ball 增加一個(gè) .show 類名,在 JS 中判斷移動(dòng)的距離或者說(shuō)是移動(dòng)距離所占的百分比是否大于了這段小距離所占的百分比,大于的話增加這個(gè)類名 show 否則去掉,這個(gè)類名控制了 左側(cè)的白色遮罩以及按鈕左側(cè)的藍(lán)色的線條的顯示與隱藏
PC 端 Demo
PC 端主要使用了
mousedown-- 當(dāng)按下鼠標(biāo)按鈕時(shí),mousemove-- 獲得鼠標(biāo)指針在頁(yè)面中的位置 ,mouseup-- 當(dāng)松開(kāi)鼠標(biāo)按鈕時(shí) 三個(gè)事件
- HTML
<!-- 投資人模塊 -->
<div class="in_box">
<div class="in_list touch_list">
<div class="l">
投資限額
</div>
<div class="r">
<div class="line">
<div class="ball">
<div class="touch" title="鼠標(biāo)拖動(dòng)改變金額"></div>
</div>
</div>
<div class="txt">
<!-- 程序調(diào)取投資人投資限額數(shù)據(jù) 無(wú)數(shù)據(jù)默認(rèn)為 10 -->
<span class="count" id="limit1">10</span>萬(wàn)
</div>
</div>
</div>
<div class="in_list touch_list">
<div class="l">
扣款額度
</div>
<div class="r">
<div class="line">
<div class="ball">
<div class="touch" title="鼠標(biāo)拖動(dòng)改變金額"></div>
</div>
</div>
<div class="txt">
<!-- 程序調(diào)取投資人扣款限額數(shù)據(jù) 無(wú)數(shù)據(jù)默認(rèn)為 5 -->
<span class="count" id="limit2">5</span>萬(wàn)
</div>
</div>
</div>
<div class="in_list">
<div class="l">
授權(quán)期限
</div>
<div class="r">
<ul class="selyears clearfix">
<!-- 程序判斷投資人授權(quán)期限數(shù)據(jù)為相應(yīng) li 加類名 cur 無(wú)數(shù)據(jù)默認(rèn)給第三個(gè)加 -->
<li>1年</li>
<li>2年</li>
<li class="cur">3年</li>
</ul>
<!-- 程序調(diào)取投資人授權(quán)期限數(shù)據(jù) 無(wú)數(shù)據(jù)默認(rèn)為 3 -->
<input id="limit3" type="hidden" value="3">
</div>
</div>
</div>
- CSS
.in_box {
margin: 0 auto;
width: 600px;
}
.in_box .in_list {
line-height: 32px;
margin-bottom: 22px;
overflow: hidden;
}
.in_box .in_list .l {
float: left;
width: 140px;
color: #333;
font-size: 16px;
margin-right: 20px;
text-align: right;
}
.in_box .in_list .r {
float: left;
width: 440px;
overflow: hidden;
}
.in_box .in_list .r .line {
float: left;
width: 230px;
position: relative;
height: 32px;
margin-right: 30px;
}
.in_box .in_list .r .line:after {
content: " ";
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
margin: auto;
height: 6px;
width: 260px;
box-shadow: 0 1px 4px rgba(0,0,0,.4) inset;
border-radius: 4px;
}
.in_box .in_list .r .line .ball {
position: absolute;
width: 30px;
height: 20px;
top: 0;
bottom: 0;
margin: auto;
z-index: 10;
}
.in_box .in_list .r .line .ball:before {
content: " ";
display: block;
position: absolute;
width: 230px;
height: 6px;
background-color: #009ce4;
box-shadow: 0 1px 4px rgba(0,0,0,.3) inset;
border-radius: 4px 0 0 4px;
left: -230px;
top: 0;
bottom: 0;
margin: auto;
}
.in_box .in_list .r .line .ball .touch {
width: 100%;
height: 100%;
background: url(/Images/Areas/AccountMan/BSWarrant/spriteImg.png) no-repeat;
background-position: 0 0;
border-radius: 4px;
box-shadow: 0 0 3px rgba(0,0,0,.3) inset,1px 1px 5px rgba(0,0,0,.4);
cursor: pointer;
}
.in_box .in_list .r .txt {
float: left;
margin-left: 20px;
color: #00a0e9;
font-size: 18px;
font-weight: 600;
}
.in_box .in_list .r .txt span {
color: #00a0e9;
}
.in_box .in_list .r .selyears li {
float: left;
width: 80px;
height: 32px;
box-shadow: 0 0 0 1px #ccc inset;
text-align: center;
font-size: 16px;
color: #666;
line-height: 32px;
cursor: pointer;
margin-right: 10px;
}
.in_box .in_list .r .selyears li.cur {
box-shadow: none;
background: url(/Images/Areas/AccountMan/BSWarrant/spriteImg.png) no-repeat;
background-position: 0 -20px;
}
.bd_rule {
border-top: 1px solid #e6e6e6;
padding: 38px 0 64px;
}
.bd_rule .txt {
line-height: 36px;
color: #999;
font-size: 14px;
padding-left: 90px;
position: relative;
width: 470px;
margin: 0 auto;
}
.bd_rule .txt:before {
content: "授權(quán)須知";
position: absolute;
line-height: 36px;
height: 36px;
left: 0;
top: 0;
}
/*雪碧圖*/
.spriteImg {
background: url(/Images/Areas/AccountMan/BSWarrant/spriteImg.png) no-repeat;
}
.touchicon {
height: 20px;
width: 30px;
background-position: 0 0;
}
.selectact {
height: 32px;
width: 80px;
background-position: 0 -20px;
}
- JS
//鼠標(biāo)拖動(dòng)交互
$(function () {
var startXs = [],//接收每個(gè)按鈕移動(dòng)距離的數(shù)組
x = 0,//移動(dòng)距離計(jì)算時(shí)所用的初始值
endX = 0,//接收鼠標(biāo)移動(dòng)后位置的數(shù)值
startX = 0;//接收鼠標(biāo)開(kāi)始時(shí)位置的數(shù)值 其實(shí)算的是元素的相對(duì)的起始位置的 0 0 點(diǎn)的坐標(biāo)
var down = false;//判斷鼠標(biāo)是否按下
//數(shù)據(jù)初始化
initData();
//鼠標(biāo)拖拽事件
$('.touch_list').each(function (index, element) {
//mousedown 當(dāng)按下鼠標(biāo)按鈕時(shí)
$(element).find('.touch').on('mousedown', function (event) {
down = true;
x = startXs[index];
//console.log(event);
event.preventDefault();
startX = event.pageX - x;
console.log(1);
});
//mousemove 獲得鼠標(biāo)指針在頁(yè)面中的位置
$(element).on('mousemove', function (event) {
//判斷鼠標(biāo)是否按下
if (down) {
event.preventDefault();
//console.log(event);
endX = event.pageX;
x = endX - startX;
var all = 230;//230 為 .line 的長(zhǎng)度
x = x > all ? all : (x < 0 ? 0 : x);
var num = x / all * 100;
$(this).find('.ball').css({ "left": x + 'px' });
var money = parseInt(num / 100 * (index == 0 ? 1000 : 10));
$('#limit' + (index + 1)).html(money);
console.log(2);
}
});
//mouseup 當(dāng)松開(kāi)鼠標(biāo)按鈕時(shí)
$(element).on('mouseup', function (event) {
event.preventDefault();
down = false;
startXs[index] = x;
console.log(down);
});
});
//期限 點(diǎn)擊交互
$('.selyears').find('li').click(function () {
$(this).addClass('cur').siblings('li').removeClass('cur');
$('#limit3').val($(this).index() + 1);
});
//投資人初始化數(shù)據(jù)函數(shù)
function initData() {
if ($('.touch_list').length) {
var money1 = $('#limit1').html() * 1;
var money2 = $('#limit2').html() * 1;
$('.touch_list').each(function (index, element) {
if (index == 0) {
var num = money1 / 1000;
} else if (index == 1) {
var num = money2 / 10;
}
var length = num * 230;//230 為 .line 的長(zhǎng)度
length = length > 230 ? 230 : (length < 0 ? 0 : length);
startXs.push(length);
$(element).find('.ball').animate({ "left": length + 'px' }, 1000);
});
};
};
});
- 瀏覽器效果圖
3.gif
- 總結(jié):
PC 和 手機(jī)端最主要的區(qū)別除了使用的事件之外還有就是元素移動(dòng)范圍的不同,PC 端范圍是按鈕的相對(duì)父級(jí)
.touch_list,這樣使得拖拽的范圍擴(kuò)大了些,不會(huì)顯得有些"笨重"




