JS實(shí)用控件——可滑動(dòng)列表項(xiàng)

有時(shí)候我們?cè)谝粋€(gè)list中要為列表項(xiàng)添加左右滑動(dòng)的效果茫经,通過(guò)滑動(dòng)出來(lái)的按鈕實(shí)現(xiàn)一些點(diǎn)擊事件薇组,這時(shí)候就可以用到本文所介紹的插件了肿仑。

照例序目,先上效果圖:


插件效果圖

我覺得這個(gè)效果還是挺高頻且實(shí)用的,奈何weui里面沒(méi)有這個(gè)擴(kuò)展楞卡,只能自己在網(wǎng)上搜索并改進(jìn)了霜运。為了方便使用脾歇,我已經(jīng)把左右滑動(dòng)效果封裝成了一個(gè)jquery插件了,讀者也可以根據(jù)需要修改其代碼做更多的擴(kuò)展淘捡。

1藕各、列表項(xiàng)html
先貼一下列表項(xiàng)的html代碼:

<a href="#" class="weui-media-box weui-media-box_appmsg swipte_item">
    <div class="weui-media-box__hd">
        <img class="weui-media-box__thumb" src="thumbnail.png">
    </div>
    <div class="weui-media-box__bd">
        <h4 class="weui-media-box__title"></h4>
        <p class="weui-media-box__desc"></p>
    </div>
    <li class="weui-swiped-btn weui-swiped-btn_warn swipe_btn">拒接</li>
    <li class="weui-swiped-btn accept_btn">接單</li>
</a>

其中,兩個(gè)li標(biāo)簽的class屬性可以自定義焦除,后續(xù)生成滑動(dòng)實(shí)例要用到激况,還有,我用的是weui膘魄,寫出來(lái)是如上的效果乌逐,讀者最好根據(jù)需求自行制作控件。

2创葡、列表項(xiàng)css
隨后是css代碼:

.weui-swiped-btn.weui-swiped-btn_warn.swipe_btn {
    color: white;
    position: absolute;
    right: -67px;
    width: 35px;
    text-align: center;
    height: 70px;
    line-height: 70px;
}

.weui-swiped-btn.accept_btn {
    color: white;
    background: #1AAD19;
    position: absolute;
    left: -67px;
    width: 35px;
    text-align: center;
    height: 70px;
    line-height: 70px;
}

讀者根據(jù)自己的需求修改就好了浙踢,這里面有個(gè)問(wèn)題,就是left灿渴、right的偏移和width不一樣洛波,我暫時(shí)沒(méi)找出問(wèn)題根源,只能在插件里通過(guò)增加滑動(dòng)偏移來(lái)抵消掉負(fù)偏移骚露,不知道哪位大神能指導(dǎo)一下蹬挤。

3、滑動(dòng)插件js代碼
借鑒前人代碼基礎(chǔ)上棘幸,已經(jīng)封裝成了JQuery代碼焰扳,能實(shí)現(xiàn)左右雙向的滑動(dòng):

/* * 
 * @brief 列表項(xiàng)左滑右滑功能創(chuàng)建
 *        使用方法:$('.itemWipe').touchWipe({itemBtn: '.item-button'});
 * @param itemWipe  條目樣式名
 *        itemBtn   滑動(dòng)后出現(xiàn)的按鈕樣式名(左右按鈕大小應(yīng)一致,傳入任一個(gè)即可)
 * @return 帶滑動(dòng)效果的列表項(xiàng)
 * */
