** 1.1. ** Série de compensação de deslocamento de elemento
1.1.1 Visão geral do deslocamento
deslocamento se traduz em deslocamento. Podemos obter dinamicamente a posição (deslocamento), tamanho, etc. do elemento usando os atributos relevantes da série de deslocamento.
-
Obtenha a distância do elemento com a posição do elemento pai posicionado
-
Obtenha o tamanho do próprio elemento (largura e altura)
-
Nota: O valor retornado não possui uma unidade
1.1.2 A diferença entre deslocamento e estilo
Deslocamento
-
deslocamento pode obter o valor do estilo em qualquer folha de estilo
-
O valor obtido pela série offset não possui unidade
-
offsetWidth 包含 padding + border + width
-
Atributos como offsetWidth são atributos somente leitura, que só podem ser obtidos e não podem ser atribuídos.
-
Portanto, queremos obter o tamanho e a posição do elemento, é mais apropriado usar deslocamento
estilo
-
o estilo só pode obter o valor do estilo na folha de estilo embutida
-
style.width obtém uma string com unidades
-
style.width obtém o valor sem preenchimento e borda
-
style.width é um atributo legível e gravável, que pode ser obtido ou atribuído
-
Então, se quisermos mudar o valor do elemento, precisamos mudá-lo com estilo
Como geralmente registramos eventos de toque para elementos, devemos nos lembrar de targetTocuhes
1.1.3 Caso: Obtenha as coordenadas do mouse na caixa
- Clicamos dentro da caixa e queremos obter a distância entre o mouse e os lados esquerdo e direito da caixa.
- Primeiro pegue as coordenadas do mouse na página (e.pageX, e.pageY)
- Em segundo lugar, obtenha a distância da caixa na página (box.offsetLeft, box.offsetTop)
- Subtraia a distância da caixa na página das coordenadas do mouse da página para obter as coordenadas do mouse na caixa
- Se você quiser mover o mouse, obtenha as últimas coordenadas e use o mouse para mover
var box = document.querySelector('.box');
box.addEventListener('mousemove', function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
this.innerHTML = 'x坐标是' + x + ' y坐标是' + y;
})
1.1.4 Caso: Arrastar e soltar da caixa modal
A caixa pop-up também é chamada de caixa modal.
1. Clique na camada pop-up, uma caixa modal aparecerá e uma camada de oclusão translúcida cinza será exibida.
2. Clique no botão Fechar para fechar o quadro modal e fechar a camada de oclusão translúcida cinza ao mesmo tempo.
3. Posicione o mouse na linha superior da caixa modal, você pode segurar o mouse e arrastar a caixa modal para mover na página.
4. Solte o mouse, você pode parar de arrastar a caixa modal para mover
1.1.5. Estudo de caso:
- Clique na camada pop-up, a caixa modal e a camada de oclusão serão exibidas display: block;
- Clique no botão Fechar, a caixa modal e a camada de oclusão serão mostradas ocultas: nenhuma;
- O princípio de arrastar na página: o mouse é pressionado e movido e, em seguida, o mouse é liberado
- O evento de gatilho é que o mouse pressiona o botão do mouse para baixo, move o mouse para remover e solta o botão do mouse para cima
- Processo de arrastar: Durante o movimento do mouse, o último valor é obtido e atribuído aos valores esquerdo e superior da caixa modal, de modo que a caixa modal possa seguir o mouse para longe
- A origem do evento acionado pelo pressionamento do mouse é a linha superior, ou seja, o id é o título
- As coordenadas do mouse menos as coordenadas do mouse na caixa é a posição real da caixa modal.
- Quando o mouse é pressionado, queremos obter as coordenadas do mouse na caixa.
- Quando o mouse se move, deixe as coordenadas da caixa modal serem definidas como: coordenadas do mouse menos as coordenadas da caixa Observe que o evento de movimento é escrito no evento de imprensa.
- Quando o mouse é solto, o arrasto para, ou seja, o evento de movimento do mouse pode ser cancelado
// 1. 获取元素
var login = document.querySelector('.login');
var mask = document.querySelector('.login-bg');
var link = document.querySelector('#link');
var closeBtn = document.querySelector('#closeBtn');
var title = document.querySelector('#title');
// 2. 点击弹出层这个链接 link 让mask 和login 显示出来
link.addEventListener('click', function() {
mask.style.display = 'block';
login.style.display = 'block';
})
// 3. 点击 closeBtn 就隐藏 mask 和 login
closeBtn.addEventListener('click', function() {
mask.style.display = 'none';
login.style.display = 'none';
})
// 4. 开始拖拽
// (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
title.addEventListener('mousedown', function(e) {
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
// (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
document.addEventListener('mousemove', move)
function move(e) {
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
}
// (3) 鼠标弹起,就让鼠标移动事件移除
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove', move);
})
})
1.1.6 Caso: Imitação de Lupa JD
- Todo o caso pode ser dividido em três módulos funcionais
- Passe o mouse sobre a caixa de imagem pequena, a camada de oclusão amarela e a caixa de imagem grande são exibidas, deixe a função de ocultar 2 caixas
- A camada de oclusão amarela segue a função do mouse.
- Mova a camada de oclusão amarela, o quadro geral segue a função de movimento.
1.1.7. Estudo de caso:
- A camada de oclusão amarela segue a função do mouse.
- Não é apropriado dar as coordenadas do mouse à camada de oclusão. Porque as coordenadas da camada de oclusão estão sujeitas à caixa pai.
- O primeiro é colocar as coordenadas do mouse na caixa.
- Em seguida, os valores são dados à camada de oclusão como os valores esquerdo e superior.
- O evento de movimento do mouse é usado neste momento, mas ainda está se movendo na pequena caixa de imagem.
- Verificou-se que a posição da camada de proteção estava errada e metade da altura e largura da própria caixa tiveram que ser subtraídas.
- A camada de oclusão não pode exceder o escopo da pequena caixa de imagem.
- Se for menor que zero, defina as coordenadas para 0
- Se for maior do que a distância máxima de movimento da camada de oclusão, defina as coordenadas para a distância máxima de movimento
- A distância máxima de movimento da camada de oclusão: a largura da pequena caixa de imagem menos a largura da caixa da camada de oclusão
window.addEventListener('load', function() {
var preview_img = document.querySelector('.preview_img');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
// 1. 当我们鼠标经过 preview_img 就显示和隐藏 mask 遮挡层 和 big 大盒子
preview_img.addEventListener('mouseover', function() {
mask.style.display = 'block';
big.style.display = 'block';
})
preview_img.addEventListener('mouseout', function() {
mask.style.display = 'none';
big.style.display = 'none';
})
// 2. 鼠标移动的时候,让黄色的盒子跟着鼠标来走
preview_img.addEventListener('mousemove', function(e) {
// (1). 先计算出鼠标在盒子内的坐标
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
// console.log(x, y);
// (2) 减去盒子高度 300的一半 是 150 就是我们mask 的最终 left 和top值了
// (3) 我们mask 移动的距离
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
// (4) 如果x 坐标小于了0 就让他停在0 的位置
// 遮挡层的最大移动距离
var maskMax = preview_img.offsetWidth - mask.offsetWidth;
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maskMax) {
maskX = maskMax;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= maskMax) {
maskY = maskMax;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
// 3. 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
// 大图
var bigIMg = document.querySelector('.bigImg');
// 大图片最大移动距离
var bigMax = bigIMg.offsetWidth - big.offsetWidth;
// 大图片的移动距离 X Y
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
bigIMg.style.left = -bigX + 'px';
bigIMg.style.top = -bigY + 'px';
})
})
1.2. Série do cliente da área visual do elemento
1.2.1 visão geral do cliente
O cliente é traduzido como o cliente. Usamos os atributos relevantes da série do cliente para obter as informações relevantes da área visual do elemento.
O tamanho do quadro e o tamanho do elemento do elemento podem ser obtidos dinamicamente por meio dos atributos relevantes da série do cliente .
1.2.2. Análise do código-fonte do Taobao flexible.js
Execute a função imediatamente (função () ()) () ou (função () () ())
Função principal: Crie um escopo independente. Evite conflitos de nomenclatura
As três situações a seguir irão acionar o evento de carregamento quando a página for atualizada.
1. Hiperlink de uma tag
2. F5 ou botão de atualização (atualização forçada)
3. Botões de avançar e voltar
Mas no Firefox, existe um recurso, existe um "cache de ida e volta", esse cache não só salva os dados da página, mas também salva o estado do DOM e do JavaScript; na verdade, a página inteira é armazenada na memória.
Portanto, o botão Voltar não pode atualizar a página neste momento.
Neste momento, você pode usar o evento pageshow para acionar. , Este evento é acionado quando a página é exibida, independentemente de a página vir do cache. No recarregamento da página, o pagehow será disparado após o evento de carregamento ser disparado; de acordo com o persistido no objeto de evento para determinar se é o evento pagehow disparado pela página no cache
注意这个事件给window添加。
1.3. Série de rolagem de rolagem de elemento
1.3.1. Visão geral da rolagem
A tradução de rolagem significa rolagem. Podemos obter dinamicamente o tamanho e a distância de rolagem do elemento usando os atributos relacionados da série de rolagem.
1.3.2. O cabeçalho da página que está sendo rolada
Se a altura (ou largura) do navegador não for alta o suficiente para exibir a página inteira, uma barra de rolagem aparecerá automaticamente. Quando a barra de rolagem é rolada para baixo, a altura acima da página fica oculta, chamamos isso de cabeçalho rolado da página. O evento onscroll é disparado quando a barra de rolagem está rolando.
1.3.3. Caso: A imitação do Taobao corrige a barra lateral direita
- A barra lateral original está absolutamente posicionada
- Quando a página rola para uma determinada posição, a barra lateral muda para uma posição fixa
- A página continua a rolar e será exibida de volta ao topo
1.3.4. Estudo de caso:
- É necessário usar a rolagem de evento de rolagem de página porque é rolagem de página, então a fonte do evento é o documento
- Rolar para uma determinada posição é julgar o valor superior da página que está sendo rolada.
- O cabeçalho da página que está sendo rolada: você pode obter o window.pageXOffset esquerdo se for rolado por window.pageYOffset
- Observe que o cabeçalho onde o elemento é rolado é element.scrollTop, se for o cabeçalho onde a página é rolada, é window.pageYOffset
- Na verdade, este valor pode ser obtido pelo offsetTop da caixa.Se for maior ou igual a este valor, a caixa pode ser posicionada de forma fixa.
//1. 获取元素
var sliderbar = document.querySelector('.slider-bar');
var banner = document.querySelector('.banner');
// banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面
var bannerTop = banner.offsetTop
// 当我们侧边栏固定定位之后应该变化的数值
var sliderbarTop = sliderbar.offsetTop - bannerTop;
// 获取main 主体元素
var main = document.querySelector('.main');
var goBack = document.querySelector('.goBack');
var mainTop = main.offsetTop;
// 2. 页面滚动事件 scroll
document.addEventListener('scroll', function() {
// console.log(11);
// window.pageYOffset 页面被卷去的头部
// console.log(window.pageYOffset);
// 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位
if (window.pageYOffset >= bannerTop) {
sliderbar.style.position = 'fixed';
sliderbar.style.top = sliderbarTop + 'px';
} else {
sliderbar.style.position = 'absolute';
sliderbar.style.top = '300px';
}
// 4. 当我们页面滚动到main盒子,就显示 goback模块
if (window.pageYOffset >= mainTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
})
1.3.5. Solução de compatibilidade de cabeçalho quando a página é rolada
Deve-se observar que o cabeçalho rolado da página tem problemas de compatibilidade. Portanto, o cabeçalho rolado geralmente tem os seguintes métodos de escrita:
- DTD declarado, use document.documentElement.scrollTop
- Nenhum DTD declarado, use document.body.scrollTop
- Novos métodos window.pageYOffset e window.pageXOffset, o IE9 começou a oferecer suporte
function getScroll() {
return {
left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0,
top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0
};
}
使用的时候 getScroll().left
1.4. Resumo das três séries principais
Seu principal uso:
1. A série de deslocamento é freqüentemente usada para obter a posição do elemento offsetLeft offsetTop
2.client é frequentemente usado para obter o tamanho do elemento clientWidth clientHeight
3.scroll é frequentemente usado para obter a distância de rolagem scrollTop scrollLeft
4. Observe que a distância de rolagem da página é obtida por meio de window.pageXOffset
1.5. A diferença entre mouseenter e mouseover
- O evento mouseenter é acionado quando o mouse se move sobre o elemento
- Semelhante ao mouseover, a diferença entre eles é
- O mouseover será disparado quando o mouse passar por sua própria caixa e quando passar por uma caixa filha. mouseenter só será acionado por sua própria caixa
- A razão para isso é porque o mouseenter não borbulha
- Use o mouseenter com o mouse para sair do mouse, o mesmo não borbulhará
1.6. Pacote de funções de animação
1.6.1. Princípio de realização de animação
Princípio básico: Continue movendo a posição da caixa por meio do temporizador setInterval ().
Etapas de implementação:
- Obtenha a posição atual da caixa
- Deixe a caixa adicionar 1 distância de movimento à posição atual
- Use o cronômetro para repetir esta operação
- Adicione uma condição para encerrar o cronômetro
- Observe que este elemento precisa adicionar posicionamento antes que element.style.left possa ser usado
1.6.2. A função de animação registra diferentes temporizadores para diferentes elementos
Se vários elementos usarem esta função de animação, declare o cronômetro com var todas as vezes. Podemos usar diferentes temporizadores para diferentes elementos (use nossos próprios temporizadores exclusivamente).
Princípio básico: o uso de JS é uma linguagem dinâmica que pode facilmente adicionar atributos ao objeto atual.
function animate(obj, target) {
// 当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
// 解决方案就是 让我们元素只有一个定时器执行
// 先清除以前的定时器,只保留当前的一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function() {
if (obj.offsetLeft >= target) {
// 停止动画 本质是停止定时器
clearInterval(obj.timer);
}
obj.style.left = obj.offsetLeft + 1 + 'px';
}, 30);
}