Знаёмства з jQuery

Калі мы ўжо ведаем трошкі пра JavaScript, можна паспрабаваць давецца пра jQuery – бібліятэку JavaScript якая дазваляе вельмі проста рабіць вэб-старонкі інтэрактыўнымі. Для пачатку давайце даведаемся як выклікаць дыялогавыя акенцы калі Вы ціскаеце па якому-небудзь элементу на старонцы.

Спачатку спампуйце download jQuery. Выбярыце “uncompressed, development version” з сэкцыі jQuery 2.x; калі файл проста адчыняецца ў Вашым браўзеры захавайце яго ў тэчцы js. Давайце таксама створым файл scripts.js каб захоўваць наш уласны JavaScript. Пакульп пачніце з вось такога HTML-файла:

html-help.html
<!DOCTYPE html>
<html>
<head>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
    <title>HTML help</title>
</head>
<body>
    <div class="container">
        <h1>HTML help</h1>

        <p>This is a very special page. If you click somewhere, it will tell you what type of HTML element you clicked on.</p>

        <p>Look at this cute kitter!</p>
        <img src="img/kitter.jpg">
    </div>

    <script src="js/jquery-2.1.1.js"></script>
    <script src="js/scripts.js"></script>
</body>
</html>

Вельмі важна каб файл scripts.js знаходзіўся пасьля jQuery, таму што ён будзе выкарыстоўваць функцыі jQuery, якія павінны быць загружанымі першымі.

Ок, зараз можна карыстацца jQuery! Надрукуйце наступнае ў scripts.js:

scripts.js
jQuery("h1").click(function() {
    alert("This is a header.");
});

jQuery("p").click(function() {
    alert("This is a paragraph.");
});

jQuery("img").click(function() {
    alert("This is an image.");
});

Перад тым як мы пачнем размаўляць пра JavaScript, звярніце ўвагу на код функцыі function() – ён вельмі падобны на той, якім мы карысталіся раней, хаця мы не прысвоілі функцыю зьменнай і напісалі код функцыі ў некалі радкоў. Таксама звярніце ўвагу на водступы!

Калі Вы абнавіце старонку і пачнеце ціскаць па розным элементам маленькае дыялогавае акенца пачне зьяўляцца і адлюстроўваць назву элемента. Ура! Зараз давайце разбярэмся як усё гэта працуе.

Тут у нас мы маем новую функцыю: функцыю jQuery(). Адзіная рэч, якую робіць функцыя jQuery – гэта выбірае HTML-элементы на старонцы ў залежнасьці ад аргумента, які перададзены ў яе. Таму код jQuery("p") выбірае ўсе параграфы на старонцы.

Пасьля таго, як элементы вабраны, мы выкарыстоўваем мэтад .click() каб прымацаваць апрацоўшчыка падзеі да іх. Апрацоўшчык падзеі “слухае” элементы і выклікаецца калі адбываецца клік.

Потым мы кажам jQuery што рабіць калі карыстальнік ціснуў па элементу. Мы перадаем функцыю як аргумэнт. Функцыя змяшчае код alert(). Прычына, чаму jQuery патрабуе каб мы перадавалі функцыю з кодам alert(), а не проста alert(), у тым, што калі мы хочам мы можам выклікаць alert() або іншую функцыю некалькі разоў. Напрыклад:

jQuery("h1").click(function() {
    alert("This is a header.");
    alert("I told you, THIS IS A HEADER!");
});

Калі Вы перадаеце функцыю ў якасьці аргумэнта ў іншую функцыю, функцыя, якую Вы перадаеце, завецца callback.

Давайце трошкі падчысьцім наш код зараз. Напэўна, падаецца трохі няправільным класьці тэг <script> у цела дакуманта, дзе знаходзіцца змест старонкі. Давайце перакладзем яго лепей у <head>, дзе змяшчаецца інфармацыю пра старонку:

html-help.html
<head>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
    <script src="js/jquery-2.1.1.js"></script>
    <script src="js/scripts.js"></script>
    <title>HTML help</title>
