1. 程式人生 > >學習Js(1)-使用Jquery實現滑動切換效果

學習Js(1)-使用Jquery實現滑動切換效果

1.前言雜談:
對於Javascript 是從大二就開始接觸了,那個時候剛開始接觸到web開發。在公司實習期間,由於什麼都不會,帶我師兄就讓我在百度傳課上看了一週的傳智播客的教學視訊,這才有點底子,可以寫寫正則,做表單驗證什麼的。到現在剛參加工作的時候,一直不太想從事前端方面的工作,覺得這個應該由公司前端來完成,我是用C#的,讓我能專注的寫後臺就好。
但現實比較那啥,領導要求啊,沒辦法,只能寫了。在接觸了一段時間後,也著實加深了自己對整個web開發的理解,從HTML到CSS,再到JS,雖然簡單,上手容易,但這是針對學習門檻上的。任何一個需要多人蔘與才能完成的網站專案,都需要對這三門語言進行深入理解才行。如:只有理解CSS的樣式繼承層次,對HTML程式碼結構做好規劃,才能夠良性的對網站中的頁面進行增添刪除,不至於顯得過於臃腫,也不會造成修改了某區域性的樣式之後,造成網站中其餘頁面錯位等情況。

2.需求說明:
網站首頁的廣告位,要增添左右滑動效果;
方便以後對廣告位進行擴充套件;
方便移植到其它需要滑動的區域中。

示例下載1

3.效果展示圖:
這裡寫圖片描述

4.重要程式碼展示及說明:

/*HTML程式碼結構*/
<body>
    <div class="cooperation">
        <div class="ico" >/*圖示*/
            <span id="icoL" ></span>
            <span id="icoR" ></span>
        </div
>
<!--網頁中的展示區域,這裡注意style中的三個屬性是必須的,如果滑動效果出現了彈跳或是不流暢等現象,可以對width屬性進行微調--> <ul class="img_display" style="overflow:hidden;white-space:nowrap;width: 1175px;" > <li ><img src="1.png"></li> <li ><img src="2.png"></li>
<li ><img src="3.png"></li> <li ><img src="4.png"></li> </ul> <!--這裡是隱藏區域,用來存放未展示出來的圖片--> <!--這裡有個問題就是,每次頁面載入的時候,隱藏區域的圖片未被展示出來,但仍然請求了伺服器的資源,這樣不太好,但一時也沒想到好的方法來儲存隱藏區域的資訊--> <ul class="img_hidden" style="display:none;"> <li><img src="5.png"></li> <li ><img src="6.png"></li> <li ><img src="7.png"></li> <li ><img src="8.png"></li> </ul> <div class="clear"></div> </div> </body>

下面是JS的程式碼展示:
這裡主要使用了Jquery中的animate函式。簡單來說這個函式是在指定時間內,將指定的元素逐漸移動到某一位置。animate用法參考

需要注意的是,指定函式位置時可以使用left,right,top,bottom,也可以使用marginLeft,marginTop等,區別在於前者需要HTML元素本身的position設定成為absolute即絕對定位,後者則沒什麼要求,都可以使用。

這裡其實涉及到CSS定位的一個層次問題,筆者在這方面沒有什麼瞭解,就不過多解釋了。

<script src="jquery-1.10.2.min.js"></script>
<script type="text/javascript" charset="utf-8">
    $("#icoL").bind("click",function(){
        MoveLeft(".img_display",4,"li",".img_hidden");
    });
    $("#icoR").bind("click",function(){
        MoveRight(".img_display",4,"li",".img_hidden");
    });

//往左滑動
//displayRegion 顯示區域
//displayNum 顯示區域中,顯示元素個數
//elementName 顯示元素標識
//HiddenRegion 隱藏區域
function MoveLeft(displayRegion, displayNum, elementName, HiddenRegion) {
    //防止重複點選
    if ($(displayRegion + " " + elementName).length >= displayNum + 1) {
        return;
    }

    //算滑動距離
    var width = parseInt($($(displayRegion)[0]).css("width"));
    var marginLeft = 0;
    $(displayRegion + " " + elementName).each(function (index) {
        if (index > 0) {
            //除去displayRegion中第一個元素的marginLeft,因為滑動是以第一個元素本身的左邊為基準開始滑動的。
            marginLeft += parseInt($(this).css("marginLeft"));
        }
    });

    //原始滑動距離
    var distance = (width - marginLeft) / displayNum;

    //由於在滑動結束時,會移除滑動到螢幕之外的元素,所以得考慮元素移除後,如何恢復原始的佈局;
    //令滑動前,displayRegion中第一個元素的marginLeft為a,第二個元素的為b;
    //若a==0,滑動距離應加上b;若a<>0,則無需加上b
    if (parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft")) == 0) {
        distance += parseInt($($(displayRegion + " " + elementName)[1]).css("marginLeft"));
    }

    //從HiddenRegion中取出第一個元素,填補到displayRegion得末尾
    var displayElem = $(HiddenRegion + " " + elementName + ":first")[0];
    $(displayRegion).append(displayElem.outerHTML);
    $(displayElem).detach();


    var hiddenElem = $(displayRegion + " " + elementName + ":first")[0];
    $(hiddenElem).animate({ marginLeft: 0 - distance }, 1000, function () {
        //滑動結束,移除滑出螢幕外的元素,填補到HiddenRegion得末尾,併除去滑動造成的marginLeft的改變
        $(HiddenRegion).append(hiddenElem.outerHTML);
        $(hiddenElem).detach();
        $(HiddenRegion + " " + elementName + ":last").removeAttr("style");
    });
}


//往右滑動
//displayRegion 顯示區域
//displayNum 顯示區域中,顯示元素個數
//elementName 顯示元素標識
//HiddenRegion 隱藏區域
function MoveRight(displayRegion, displayNum, elementName, HiddenRegion) {
    if ($(displayRegion + " " + elementName).length >= displayNum + 1) {
        return;
    }

    //算滑動距離
    var slideDistance = parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft"));

    //算元素的隱藏距離,即滑動前應該在displayRegion中的那裡加上新增的元素
    var hiddenDistance = 0 - parseInt($(displayRegion + " " + elementName)[0].offsetWidth);

    if (parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft")) == 0) {
        hiddenDistance -= parseInt($($(displayRegion + " " + elementName)[1]).css("marginLeft"));
    }

    var displayElem = $(HiddenRegion + " " + elementName + ":last")[0];
    $(displayElem).attr("style", "margin-left:" + hiddenDistance + "px");
    $(displayRegion).prepend(displayElem.outerHTML);
    $(displayElem).detach();

    $($(displayRegion + " " + elementName + ":first")[0]).animate({ marginLeft: slideDistance }, 1000, function () {
        $(HiddenRegion).prepend($(displayRegion + " " + elementName + ":last")[0].outerHTML);
        $($(displayRegion + " " + elementName + ":last")[0]).detach();
        $(displayRegion + " " + elementName + ":first").removeAttr("style");
    });
}
</script>

示例下載1
如果有更好的實現方法,請在下方法留言。

5.新需求說明:、
不改動原有的滑動效果;
網站首頁的廣告位不夠用,需要按地區進行分類;
當某一地區廣告位不足時,可以進行迴圈滑動;
全國地區類別中,可以通過滑動瀏覽到所有的公司,公司按加入時間降序排列。
方便在不同地區裡新增廣告位;
方便移植到其它需要滑動的區域中。

6.效果展示圖:
全國地區滑動

全國地區滑動

廣告位不足時,實現迴圈滑動

7.主要程式碼說明:
其實相較於剛開始的滑動效果,這裡只是新增了對全國地區和廣告位不足的處理,原始的滑動效果和HTML結構並沒有變化。仍舊是需要一個顯示區域和一個隱藏區域。

主要的HTML程式碼如下:

