ilyachalov (ilyachalov) wrote,
ilyachalov
ilyachalov

Category:

JavaScript: заметка рядом с элементом

Решил задачу «Покажите заметку рядом с элементом» к подразделу 1.11 «Координаты» второй части учебника по JavaScript.

Дана HTML-страница, код которой можно посмотреть в песочнице. В теле этой HTML-страницы уже есть скрипт с функцией showNote (на русский название этой функции переводится как «показать заметку»):
function showNote(anchor, position, html) {
    let note = document.createElement('div'); // создаём заметку,
    note.className = "note";                  // указываем ее CSS-класс и содержимое
    note.innerHTML = html;
    document.body.append(note);               // добавляем заметку на HTML-страницу

    positionAt(anchor, position, note);       // перемещаем заметку в указанную позицию
}

Создание HTML-элемента, заполнение его свойств и добавление его на HTML-страницу рассматривалось в учебнике в предыдущих подразделах. Один из главных смыслов функции showNote в том, чтобы показать ученику, что прежде, чем двигать HTML-элемент на странице, его сначала нужно добавить на эту HTML-страницу. В противном случае нужные для вычисления новых координат HTML-элемента его JavaScript-свойства (ширина offsetWidth, высота offsetHeight и так далее) будут равны нулю.

Функция showNote должна создать и показать заметку с указанным содержимым (параметр html) рядом с указанным HTML-элементом (параметр anchor) в указанной позиции (параметр position). Параметр position по условиям задачи — это строка, содержащая одно из значений "top", "right" или "bottom", то есть сверху, справа или снизу от заданного HTML-элемента anchor соответственно.

Еще в скрипте заданной HTML-страницы имеется код для тестирования работы функции showNote:
// тестируем
let blockquote = document.querySelector('blockquote');

showNote(blockquote, "top",    "заметка выше");
showNote(blockquote, "right",  "заметка справа");
showNote(blockquote, "bottom", "заметка ниже");

От нас требуется написать функцию positionAt (ее название можно перевести как «переместить в позицию»), которая вызывается из функции showNote. Эта функция должна переместить указанную заметку (параметр note), созданную ранее в функции showNote, к указанному HTML-элементу (параметр anchor), расположив ее в указанной позиции (параметр position) относительно HTML-элемента anchor.

Еще в теле заданной HTML-страницы есть текст, помещенный в HTML-элементы p (параграф) и blockquote (цитата). Для заданной HTML-страницы в отдельном файле index.css описаны три стиля: .note (CSS-класс для заметок), blockquote (стиль для HTML-элементов blockquote) и blockquote:before (стиль для большой открывающей кавычки в цитате).

Я, кстати, знаю язык CSS довольно поверхностно, поэтому с удовольствием изучаю стили, задаваемые в задачах к подразделам учебника. Там встречается много интересного, но подробное рассмотрение этих стилей выходит за пределы темы этого поста.

В вышеуказанном тестовом коде в качестве HTML-элемента anchor используется HTML-элемент blockquote. Тестовый код трижды запускает функцию showNote с различным набором параметров, в результате чего рядом с HTML-элементом blockquote должно появиться три заметки с разным содержимым (в данном случае — текстом). Эти три заметки должны быть расположены сверху, справа и снизу от HTML-элемента blockquote.

После проведенного к этому моменту разбора условий задачи и заданной HTML-страницы становится понятно, как решать эту задачу. В принципе, можно действовать в том же ключе, что и в решениях задач, рассмотренных в предыдущих двух постах, объединяя их:

1. JavaScript: мяч на футбольном поле
2. JavaScript: координаты углов поля

Я написал такое решение (оно очень близко к решению авторов задачи):
function positionAt(anchor, position, elem) {
    // ... ваш код ...
    let rect = anchor.getBoundingClientRect();     // координаты HTML-элемента anchor
    
    let x = 0, y = 0;                              // вычислим новые координаты
    switch (position) {                            // для HTML-элемента elem
        case "top":
            x = rect.x;
            y = rect.y - elem.offsetHeight; break;
        case "right":
            x = rect.x + anchor.offsetWidth;
            y = rect.y; break;
        case "bottom":
            x = rect.x;
            y = rect.y + anchor.offsetHeight;
    }
    
    elem.style.left = x + "px";                    // передвинем HTML-элемент elem
    elem.style.top = y + "px";                     // в новую позицию
}

Изначально каждая заметка добавляется функцией showNote в конец тела HTML-страницы с помощью метода append. Задача функции positionAt — передвинуть существующую в теле HTML-страницы заметку в указанную (через ее параметры) позицию.

Функция getBoundingClientRect возвращает координаты относительно левого верхнего угла окна браузера. Координаты заметки тоже определяются относительно левого верхнего угла окна браузера, потому что в стиле CSS-класса заметки .note есть указание position: fixed; (фиксированное позиционирование). Подробнее о разных видах CSS-позиционирования можно узнать по старой знакомой ссылке:

https://developer.mozilla.org/ru/docs/Learn/CSS/CSS_layout/Positioning

Из-за фиксированного позиционирования заметок при прокрутке содержимого заданной HTML-страницы заметки «уедут» от HTML-элемента, возле которого они были размещены. Исправить эту ситуацию предлагается в следующей задаче обсуждаемого подраздела данного учебника.
Tags: Образование, Программирование
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments