JavaScript >> Javascript 文檔 >  >> Tags >> CSS

使用 jQuery 和 CSS3 更好地選擇元素

在創建您的網頁設計時,您總是力求在不同瀏覽器中保持一致的外觀。不幸的是,您網站中最基本的元素之一——瀏覽器控件——也被證明是最難設計的。其中一些,例如 select 元素,超過一定程度是不可能改變的。

這就是為什麼,今天我們要構建一個腳本,它將採用普通的 select 元素,並將其替換為更好看的標記驅動版本,同時保持所有功能完好無損。

HTML

像往常一樣,我們從教程的 HTML 部分開始。我正在使用 HTML5 標記,因為它為我們提供了一些有用的功能,例如 data 屬性, 使用它我們可以將任意數據添加到頁面的標記中。

select-jquery.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Making Better Select Elements with jQuery and CSS3 | Tutorialzine Demo</title>

<link rel="stylesheet" type="text/css" href="css/styles.css" />

</head>
<body>

<div id="page">
    <h1>Your Product</h1>

    <form method="post" action="">

        <!-- We are going to use jQuery to hide the select element and replace it -->

        <select name="fancySelect" class="makeMeFancy">

            <!-- Notice the HTML5 data attributes -->

            <option value="0" selected="selected" data-skip="1">Choose Your Product</option>
            <option value="1" data-icon="img/products/iphone.png" data-html-text="iPhone 4&lt;i&gt;in stock&lt;/i&gt;">iPhone 4</option>
            <option value="2" data-icon="img/products/ipod.png" data-html-text="iPod &lt;i&gt;in stock&lt;/i&gt;">iPod</option>
            <option value="3" data-icon="img/products/air.png" data-html-text="MacBook Air&lt;i&gt;out of stock&lt;/i&gt;">MacBook Air</option>
            <option value="4" data-icon="img/products/imac.png" data-html-text="iMac Station&lt;i&gt;in stock&lt;/i&gt;">iMac Station</option>
        </select>
    </form>

</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script src="js/script.js"></script>

</body>
</html>

你可以看到我們正在使用 data 選項中嵌入信息的屬性 選擇的元素 .我們包括了一個產品圖標和一個富文本描述,這兩者稍後都會顯示在 select 元素的改進版本中。

我設置了一個任意的 data-skip 第一個元素上的屬性,以便我們的腳本知道不將其包含在生成的列表中。您也可以只檢查 data-icon 是否存在 和 data-html-text 屬性並在必要時跳過該元素。

文檔底部包含 jQuery 1.4.3 版(撰寫本文時庫的最新版本)和我們的 script.js,您可以在下一步中看到。

jQuery

在 document.ready 事件中,jQuery 檢查 select 元素 ,並使用數據屬性,構建您可以在下面看到的標記,該標記被附加在 select 之後 :

<div style="width: 144px;" class="tzSelect">
    <div class="selectBox">iMac Station</div>
    <ul class="dropDown">
        <li><img src="img/products/iphone.png"><span>iPhone 4<i>in stock</i></span></li>
        <li><img src="img/products/ipod.png"><span>iPod <i>in stock</i></span></li>
        <li><img src="img/products/air.png"><span>MacBook Air<i>out of stock</i></span></li>
        <li><img src="img/products/imac.png"><span>iMac Station<i>in stock</i></span></li>
    </ul>
</div>

如您所見,我們基本上是在構建一個無序列表,其中一個 li 元素代表 select 的每個選項 .選擇框本身由帶有 .selectBox 的 div 表示 類。

現在讓我們仔細看看這段代碼是如何生成的。

js/script.js