</head>

Ну вось. Паспрабуйце паклікаць зараз. Нічога не адбываецца! Давайце пераглядзем наш JavaScript-код каб разабрацца дзе ён зламаўся. Ці памятаеце Вы што jQuery('p') будзе шукаць усе <p> тэгі на старонцы? Браўзер загружае Вашую старонку з верху HTML дакуманта да нізу. Таму на той момант калі мы кладзем JavaScript у <head>, замест таго, каб класьці яго ў канец, тэгаў <p> яшчэ не існуе, т.б. мэтаду .click() няма на чым выклікацца. Тое, што мы павінны зрабіць, гэта сказаць JavaScript’у каб ён не выконваўся пакуль дакумант не падгрузіцца. На шчасце, jQuery дазваляе лёгка гэта зрабіць:

scripts.js
jQuery(document).ready(function() {
    jQuery("h1").click(function() {
        alert("This is a header.");
    });

    jQuery("p").click(function() {
        alert("This is a paragraph.");
    });

    jQuery("img").click(function() {
        alert("This is an image.");
    });
});

Тут мы кажам jQuery знайсьці HTML-дакумант а потым выклікаць мэтад .ready() на ім. Калі дакумант скончыў запампоўвацца, jQuery выканае callback-функцыю, якая перададзена ў мэтад .ready(). І гэтая функцыя выканае наш код. У большасьці выпадкаў будзе добрай ідэяй абгортваць Ваш JavaScript код у функцыю перададзеную ў мэтад .ready(), каб ён выклікаўся пасьля таго, як старонка загружана і Вы не сутыкаліся з праблемамі, якія мы толькі што мелі.

Паглядзіце старонку – яна будзе зноў працаваць.

Шмат распрацоўшчыкаў на JavaScript карыстаюцца скарочаным шляхам выкліканьня jQuery: замест напісаньня jQuery() штораз, можна выкарыстоўваць проста $():

scripts.js
$(document).ready(function() {
    $("h1").click(function() {
        alert("This is a header.");
    });

    $("p").click(function() {
        alert("This is a paragraph.");
    });

    $("img").click(function() {
        alert("This is an image.");
    });
});

Так рабіць насамрэч ня вельмі абавязкова, але гэта захоўвае нам трошкі часу каб не паўтараць адныя і тыя ж дзеяньні.

Пагуляйце з jQuery самастойна зараз:

  • Дадайце на старонку тэг <h2> і “павесьце” на яго апрацоўшчык .click(). Перадайце callback, які змяшчае выклік функцыі confirm().
  • Зрабіце тое ж самае для <ul>.
  • Замяніце мэтад .click() на .dblclick(). Калі ён выклікаецца? Замяніце на .hover(). Калі выклікаецца ён?

jQuery эфекты

Адлстроўваньне дыялогавых акенцаў ужо трохі паднадакучыла, таму давайце перайдзем да сапраўднага маніпуляваньня старонкай захоўваючы і адлюстроўваючы ейныя элементы. Вось HTML з якім мы будзем працаваць:

peek-a-boo.html
<!DOCTYPE html>
<html>
<head>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
    <link href="css/styles.css" rel="stylesheet" type="text/css">
    <script src="js/jquery-1.9.1.js"></script>
    <script src="js/scripts.js"></script>
    <title>Peek-a-boo</title>
</head>
<body>
    <div class="container">
        <h1>Peek-a-boo</h1>

        <p>Let's play peek-a-boo. Click here to see the surprise!</p>

        <img src="img/kitten.jpg">
    </div>
</body>
</html>

Відавочна, то гэты код пакуль ня будзе працаваць. Першае што мы павінны зрабіц гэта схаваць коціка з дапамогай CSS. Як звычайна, мы створым файл styles.css унутры тэчкі css. Потым давайце дададзім CSS-правіла каб схаваць малюнак:

styles.css
img {
    display: none;
}

Зараз можна выкарыстоўваць jQuery паказаць кацянё калі Вы ціскаеце на параграф:

scripts.js
$(document).ready(function() {
    $("p").click(function() {
        $("img").show();
    });
});

Крута, ці не? Тут мы выкарысталі яшчэ адну функцыю jQuery якая завецца .show(), якая, вядома, паказвае схаваны элемент.

А ці не было б клёва, калі пасьля кліка па параграфу ягоны тэкст зьмяняўся і рабіўся: “Якое класнае кацянё! Цісніце яшчэ раз каб схаваць яго.” Давайце паспрабуем. Спачатку крыху зьмяненьняў у HTML:

peek-a-boo.html
<body>
    <div class="container">
        <h1>Peek-a-boo</h1>

        <div class="kitten-hidden">
            <p>Let's play peek-a-boo. Click here to see the surprise!</p>
        </div>

        <div class="kitten-showing">
            <p>What a cute kitten! Click here to hide her again.</p>
            <img src="img/kitten.jpg">
        </div>
    </div>
</body>

Зараз мы абгарнулі змест нашай старонкі ў два тэга <div>: першы калі кацянё схавана і другі, калі адлюстроўваецца. Зараз абнавім CSS каб кацянё было захавана першапачаткова:

styles.css
.kitten-showing {
    display: none;
}

І зараз JavaScript:

scripts.js
$(document).ready(function() {
    $("p").click(function() {
        $(".kitten-showing").show();
        $(".kitten-hidden").hide();
    });
});

Адна з найклёвейшых рэчаў jQuery гэта тое, што ён выкарыстоўвае тыя ж селектары што і CSS.

Зараз наш код пасьпяхова зьмяняе тэкст, які адлюстроўваецца зверху коціка! Ён пакуль працуе толькі аднойчы – калі Вы цісніце другі раз нічога не зьменіцца, таму давайце выправім гэта:

scripts.js
$(document).ready(function() {
    $("p").click(function() {
        $(".kitten-showing").toggle();
        $(".kitten-hidden").toggle();
    });
});

Клёва. Зараз усё працуе як і плянавалася.

Глядзіце, застаецца пару рэчаў, якія мне яшчэ не падабаюцца наконт старонкі. Амаль усе карыстальнікі чакаюць, што калі элемент клікабельны, ён мае іншы колер і што калі правесьці мышкай зьявіцца курсор у выглядзе рукі. Гэта даволі проста рэалізаваць з дапамогай CSS:

styles.css
p {
    cursor: pointer;
    color: #0088cc;
}

p:hover {
    text-decoration: underline;
}

Зараз гэта працуе і выглядае нашмат лепей. Але ці ўсё мы ўлічылі? Што будзе калі дадаць яшчэ адзін параграф:

peek-a-boo.html
<body>
    <div class="container">
        <h1>Peek-a-boo</h1>
        <p><strong>Peek-a-boo</strong> is an ancient game riddled in mystery and deceit. Though it appears
        to be an innocent children's pastime, you may change your mind when you learn of its treacherous history.</p>

        <div class="kitter-hidden">
            <p>Let's play peek-a-boo. Click here to see the surprise!</p>
        </div>

        <div class="kitter-showing">
            <p>What a cute kitter! Click here to hide her again.</p>
            <img src="img/kitter.jpg">
        </div>
    </div>
</body>

Жах! Нашыя стылі буяняць і прымяняюцца да параграфа, які не павінен быць клікабельным. І нават горш: калі Вы ціскаеце па яму, кацянё хаваецца! Нам насамрэч трэба зменшыць шэраг элементаў, на якія ўздзейнічае CSS і JavaScript. Давайце дададзім пару тэгаў <span> каб размежаваць функцыі нашага зместу:

peek-a-boo.html
<body>
    <div class="container">
        <h1>Peek-a-boo</h1>
        <p><strong>Peek-a-boo</strong> is an ancient game riddled in mystery and deceit. Though it appears
        to be an innocent childrens' pastime, you may change your mind when you learn of its treacherous history.</p>

        <div class="kitten-hidden">
            <p>Let's play peek-a-boo. <span class="clickable">Click here</span> to see the surprise!</p>
        </div>

        <div class="kitten-showing">
            <p>What a cute kitten! <span class="clickable">Click here</span> to hide her again.</p>
            <img src="img/kitten.jpg">
        </div>
    </div>