<body>
        <ul class="company_city">
            <li class="city on" city_abbr="QuanGuo">全國</li>
            <li class="city" city_abbr="HB">華北</li>
            <li class="city" city_abbr="HD">華東</li>
            <li><a href="" target="_self">全部公司 </a></li>
        </ul>
        <div class="ico" >
            <span id="icoL" ></span>
            <span id="icoR" ></span>
        </div>
    <div class="cooperation" >
        <!---全國 可通過滑動檢視所有公司 -->
        <ul class="img_display_QuanGuo" style="overflow:hidden;white-space:nowrap;width: 1175px;" >
            <li sortNum="4"><img src="4.png" ></li>
            <li sortNum="3"><img src="3.png" ></li>
            <li sortNum="2"><img src="2.png" ></li>
            <li sortNum="1"><img src="1.png" ></li>
        </ul>
        <ul class="img_hidden_QuanGuo" style="display:none;">

        </ul>
        <!-- 廣告位不夠用時,進行迴圈滑動-->
        <ul class="img_display_HB" style="overflow:hidden;white-space:nowrap;width: 1175px;display:none;" >
            <li sortNum="4"><img src="4.png" ></li>
            <li sortNum="3"><img src="3.png" ></li>
            <li sortNum="2"><img src="2.png" ></li>
            <li sortNum="1"><img src="1.png" ></li>
        </ul>
        <ul class="img_hidden_HB" style="display:none;">

        </ul> 

        <ul class="img_display_HD" style="overflow:hidden;white-space:nowrap;width: 1175px;display:none;" >
            <li sortNum="4"><img src="4.png" ></li>
            <li sortNum="3"><img src="3.png" ></li>
            <li sortNum="2"><img src="2.png" ></li>
            <li sortNum="1"><img src="1.png" ></li>         
        </ul>
        <ul class="img_hidden_HD" style="display:none;">
            <li sortNum="8" ><img src="8.png" ></li>
            <li sortNum="7" ><img src="7.png" ></li>
            <li sortNum="6" ><img src="6.png" ></li>
            <li sortNum="5" ><img  src="5.png" ></li>
        </ul>       
        <div class="clear"></div>
    </div>
</body>

這裡新增了兩點處理,一個是判斷廣告位是否足夠,即判斷相應地區的隱藏區域中是否有元素存在;另一個是增加了對全國地區的處理。

先說判斷廣告位的問題,如果隱藏區域中沒有元素存在,那麼在進行滑動之前,先要往隱藏區域中填充元素,怎麼填充視往左往右而定;在滑動完成之後要清空隱藏區域,回覆到原始狀態,以進行下一次滑動。

再說對全國地區的處理:在全國 這個選項被選中的情況下,使用者可以通過左右滑動看到所有的公司,這些公司按照一定規則排序,這裡的排序規則是給每個元素新增了一個sortNum屬性,sortNum越大排的就越前。
從HTML程式碼中可以看到,在img_display_QuanGuo中有四個元素,這是為了主頁顯示效果,而提前寫在頁面裡面的;而在img_hidden_QuanGuo中是沒有元素的,這就意味著每次滑動前,都要動態的新增元素到這個區域中;

新增元素的規則是這樣的:
使用者點選了向左滑動的按鈕;
JS會先獲取最左邊元素的sortNum;
如果sortNum是1,即最小的,那麼需要找到所有展示元素中sortNum最大的元素,並新增到隱藏區域中;
如果sortNum大於1,那麼需要找到比sortNum小,且離sortNum最近的一個元素,並把該元素新增到隱藏區域中;
進行滑動;
滑動完成時,將隱藏區域清空,回覆到原始狀態。

使用者點選了向右滑動的按鈕;
JS會先獲取最右邊元素的sortNum;
遍歷所有展示,找到比sortNum大,且離sortNum最近的一個元素,並把該元素新增到隱藏區域中;
如果找不到,則認為最右邊元素的sortNum是最大的,此時要進行迴圈滑動了,將sortNum=1的元素新增到隱藏區域中;
進行滑動;
滑動完成時,將隱藏區域清空,回覆到原始狀態。

$(function () {
    $(".company_city .city").each(function () {
        var abbr = $(this).attr("city_abbr");
        $(this).bind("click", function () {
            //切換不同地區的公司
            $(".cooperation").children().each(function (index, element) {
                $(element).css("display", "none");
            });
            $(".img_display_" + abbr).css("display", "block");

            //調整顯示字型
            $(".company_city .city").each(function () {
                $(this).removeClass("on");
            });
            $(this).addClass("on");

            //公司左右滑動
            $("#icoL").unbind("click");
            $("#icoR").unbind("click");
            $("#icoL").bind("click", function () {
                MoveRight(".img_display_" + abbr, 4, "li", ".img_hidden_" + abbr);


            });
            $("#icoR").bind("click", function () {
                MoveLeft(".img_display_" + abbr, 4, "li", ".img_hidden_" + abbr);
            });
        });
    });
    //點選 全國
    $(".company_city .city")[0].click();
});