$(document).ready(function(){

    // The select element to be replaced:
    var select = $('select.makeMeFancy');

    var selectBoxContainer = $('<div>',{
        width       : select.outerWidth(),
        className   : 'tzSelect',
        html        : '<div class="selectBox"></div>'
    });

    var dropDown = $('<ul>',{className:'dropDown'});
    var selectBox = selectBoxContainer.find('.selectBox');

    // Looping though the options of the original select element

    select.find('option').each(function(i){
        var option = $(this);

        if(i==select.attr('selectedIndex')){
            selectBox.html(option.text());
        }

        // As of jQuery 1.4.3 we can access HTML5
        // data attributes with the data() method.

        if(option.data('skip')){
            return true;
        }

        // Creating a dropdown item according to the
        // data-icon and data-html-text HTML5 attributes:

        var li = $('<li>',{
            html:   '<img src="'+option.data('icon')+'" /><span>'+
                    option.data('html-text')+'</span>'
        });

        li.click(function(){

            selectBox.html(option.text());
            dropDown.trigger('hide');

            // When a click occurs, we are also reflecting
            // the change on the original select element:
            select.val(option.val());

            return false;
        });

        dropDown.append(li);
    });

    selectBoxContainer.append(dropDown.hide());
    select.hide().after(selectBoxContainer);

    // Binding custom show and hide events on the dropDown:

    dropDown.bind('show',function(){

        if(dropDown.is(':animated')){
            return false;
        }

        selectBox.addClass('expanded');
        dropDown.slideDown();

    }).bind('hide',function(){

        if(dropDown.is(':animated')){
            return false;
        }

        selectBox.removeClass('expanded');
        dropDown.slideUp();

    }).bind('toggle',function(){
        if(selectBox.hasClass('expanded')){
            dropDown.trigger('hide');
        }
        else dropDown.trigger('show');
    });

    selectBox.click(function(){
        dropDown.trigger('toggle');
        return false;
    });

    // If we click anywhere on the page, while the
    // dropdown is shown, it is going to be hidden:

    $(document).click(function(){
        dropDown.trigger('hide');
    });
});

在頁面加載時,腳本會掃描 select 元素的選項,並根據這些項目包含的 HTML5 數據屬性生成標記。從 jQuery 1.4.3 開始,可以使用 jQuery data() 直接訪問這些屬性的值 方法。這是一個非常方便的功能,它可以很容易地讀取嵌入的數據。

原始的選擇元素沒有被破壞——它只被 hide() 隱藏 方法。這很重要,因為正如您從上面的代碼中看到的那樣,我們將選擇的任何更改反映回原始選擇元素。這樣,當您將 select 用作​​表單的一部分時,這些值將被正確記錄並傳遞給您的後端腳本。

現在我們的代碼已經到位,讓我們仔細看看 CSS3 的魔力讓這一切成為可能。

CSS

從上一步頂部的標記可以看出,我們只使用了最少量的標記來顯示選擇框和下拉菜單。如果我們僅限於使用 CSS3 之前的技術,我們將不得不添加更多的 div 和 span。

css/styles.css

#page{
    width:230px;
    margin:100px auto;
}

#page h1{
    font-weight:normal;
    text-indent:-99999px;
    overflow:hidden;
    background:url('../img/your_product.png') no-repeat;
    width:230px;
    height:36px;
}

#page form{
    margin:20px auto;
    width:200px;
}

.tzSelect{

    /* This is the container of the new select element */

    height:34px;
    display:inline-block;
    min-width:200px;
    position:relative;

    /* Preloading the background image for the dropdown */
    background:url("../img/dropdown_slice.png") no-repeat -99999px;
}

.tzSelect .selectBox{
    position:absolute;

    height:100%;
    width:100%;

    /* Font settings */

    font:13px/34px "Lucida Sans Unicode", "Lucida Grande", sans-serif;
    text-align:center;
    text-shadow:1px 1px 0 #EEEEEE;
    color:#666666;

    /* Using CSS3 multiple backgrounds and a fallback */

    background:url('../img/select_slice.png') repeat-x #ddd;
    background-image:url('../img/select_slice.png'),url('../img/select_slice.png'),url('../img/select_slice.png'),url('../img/select_slice.png');
    background-position:0 -136px, right -204px, 50% -68px, 0 0;
    background-repeat: no-repeat, no-repeat, no-repeat, repeat-x;

    cursor:pointer;

    -moz-border-radius:3px;
    -webkit-border-radius:3px;
    border-radius:3px;
}