</body>

Абнавім наш css:

styles.css
.kitten-showing {
    display: none;
}

.clickable {
    cursor: pointer;
    color: #0088cc;
}

.clickable:hover {
    text-decoration: underline;
}

І JavaScript:

scripts.js
$(document).ready(function() {
        $(".clickable").click(function() {
        $(".kitten-showing").toggle();
        $(".kitten-hidden").toggle();
    });
});

Нашмат лепей зараз.

Глядзіце далей яшчэ адно пытаньне: ці не падаецца Вам, што мы трохі некарэктна выкарыстоўваем класы kitten-hidden і kitten-showing. Мы павінны выкарыстоўваць класы тады, калі мы хочам каб можна было проста надаць элементу стылізаваны выгляд. Напрыклад для span’а выкарыстоўваньне clickable класса мае сэнс: існуе два месца на старонцы дзе мы яго выкарыстоўваем, і можна ўявіць выпадкі, дзе гэты клас яшчэ спатрэбіцца. Але класы kitten-hidden і kitten-showing больш нідзе на старонцы выкарыстаны не могуць – гэтыя сэкцыі павінны быць унікальны. Для такіх выпадкаў мы маем яшчэ адну рэч: ідэнтыфікатар элемента – ID. Паглядзіце:

peek-a-boo.html
<body>
    <div class="container">
        <h1>Peek-a-boo</h1>
        <p><strong>Peek-a-boo</strong> is an ancient game riddled in mystery and deceit. Though it appears
        to be an innocent children's pastime, you may change your mind when you learn of its treacherous history.</p>

        <div id="kitten-hidden">
            <p>Let's play peek-a-boo. <span class="clickable">Click here</span> to see the surprise!</p>
        </div>

        <div id="kitten-showing">
            <p>What a cute kitten! <span class="clickable">Click here</span> to hide her again.</p>
            <img src="img/kitten.jpg">
        </div>
    </div>
</body>

Зараз зменім наш CSS:

styles.css
#kitten-showing {
    display: none;
}

І JavaScript як тут:

scripts.js
$(document).ready(function() {
    $(".clickable").click(function() {
        $("#kitten-showing").toggle();
        $("#kitten-hidden").toggle();
    });
});

Дык у чым жа розніца паміж класам і ID, акрамя таго, што мы выкарыстоўваем . каб выбраць клас і # каб выбрацьID? Няма розніцы, сапраўды, акрамя таго, што ID павінен быць унікальным на старонцы, а класам можна карыстацца столькі разоў, колькі трэба. Выкарыстоўваючы ID, Вы кажаце, што спасылаецеся толькі на адзін канкрэтны элемент.

Давайце зробім яшчэ адзін крок у накірунку таго, каб зрабіць наш код яшчэ больш простым для паўторнага выкарыстаньня. Замест таго, каб называць ідэнтыфікатары kitten-showing і kitten-hidden, мы можам назваць іх initially-hidden і initially-showing. З такімі імёнамі, мы можам выкарыстаць наш код далей у якім-небудзь іншым месцы.

Зараз маленькая лекцыя пра то што Вы толькі што даведаліся перад тым як пачаць практыкавацца. Калі мы выкарыстоўваем JavaScript для таго, каб маніпуляваць старонкай, мы не зьмяняем крынічны код. Не мае значэньня як моцна мы зьмяняем старонку з дапамогай JavaScript’а – калі Вы цісніце кнопку Refresh у браўзеры усе зьмяненьні зьнікнуць. Што робіць JavaScript – гэта зьмяняе Document Object Model або DOM. DOM – гэта мадэль, якую будуе браўзер калі чытае HTML. Калі Вы інспектуеце элементы праз інспектар Вы насамрэч бачыце DOM а не HTML. Паспрабуйце праінспектаваць старонку, з якой мы працуем, а потым цісніце click here. У інспектаре Вы ўбачыце што DOM зьмяняецца.