//往左滑動
//displayRegion 顯示區域
//displayNum 顯示區域中,顯示元素個數
//elementName 顯示元素標識
//HiddenRegion 隱藏區域
function MoveLeft(displayRegion, displayNum, elementName, HiddenRegion) {
    //防止重複點選
    if ($(displayRegion + " " + elementName).length >= displayNum + 1) {
        return;
    }

    //若是全國地區,則可以滑動看到所有公司(按時間降序排序,越新排越前;即SortNum越大排越前),需要進行處理
    var isQuanGuo = false;
    if (displayRegion.indexOf("QuanGuo") > 0) {
        isQuanGuo = true;
    }
    if (isQuanGuo == true) {
        var sortNum = parseInt($($(displayRegion + " " + elementName + ":last")[0]).attr("SortNum"));
        //迴圈、依次遞減的查詢比sortNum小的元素。
        while ($(HiddenRegion + " " + elementName).length <= 0 && sortNum > 1) {
            $(displayRegion).parent().find(elementName).each(function () {
                if (parseInt($(this).attr("SortNum")) == (sortNum - 1)) {
                    $(HiddenRegion).prepend(this.outerHTML);
                    return false;
                }
            });
            if ($(HiddenRegion + " " + elementName).length <= 0) {
                sortNum--;
            }
        }

        //為迴圈滑動,此時要查詢SortNum最大的元素
        if (sortNum == 1) {
            var maxNum = parseInt($($(displayRegion).parent().find(elementName + ":first")[0]).attr("SortNum"));
            var maxIndex = 0;
            $(displayRegion).parent().find(elementName).each(function (index,element) {
                if(maxNum<parseInt($(this).attr("SortNum"))){
                    maxNum = parseInt($(this).attr("SortNum"));
                    maxIndex = index;
                }
            });
            $(HiddenRegion).prepend($(displayRegion).parent().find(elementName)[maxIndex].outerHTML);
        }
    }

    //判斷元素總數是否等於displayNum,若是,則需處理
    var isEelementLack = false;
    if ($(HiddenRegion + " " + elementName).length <= 0) {
        isEelementLack = true;
    }
    if (isEelementLack == true) {
        $(HiddenRegion).prepend($(displayRegion + " " + elementName)[0].outerHTML);
    }    

    //算滑動距離
    var width = parseInt($($(displayRegion)[0]).css("width"));
    var marginLeft = 0;
    $(displayRegion + " " + elementName).each(function (index) {
        if (index > 0) {
            //除去displayRegion中第一個元素的marginLeft,因為滑動是以第一個元素本身的左邊為基準開始滑動的。
            marginLeft += parseInt($(this).css("marginLeft"));
        }
    });

    //原始滑動距離
    var distance = (width - marginLeft) / displayNum;

    //由於在滑動結束時,會移除滑動到螢幕之外的元素,所以得考慮元素移除後,如何恢復原始的佈局;
    //令滑動前,displayRegion中第一個元素的marginLeft為a,第二個元素的為b;
    //若a==0,滑動距離應加上b;若a<>0,則無需加上b
    if (parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft")) == 0) {
        distance += parseInt($($(displayRegion + " " + elementName)[1]).css("marginLeft"));
    }

    //從HiddenRegion中取出第一個元素,填補到displayRegion得末尾
    var displayElem = $(HiddenRegion + " " + elementName + ":first")[0];
    $(displayRegion).append(displayElem.outerHTML);
    $(displayElem).detach();


    var hiddenElem = $(displayRegion + " " + elementName + ":first")[0];
    $(hiddenElem).animate({ marginLeft: 0 - distance }, 1000, function () {
        //滑動結束,移除滑出螢幕外的元素,填補到HiddenRegion的末尾,併除去滑動造成的marginLeft的改變
        $(HiddenRegion).append(hiddenElem.outerHTML);
        $(hiddenElem).detach();
        $(HiddenRegion + " " + elementName + ":last").removeAttr("style");

        //清空HiddenRegion,保證元素不夠的情況下也可以迴圈滑動;回到初始狀態
        if (isEelementLack == true || isQuanGuo == true) {
            $(HiddenRegion).empty();
        }
    });


}