.tzSelect .selectBox:hover,
.tzSelect .selectBox.expanded{
    background-position:0 -170px, right -238px, 50% -102px, 0 -34px;
    color:#2c5667;
    text-shadow:1px 1px 0 #9bc2d0;
}

CSS3 允許我們通過添加多個 url() 來為元素分配多個背景圖像 聲明用逗號分隔。它們從上到下添加到元素中,每個連續的背景顯示在前一個的下方。

目前,Firefox、Safari、Chrome 和 Opera 支持多種背景。對於 Internet Explorer 和早期版本的瀏覽器,定義了一個 fallback,它基本上只是一個常規版本的背景。解析CSS文檔時,不理解多背景的瀏覽器會直接忽略規則,使用普通的。

.tzSelect .dropDown{
    position:absolute;
    top:40px;
    left:0;
    width:100%;
    border:1px solid #32333b;
    border-width:0 1px 1px;
    list-style:none;

    -moz-box-sizing:border-box;
    -webkit-box-sizing:border-box;
    box-sizing:border-box;

    -moz-box-shadow:0 0 4px #111;
    -webkit-box-shadow:0 0 4px #111;
    box-shadow:0 0 4px #111;
}

.tzSelect li{
    height:85px;
    cursor:pointer;
    position:relative;

    /* Again, using CSS3 multiple backgrounds */

    background:url('../img/dropdown_slice.png') repeat-x #222;
    background-image:url('../img/dropdown_slice.png'),url('../img/dropdown_slice.png'),url('../img/dropdown_slice.png');
    background-position: 50% -171px, 0 -85px, 0 0;
    background-repeat: no-repeat, no-repeat, repeat-x;
}

.tzSelect li:hover{
    background-position: 50% -256px, 0 -85px, 0 0;
}

.tzSelect li span{
    left:88px;
    position:absolute;
    top:27px;
}

.tzSelect li i{
    color:#999999;
    display:block;
    font-size:12px;
}

.tzSelect li img{
    left:9px;
    position:absolute;
    top:13px;
}

盒子大小 我用於 .dropDown 的屬性 類,指定邊框如何疊加到元素的總大小。通常,這裡的邊框會增加 2px 的整體寬度並破壞對齊方式。使用 box-sizing 設置為 邊框框 ,但是,整體寬度不會超過定義中指定的寬度,並且邊框會佔用內部空間。

有了這個,我們的 jQuery 和 CSS3 驅動的選擇框就完成了!

離別詞

在本教程中,我們演示了 jQuery 1.4.3 引入的一些方便的特性以及更多 CSS3 的功能。這個腳本的一個好處是,它將原來的選擇框隱藏在頁面上,並根據花哨的替換改變它的值。這樣,當您提交表單時,也會傳遞正確的值。


Tutorial JavaScript 教程
  1. Nestjs,外部事件總線

  2. 高級 TypeScript 練習 - 答案 7

  3. 使用按鈕滾動下拉菜單

  4. Object.assign() 和 just assign 之間的區別

  5. [ 國家藝術 ] 為什麼不可能用 JavaScript 編寫一個身份函數,以及如何做到這一點

  6. 從書籤加載外部 JS?

  7. 如何使用 React 設置 Tailwind CSS

  1. 使用 Redux 工具包的現代 React Redux 教程 - 2020

  2. 如何使用 Node.js 構建命令行界面 (CLI)

  3. 我如何將 Github 拉取請求狀態同步到 Asana 任務流

  4. 當今 Node 中的 ES 模塊

  5. 強制 IE8 重新渲染/重新繪製 :before/:after 偽元素

  6. RIP jQuery:現代瀏覽器的替代方案

  7. 使用 Typescript 和 Route Maps 的類型安全路由

  1. React StudyBoard (React, Hooks, Redux...)

  2. 冠狀病毒雜貨店協助

  3. 我們無法使用快速鏈接(或 Instant.page)更快

  4. 構建一個 React Native 應用程序。第 2 部分:分發