Вашая чарга:

  • На старонцы з сэкцыямі і коцікамі дадайце спасылкі, якія б паказвалі/хавалі сэкцыі;
  • Замяніце .show() і .hide() на .fadeIn(), .fadeOut(), .fadeToggle(), .slideDown(), .slideUp() і .slideToggle(). Ці больш падабаецца?

Маніпуляцыі з DOM

У папярэдней сэкцыі мы даведаліся як лёгка хаваць і паказваць элементы у DOM. Зараз давайце пойдзем глыбей і навучымся дадаваць і выдаляць элементы з DOM. Вось HTML з якога мы пачнем:

talk.html
<!DOCTYPE html>
<html>
<head>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css">
    <link href="css/styles.css" rel="stylesheet" type="text/css">
    <script src="js/jquery-1.10.2.js"></script>
    <script src="js/scripts.js"></script>
    <title>Talk to the web page</title>
</head>
<body>
    <div class="container">
        <h1>Talk to the web page</h1>
        <p>Click a button to say something to the web page. See what it says back!</p>

        <button class="btn btn-primary" id="hello">Say "hello"</button>
        <button class="btn btn-inverse" id="goodbye">Say "goodbye"</button>
        <button class="btn btn-danger" id="stop">Say "stop copying me!"</button>

        <div class="row">
            <div class="col-md-6">
                <h2>You said:</h2>
                <ul class="unstyled">

                </ul>
            </div>

            <div class="col-md-6">
                <h2>The web page said back:</h2>
                <ul class="unstyled">

                </ul>
            </div>
        </div>
    </div>
</body>
</html>

Вось JavaScript каб кнопкі працавалі:

scripts.js
$(document).ready(function() {
    $("button#hello").click(function() {
        $("ul").prepend("<li>Hello!</li>");
    });

    $("button#goodbye").click(function() {
        $("ul").prepend("<li>Goodbye!</li>");
    });

    $("button#stop").click(function() {
        $("ul").prepend("<li>Stop copying me!</li>");
    });
});

Мэтад .prepend() уставіць тэкст які перадаецца ў якасьці аргумента першым дзіцём у <ul>. (Як Вы маглі ўжо здагадацца ёсьць і .append() які уставіць элемент апошнім; існуюць таксама мэтады .before() і .after() якія уставяць новы элемент перад або пасьля <ul>, а не ўнутры яго.)

Зараз няхай наша старонка што-небудзь больш цікавае кажа карыстальніку:

scripts.js
$(document).ready(function() {
    $("button#hello").click(function() {
        $("ul#user").prepend("<li>Hello!</li>");
        $("ul#webpage").prepend("<li>Why hello there!</li>");
    });

    $("button#goodbye").click(function() {
        $("ul#user").prepend("<li>Goodbye!</li>");
        $("ul#webpage").prepend("<li>Goodbye, dear user!</li>");
    });

    $("button#stop").click(function() {
        $("ul#user").prepend("<li>Stop copying me!</li>");
        $("ul#webpage").prepend("<li>Pardon me. I meant no offense.</li>");
    });
});

Вядома нам трэба зьмяніць тэгі <ul> каб яны мелі ID user і webpage. Ну Вы гэта ўжо можаце і самі зрабіць.

Зараз, калі мы ведаем як дадаваць у DOM, давайце даведаемся як выдаляць з яго. Давайце зробім так, што калі карыстльнік ціскае па паведамленьню, яно зьнікае.

Спачатку на трэба выбраць усе паведамленьні. Каб пратэставаць ці тое мы выбралі зменім фон элементаў сьпіса:

scripts.js
$(document).ready(function() {
    // previous code...
    $('li').css('background-color', 'green');
});

Нічога не працуе. Чаму? Таму што каб элементам сьпіса зьявіцца на старонцы нам спачатку трэба ціснуць на кнопку. Таму давайце зрушым наш код у функцыю, якая выклікаецца на click():