(function ($) {
    $.fn.touchWipe = function (option) {
        var defaults = {
            itemBtn: '.item-delete', //刪除元素
        };
        var opts = $.extend({}, defaults, option); //配置選項(xiàng)
        var btnWidth = $(opts.itemBtn).width() + 32;  //此處有文章中說(shuō)的問(wèn)題误续,望指導(dǎo)

        var initX; //觸摸位置X
        var initY; //觸摸位置Y
        var moveX; //滑動(dòng)時(shí)的位置X
        var moveY; //滑動(dòng)時(shí)的位置Y
        var X = 0; //移動(dòng)距離X
        var Y = 0; //移動(dòng)距離Y
        var flagX = 0; //是否是左右滑動(dòng) 0為初始吨悍,1為左右,2為上下女嘲,在move中設(shè)置畜份,在end中歸零
        var objX = 0; //目標(biāo)對(duì)象位置

        $(this).on('touchstart', function (event) {
            //console.log('start..');
            var obj = this;
            initX = event.targetTouches[0].pageX;
            initY = event.targetTouches[0].pageY;
            //console.log(initX + ':' + initY);
            objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
            //console.log(objX);
            if (objX == 0) {
                $(this).on('touchmove', function (event) {
                    // 判斷滑動(dòng)方向,X軸阻止默認(rèn)事件欣尼,Y軸跳出使用瀏覽器默認(rèn)
                    if (flagX == 0) {
                        setScrollX(event);
                        return;
                    } else if (flagX == 1) {
                        event.preventDefault();
                    } else {
                        return;
                    }

                    var obj = this;
                    moveX = event.targetTouches[0].pageX;
                    X = moveX - initX;
                    if (X >= 0) {
                        var l = Math.abs(X);
                        obj.style.WebkitTransform = "translateX(" + l + "px)";
                        if (l > btnWidth) {
                            l = btnWidth;
                            obj.style.WebkitTransform = "translateX(" + l + "px)";
                        }
                    } else if (X < 0) {
                        var l = Math.abs(X);
                        obj.style.WebkitTransform = "translateX(" + -l + "px)";
                        if (l > btnWidth) {
                            l = btnWidth;
                            obj.style.WebkitTransform = "translateX(" + -l + "px)";
                        }
                    }
                });
            } else if (objX < 0) {
                $(this).on('touchmove', function (event) {
                    // 判斷滑動(dòng)方向,X軸阻止默認(rèn)事件停蕉,Y軸跳出使用瀏覽器默認(rèn)
                    if (flagX == 0) {
                        setScrollX(event);
                        return;
                    } else if (flagX == 1) {
                        event.preventDefault();
                    } else {
                        return;
                    }

                    var obj = this;
                    moveX = event.targetTouches[0].pageX;
                    X = moveX - initX;
                    if (X >= 0) {
                        var r = -btnWidth + Math.abs(X);
                        obj.style.WebkitTransform = "translateX(" + r + "px)";
                        if (r > 0) {
                            r = 0;
                            obj.style.WebkitTransform = "translateX(" + r + "px)";
                        }
                    } else { //向左滑動(dòng)
                        obj.style.WebkitTransform = "translateX(" + -btnWidth + "px)";
                    }
                });
            } else {
                $(this).on('touchmove', function (event) {
                    // 判斷滑動(dòng)方向愕鼓,X軸阻止默認(rèn)事件,Y軸跳出使用瀏覽器默認(rèn)
                    if (flagX == 0) {
                        setScrollX(event);
                        return;
                    } else if (flagX == 1) {
                        event.preventDefault();
                    } else {
                        return;
                    }

                    var obj = this;
                    moveX = event.targetTouches[0].pageX;
                    X = moveX - initX;
                    if (X <= 0) {
                        var r = btnWidth + Math.abs(X);
                        obj.style.WebkitTransform = "translateX(" + r + "px)";
                        if (r > 0) {
                            r = 0;
                            obj.style.WebkitTransform = "translateX(" + r + "px)";
                        }
                    } else { //向右滑動(dòng)
                        obj.style.WebkitTransform = "translateX(" + btnWidth + "px)";
                    }
                });
            }
        })

        //結(jié)束時(shí)判斷慧起,并自動(dòng)滑動(dòng)到底或返回
        $(this).on('touchend', function (event) {
            var obj = this;
            objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
            if (objX > -btnWidth / 2 && objX <= 0) {
                obj.style.transition = "all 0.2s";
                obj.style.WebkitTransform = "translateX(" + 0 + "px)";
                obj.style.transition = "all 0";
                objX = 0;
            } else if (objX > btnWidth / 2) {
                obj.style.transition = "all 0.2s";
                obj.style.WebkitTransform = "translateX(" + btnWidth + "px)";
                obj.style.transition = "all 0";
            } else if (objX < btnWidth / 2 && objX > 0) {
                obj.style.transition = "all 0.2s";
                obj.style.WebkitTransform = "translateX(" + 0 + "px)";
                obj.style.transition = "all 0";
                objX = 0;
            } else {
                obj.style.transition = "all 0.2s";
                obj.style.WebkitTransform = "translateX(" + -btnWidth + "px)";
                obj.style.transition = "all 0";
                objX = -btnWidth;
            }
            flagX = 0;
        })

        //設(shè)置滑動(dòng)方向
        function setScrollX(event) {
            moveX = event.targetTouches[0].pageX;
            moveY = event.targetTouches[0].pageY;
            X = moveX - initX;
            Y = moveY - initY;

            if (Math.abs(X) > Math.abs(Y)) {
                flagX = 1;
            } else {
                flagX = 2;
            }
            return flagX;
        }

        //鏈?zhǔn)椒祷?        return this;
    };

})(jQuery);

