Личная подпись: Живи, как летние цветы, умирай, как зимний снег, жизнь такая, о чем сожалеть или жаловаться.
Предисловие: Часто необходимо вычислить размер элемента или положение страницы.Еще более обыденным является появление таких ключевых слов, как offsetWidth, clientWidth, scrollWidth и scrollTop.Каждый раз, когда вы сталкиваетесь с этим, вам нужно заранее поэкспериментировать . Повышение эффективности для следующего развития. Вот однократное резюме,Используется для определения того, находится ли элемент в видимой области и простой ленивой загрузки с помощью нативного js.. В конце статьи есть простая демонстрация реализации ленивой загрузки, вы можете посмотреть, если вам это нужно.
содержание
Если рабочий хочет хорошо работать, он должен сначала заточить свои инструменты. Прежде чем судить о том, реализует ли элемент простую нативную ленивую загрузку в видимой области, давайте кратко рассмотрим следующие ключевые концепции.
PS: Если вы уже знакомы с этими концепциями, вы можете сразу перейти к пункту 5, чтобы увидеть ключевые примеры кода.
1. Смещение
Размер смещения, видимый размер элемента определяется его высотой и шириной, включая все отступы, полосы прокрутки и размеры границ (Обратите внимание, что поля не включены). Смещение элемента можно получить с помощью следующих 4 свойств.
Компенсировать | концепция | формула |
---|---|---|
offsetHeight | Объем пространства, занимаемый элементом по вертикали, в пикселях. Включает высоту элемента, высоту (видимой) горизонтальной полосы прокрутки, высоту верхней границы и высоту нижней границы. | offsetHeght = content + padding + border + scrollX |
offsetWidth | Объем пространства, занимаемый элементом по горизонтали, в пикселях. Укажите ширину элемента, ширину (видимой) вертикальной полосы прокрутки, ширину левой границы и ширину правой границы. | offsetWidth = content + padding + border + scrollY |
offsetLeft | Расстояние в пикселях от внешней левой границы элемента до внутренней левой границы содержащего его элемента. | |
offsetTop | Расстояние в пикселях от верхней внешней границы элемента до верхней внутренней границы содержащего его элемента. |
Среди них свойства offsetLeft и offsetTop связаны с содержащим элементом, а ссылка на содержащий элемент хранится в свойстве offsetParent.Свойство offsetParent не обязательно равно значению parentNode.
Как показано ниже
Уведомление:Все эти свойства смещения доступны только для чтения., и их необходимо пересчитывать каждый раз, когда к ним обращаются. Поэтому следует стараться избегать повторного обращения к этим свойствам, если вам нужно повторно использовать значения некоторых из этих свойств, вы можете сохранить их в локальных переменных для повышения производительности.
Это тожеВ предыдущей статье проект выделения текста (Нажмите здесь, чтобы прыгнуть)После добавления прокладки, текстовая проверка должна повторно приобретать причину.
резюме
offset: свойство только для чтения; включает полосы прокрутки и границы, но не поля.
2. Размер клиентской области
Размер клиентской области доступен только для чтения и пересчитывается при каждом доступе.
размер клиентской области | концепция | формула |
---|---|---|
clientWidth | Свойство clientWidth представляет собой ширину области содержимого элемента плюс ширину левого и правого отступов; | clientWidth = content + padding |
clientHeight | Высота области содержимого элемента плюс высота отступов сверху и снизу. | clientHeight = content + padding |
Чаще всего эти свойства используются при определении размера области просмотра браузера (в версиях до IE7). Как показано в следующем примере:
function getViewport(){
// 检查 document.compatMode 属性,以确定浏览器是否运行在混杂模式。
// Safari3.1 之前的版本不支持这个属性,因此就会自动执行 else 语句
if (document.compatMode == "BackCompat"){
return {
width: document.body.clientWidth,
height: document.body.clientHeight
};
} else {
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight
};
}
}
резюме
Размер клиентской области: свойство только для чтения; исключая полосы прокрутки и границы, исключая поля.
3. Размер прокрутки
концепция | |
---|---|
scrollHeight | Общая высота содержимого элемента без полос прокрутки. |
scrollWidth | Общая ширина содержимого элемента без полос прокрутки. |
scrollLeft | Количество пикселей, которые нужно скрыть слева от области содержимого. Положение прокрутки элемента можно изменить, установив это свойство. |
scrollTop | Количество пикселей, которое должно быть скрыто над областью содержимого. Положение прокрутки элемента можно изменить, установив это свойство. |
scrollWidth и scrollHeight в основном используются для определения фактического размера содержимого элемента.
Свойства scrollLeft и scrollTop могут определять текущее состояние прокрутки элемента и устанавливать позицию прокрутки элемента. Когда элемент не прокручивался, значение обоих свойств равно 0. Если элемент прокручивается вертикально, значение scrollTop будет больше 0 и представляет собой высоту в пикселях невидимого содержимого над элементом. Если элемент прокручивается горизонтально, значение scrollLeft будет больше 0 и представляет собой ширину в пикселях невидимого содержимого слева от элемента. Оба эти свойства можно установить, поэтому установка для scrollLeft и scrollTop элемента значения 0 сбрасывает положение прокрутки элемента. Например:Предыдущая статьяИспользование scrollLeft в проекте выделения текста (Нажмите здесь, чтобы прыгнуть)
резюме
Свойство только для чтения, за исключением полос прокрутки и границ.
4. Определите размер элемента
getBoundingClientRect
Написание совместимости getBoundingClientRect:
Для браузеров, не поддерживающих getBoundingClientRect(), ту же информацию можно получить другими способами. В общем, разница между правым и левым равна значению offsetWidth, а разница между нижним и верхним — offsetHeight. Комбинируя вышесказанное, вы можете создать следующую кросс-браузерную функцию:
function getElementLeft(element){
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while (current !== null){
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actualLeft;
}
function getElementTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current !== null){
actualTop += current. offsetTop;
current = current.offsetParent;
}
return actualTop;
}
function getBoundingClientRect(element) {
var scrollTop = document.documentElement.scrollTop;
var scrollLeft = document.documentElement.scrollLeft;
if (element.getBoundingClientRect) {
if (typeof arguments.callee.offset != "number") {
var temp = document.createElement("div");
temp.style.cssText = "position:absolute;left:0;top:0;"; document.body.appendChild(temp);
arguments.callee.offset = -temp.getBoundingClientRect().top - scrollTop; document.body.removeChild(temp);
temp = null;
}
var rect = element.getBoundingClientRect();
var offset = arguments.callee.offset;
return {
left: rect.left + offset,
right: rect.right + offset,
top: rect.top + offset,
bottom: rect.bottom + offset
};
} else {
var actualLeft = getElementLeft(element);
var actualTop = getElementTop(element);
return {
left: actualLeft - scrollLeft,
right: actualLeft + element.offsetWidth - scrollLeft,
top: actualTop - scrollTop,
bottom: actualTop + element.offsetHeight - scrollTop
}
}
}
5. Определяем, находится ли элемент в видимой области
Зная размер элемента и площадь за его пределами, что мы можем сделать? Мы можем использовать знания, полученные выше, чтобы определить, находится ли элемент в видимой области, и, допустим, он больше, что также является принципом реализации отложенной загрузки изображений.
5.1 Первый способ
Формула: el.offsetTop - document.documentElement.scrollTop
function isInViewPortOfOne (el) {
// viewPortHeight 兼容所有浏览器写法
const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
const offsetTop = el.offsetTop
const scrollTop = document.documentElement.scrollTop
const top = offsetTop - scrollTop
console.log('top', top)
// 这里有个+100是为了提前加载+ 100
return top <= viewPortHeight + 100
}
5.2 Второй способ
Формула: el.getBoundingClientReact().top
На самом деле el.offsetTop - document.documentElement.scrollTop = el.getBoundingClientRect().top, воспользовавшись этим, мы можем заменить метод 1 следующим кодом
function isInViewPortOfTwo (el) {
const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
const top = el.getBoundingClientRect() && el.getBoundingClientRect().top
console.log('top', top)
return top <= viewPortHeight + 100
}
5.3 Третий способ
Формула: коэффициент пересечения > 0 && коэффициент пересечения
// 定义一个交叉观察器
const io = new IntersectionObserver(ioes => {
ioes.forEach(ioe => {
const el = ioe.target
const intersectionRatio = ioe.intersectionRatio
if (intersectionRatio > 0 && intersectionRatio <= 1) {
loadImg(el)
io.unobserve(el)
}
el.onload = el.onerror = () => io.unobserve(el)
})
})
// 执行交叉观察器
function isInViewPortOfThree (el) {
io.observe(el)
}
5.4 Сравнение совместимости
Что касается совместимости, мы знаем, что более примитивный метод имеет наилучшую совместимость, поэтому могут ли второй метод и третий метод заменить третий метод? Давайте взглянем.
Судя по данным caniuse, адаптация getBoundingClientReact выглядит очень оптимистично.
Следовательно, если совместимость и адаптация должны быть выполнены как на мобильном терминале, так и на настольном терминале, второй способ может полностью заменить первый способ адаптации. Если это только для настольной адаптации (например, рабочего фона), мы можем попробовать новый метод IntersectionObserver, ведь в IntersectionObserver есть более богатые функции, которые ждут нас, чтобы испытать.
5.5 Примеры
Иногда мы хотим, чтобы определенные статические ресурсы (например, изображения) загружались только тогда, когда пользователь прокручивает страницу вниз и входит в область просмотра, что может сэкономить пропускную способность и повысить производительность веб-страницы. Это называется "ленивой загрузкой", также известной как ленивая загрузка.
Отложенная загрузка Предварительный просмотр DEMO(Поместите свое локальное изображение, чтобы добиться ленивой загрузки, заменив различные методы)
------------------------- Великолепная разделительная линия --------------------- - -------
обо мне
Сертифицированный программист по финансовому планированию
- Моя домашняя страница github (нажмите, чтобы войти)
- Моя домашняя страница Nuggets (нажмите, чтобы войти)
- Домашняя страница моей короткой книги (нажмите, чтобы войти)
- Моя официальная учетная запись (нажмите, чтобы войти или отсканируйте QR-код ниже)
Спасибо за справочную информацию, представленную ниже
-
Нативный JS реализует простейшую ленивую загрузку изображений.
-
продвинутое программирование на JavaScript
-
2019.2.22 Обновление
Связь:кликните сюда
Содержимое: document.scrollingElement заменяет document.documentElement.scrollTop и document.body.scrollTop.
document.scrollingElement объединяет реки и озера:
На рабочем столе document.scrollingElement — это document.documentElement;
На мобильных устройствах document.scrollingElement — это document.body.
Преимущество: избегайте использования совместимости document.documentElement.scrollTop = 0 (настольный компьютер), document.body.scrollTop = 0 (мобильный);