$("button#hello").click(function() {
    $("ul#user").prepend("<li>Hello! <span class='clickable delete'>x</span></li>");
    $("ul#webpage").prepend("<li>Why hello there! <span class='clickable delete'>x</span></li>");
    $('li').css('background-color', 'green');
});

Зараз калі мы ціскаем Say “hello”, паведамленьні робяцца зялёнымі.

Рухаемся на наступны крок – прымацуем апрацоўшчык падзей з выклікам дыялогавага акенца замест зьмяненьня коляра фону:

$("button#hello").click(function() {
    $("ul#user").prepend("<li>Hello! <span class='clickable delete'>x</span></li>");
    $("ul#webpage").prepend("<li>Why hello there! <span class='clickable delete'>x</span></li>");
    $('li').click(function() {
        alert('hi');
    });
});

Зараз калі мы ціснем Say “hello” а потым на паведамленьне, мы атрымае наш alert! Але існуе праблема: калі мы ціснем па кнопцы двойчы, alert таксама зьявіцца двойчы. Пры яшчэ адным кліке па апошняму паведамленьню алерт зьявіцца тры разы, а пры націсканьні па другому паведамленьню – два. Адбываецца наступнае: калі мы першы раз ціскаем на “х”, селектару $('.delete') адпавядае толькі адно паведамленьне ў кожным сьпісе да якога далучаецца апрацоўшчык падзей. Калі мы ціскаем па кнопцы другі раз першае паведамленьне ўжо на старонцы і да яго далучаецца яшчэ адзін апрацоўшчык. І кожны раз калі мы ціскаем па кнопке, яшчэ адзін апрацоўшчык падзей дадаецца на старонку.

Што мы хочам – дык гэта дадаваць апрацоўшчыкі да паведамленьняў, якія былі толькі што дададзены. Наіпрасьцей гэты робіцца з дапамогай CSS псеўда селектара :first-child, які выбірае толькі першы элемент у спісе:

$("li:first-child").click(function() {
    alert('hi');
});
$("li:first-child").click(function() {
    alert('hi');
});

Зараз пры націсканьні адчыняецца толькі адно дыялогавае акенца.

І, нарэшце, давайце заменім алерт на код які будзе насамрэч выдаляць паведамленьне:

$("ul#user").children("li").first().click(function() {
    $(this).remove();
});
$("ul#webpage").children("li").first().click(function() {
    $(this).remove();
});

Што за мэтад remove() адразу зразумела, але што такое this? this – гэта напачатку трошкі незразумелае паняцце JavaScript – мы вернемся да яго праз некалькі заняткаў. На сучасным этапе дастаткова ведаць, што this – гэта зьменная ў якой знаходзіцца элемент, па якому адбыўся клік.

Ну вось, мы ўрэшце скончылі гэты аграменны занятак!

Ок, зараз Ваша чарга. Дадайце інтэрактыўнасьці ў Вашыя старонкі – для пачатку можна зрабіць старонку “каты супраць сабак” – калі Вы ціскаеце па кату ён мяўкае, а сабака лаіць, і тое ж самае наадварот.

Акрамя .prepend() і .append() Вы можаце выкарыстоўваць мэтады .before() і .after(). Даведайцеся што яны робяць!

  • Зрабіце старонку каты супраць сабак апісаную вышэй.
  • Ці заўважылі Вы як шмат паўтарэньняў у JavaScript кодзе які Вы пісалі? На старонцы talk.html, існуе тры сэкцыі дзе Вы дадаеце апрацоўшчыкі. Код паўсюль абсалютна аднолькавы і адрозьніваецца толькі ідэнтыфікатарамі. Ліквідуйце гэту недарэчнасьць ствараючы функцыю якая прымае ID і само паведамленьне, а потым знаходзіць патрэбную кнопку і дадае ў яе апрацоўшчык з перададзеным паведамленьнем.

Папярэдні занятак Наступны занятак