//往右滑動
//displayRegion 顯示區域
//displayNum 顯示區域中,顯示元素個數
//elementName 顯示元素標識
//HiddenRegion 隱藏區域
function MoveRight(displayRegion, displayNum, elementName, HiddenRegion) {
    if ($(displayRegion + " " + elementName).length >= displayNum + 1) {
        return;
    }

    //若是全國地區,則可以滑動看到所有公司(按時間降序排序,越新排越前;即SortNum越大排越前),需要進行處理
    var isQuanGuo = false;
    if (displayRegion.indexOf("QuanGuo") > 0) {
        isQuanGuo = true;
    }
    if (isQuanGuo == true) {
        var sortNum = parseInt($($(displayRegion + " " + elementName + ":first")[0]).attr("SortNum"));
        //迴圈、一次遞增的查詢比sortNum大的元素
        while ($(HiddenRegion + " " + elementName).length <= 0 && sortNum <= $(displayRegion).parent().find(elementName).length) {
            $(displayRegion).parent().find(elementName).each(function () {
                if (parseInt($(this).attr("SortNum")) == (sortNum + 1)) {
                    $(HiddenRegion).prepend(this.outerHTML);
                    return false;
                }
            });
            if ($(HiddenRegion + " " + elementName).length <= 0) {
                sortNum++;
            }
        }
        //為迴圈滑動,此時要查詢SortNum為1的元素
        if ($(HiddenRegion + " " + elementName).length <= 0) {
            $(displayRegion).parent().find(elementName).each(function () {
                if (parseInt($(this).attr("SortNum")) == 1) {
                    $(HiddenRegion).prepend(this.outerHTML);
                    return false;
                }
            });
        }
    }


    //判斷元素總數是否等於displayNum,若是,則需處理
    var isEelementLack = false;
    if ($(HiddenRegion + " " + elementName).length <= 0) {
        isEelementLack = true;
    }

    if (isEelementLack == true) {
        $(HiddenRegion).prepend($(displayRegion + " " + elementName+":last")[0].outerHTML);
    }

    //算滑動距離
    var slideDistance = parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft"));

    //算元素的隱藏距離,即滑動前應該在displayRegion中的那裡加上新增的元素
    var hiddenDistance = 0 - parseInt($(displayRegion + " " + elementName)[0].offsetWidth);

    //這裡要注意hiddenDistance是負數,為了讓右邊新增的元素可以與原來的DIV中的第一個元素保持間距,需要做處理
    if (parseInt($($(displayRegion + " " + elementName)[0]).css("marginLeft")) == 0) {
        hiddenDistance -= parseInt($($(displayRegion + " " + elementName)[1]).css("marginLeft"));
    }

    //在顯示區域右邊新增元素
    var displayElem = $(HiddenRegion + " " + elementName + ":last")[0];
    $(displayElem).attr("style", "margin-left:" + hiddenDistance + "px");
    $(displayRegion).prepend(displayElem.outerHTML);
    $(displayElem).detach();

    $($(displayRegion + " " + elementName + ":first")[0]).animate({ marginLeft: slideDistance }, 1000, function () {
        //滑動結束,移除滑出螢幕外的元素,填補到HiddenRegion的頭部,併除去滑動造成的marginLeft的改變
        $(HiddenRegion).prepend($(displayRegion + " " + elementName + ":last")[0].outerHTML);
        $($(displayRegion + " " + elementName + ":last")[0]).detach();
        $(displayRegion + " " + elementName + ":first").removeAttr("style");

        //清空HiddenRegion,保證元素不夠的情況下也可以迴圈滑動
        if (isEelementLack == true || isQuanGuo==true) {
            $(HiddenRegion).empty();
        }
    });
}