接下來(lái)菇晃,我會(huì)其中關(guān)鍵的地方和思路解釋清楚,具體內(nèi)容就需要讀者自己理解了:

1蚓挤、獲得首次點(diǎn)擊時(shí)的像素點(diǎn)(x,y)坐標(biāo)值磺送,并通過(guò)WebkitTransform獲得當(dāng)前列表項(xiàng)偏移的像素(objX等于0說(shuō)明沒(méi)有偏移驻子,大于0說(shuō)明向右偏移了,小于0說(shuō)明向左偏移了)估灿。

2崇呵、touchmove事件觸發(fā)后,獲得當(dāng)前的手指點(diǎn)住的像素點(diǎn)(x,y)坐標(biāo)馅袁,通過(guò)與初始坐標(biāo)相減域慷,獲得手指滑動(dòng)的方向(變量X大于0是右滑,小于0是左滑)汗销。

3犹褒、隨后,判斷當(dāng)前x軸的偏移量弛针,當(dāng)超過(guò)按鈕一半是自動(dòng)滑動(dòng)到底叠骑,小于一半是返回。

4削茁、最后宙枷,在你的js代碼中,通過(guò)$('.itemWipe').touchWipe({itemBtn: '.item-button'});即可為指定html標(biāo)簽綁定此功能付材。

以上朦拖。

github傳送地址:https://github.com/JunJieDing666/YouZhiGou

若有錯(cuò)誤煩請(qǐng)指出,有地方不理解歡迎討論厌衔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末璧帝,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子富寿,更是在濱河造成了極大的恐慌睬隶,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件页徐,死亡現(xiàn)場(chǎng)離奇詭異苏潜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)变勇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門恤左,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人搀绣,你說(shuō)我怎么就攤上這事飞袋。” “怎么了链患?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵巧鸭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我麻捻,道長(zhǎng)纲仍,這世上最難降的妖魔是什么呀袱? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮郑叠,結(jié)果婚禮上夜赵,老公的妹妹穿的比我還像新娘。我一直安慰自己锻拘,他們只是感情好油吭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著署拟,像睡著了一般婉宰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上推穷,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天心包,我揣著相機(jī)與錄音,去河邊找鬼馒铃。 笑死蟹腾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的区宇。 我是一名探鬼主播娃殖,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼议谷!你這毒婦竟也來(lái)了炉爆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤卧晓,失蹤者是張志新(化名)和其女友劉穎芬首,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逼裆,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡郁稍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胜宇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耀怜。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖桐愉,靈堂內(nèi)的尸體忽然破棺而出封寞,到底是詐尸還是另有隱情,我是刑警寧澤仅财,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站碗淌,受9級(jí)特大地震影響盏求,放射性物質(zhì)發(fā)生泄漏抖锥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一碎罚、第九天 我趴在偏房一處隱蔽的房頂上張望磅废。 院中可真熱鬧,春花似錦荆烈、人聲如沸拯勉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)宫峦。三九已至,卻和暖如春玫鸟,著一層夾襖步出監(jiān)牢的瞬間导绷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工屎飘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妥曲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓钦购,卻偏偏與公主長(zhǎng)得像檐盟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子押桃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349