사용자가 페이지에서 확대 / 축소를 변경할 때 JavaScript를 사용하여 감지 할 수 있습니까? 단순히 "zoom"이벤트를 잡고 이에 응답하고 싶습니다 (window.onresize 이벤트와 유사).
감사.
사용자가 페이지에서 확대 / 축소를 변경할 때 JavaScript를 사용하여 감지 할 수 있습니까? 단순히 "zoom"이벤트를 잡고 이에 응답하고 싶습니다 (window.onresize 이벤트와 유사).
감사.
답변:
확대 / 축소가 있는지 능동적으로 감지 할 수있는 방법이 없습니다. 나는 당신이 그것을 구현하려고 시도하는 방법에 대한 좋은 항목을 발견했습니다.
줌 레벨을 감지하는 두 가지 방법을 찾았습니다. 확대 / 축소 수준 변경을 감지하는 한 가지 방법은 백분율 값이 확대되지 않는다는 사실에 의존합니다. 백분율 값은 뷰포트 너비를 기준으로하므로 페이지 확대 / 축소의 영향을받지 않습니다. 하나의 위치에 백분율이 있고 다른 하나의 위치가 픽셀에있는 두 개의 요소를 삽입하면 페이지가 확대 / 축소 될 때 분리됩니다. 두 요소의 위치 사이의 비율을 찾으면 확대 / 축소 수준이 있습니다. 테스트 사례를 참조하십시오. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
위 게시물의 도구를 사용하여 수행 할 수도 있습니다. 문제는 페이지 확대 / 축소 여부에 대한 교육 된 추측을하는 것입니다. 이것은 다른 브라우저보다 일부 브라우저에서 더 잘 작동합니다.
확대 / 축소 중에 페이지를로드하면 페이지가 확대되었는지 확인할 수있는 방법이 없습니다.
document.body.offsetWidth
이 JavaScript를 사용하여 Zoom "이벤트"에 반응합니다.
창 너비를 폴링합니다. (이 페이지에서 다소 제안했듯이 (Ian Elliott가 링크 한) : http://novemberborn.net/javascript/page-zoom-ff3 [archive] )
IE가 아닌 Chrome, Firefox 3.6 및 Opera에서 테스트되었습니다.
감사합니다, 매그너스
var zoomListeners = [];
(function(){
// Poll the pixel width of the window; invoke zoom listeners
// if the width has been changed.
var lastWidth = 0;
function pollZoomFireEvent() {
var widthNow = jQuery(window).width();
if (lastWidth == widthNow) return;
lastWidth = widthNow;
// Length changed, user must have zoomed, invoke listeners.
for (i = zoomListeners.length - 1; i >= 0; --i) {
zoomListeners[i]();
}
}
setInterval(pollZoomFireEvent, 100);
})();
좋은 소식 여러분어떤 사람들은! 최신 브라우저는 확대 / 축소가 변경 될 때 창 크기 조정 이벤트를 트리거합니다.
다음과 같이 px_ratio를 정의하십시오.
px ratio = 물리적 픽셀 대 CSS px의 비율
하나의 확대 / 축소 페이지가 있으면 뷰포트 pxes (px는 픽셀과 다름)가 줄어들고 화면에 맞아야합니다. 따라서 화면 비율 (물리적 픽셀 / CSS_px)이 커져야합니다.
그러나 창 크기 조정에서 화면 크기와 픽셀 수가 줄어 듭니다. 비율이 유지됩니다.
그러나
크기 조정 : windows.resize 이벤트 트리거-> px_ratio를 변경하지 않습니다
//for zoom detection
px_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
$(window).resize(function(){isZooming();});
function isZooming(){
var newPx_ratio = window.devicePixelRatio || window.screen.availWidth / document.documentElement.clientWidth;
if(newPx_ratio != px_ratio){
px_ratio = newPx_ratio;
console.log("zooming");
return true;
}else{
console.log("just resizing");
return false;
}
}
핵심은 CSS PX와 Physical Pixel의 차이점입니다.
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
yonran
감지 할 수 있는 멋진 플러그인 이 있습니다. 다음은 StackOverflow 에 대해 이전에 답변 한 질문입니다. 대부분의 브라우저에서 작동합니다. 응용 프로그램은 다음과 같이 간단합니다.
window.onresize = function onresize() {
var r = DetectZoom.ratios();
zoomLevel.innerHTML =
"Zoom level: " + r.zoom +
(r.zoom !== r.devicePxPerCssPx
? "; device to CSS pixel ratio: " + r.devicePxPerCssPx
: "");
}
Always enable zoom
에서는 접근성 옵션 의 버튼을 선택하십시오. 데모는 변화에 반응하지 않습니다.
창 너비 변경을 추적하여 이전 솔루션의 개선을 제안하고 싶습니다. 고유 한 이벤트 리스너 배열을 유지하는 대신 기존 Javascript 이벤트 시스템을 사용하고 너비가 변경 될 때 고유 한 이벤트를 트리거하고 이벤트 핸들러를 바인딩 할 수 있습니다.
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
스로틀 / 디 바운스 는 처리기의 호출 속도를 줄이는 데 도움이 될 수 있습니다.
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
iOS 10에서는 이벤트에 이벤트 리스너를 추가 touchmove
하고 현재 이벤트로 페이지가 확대되어 있는지 감지 할 수 있습니다.
var prevZoomFactorX;
var prevZoomFactorY;
element.addEventListener("touchmove", (ev) => {
let zoomFactorX = document.documentElement.clientWidth / window.innerWidth;
let zoomFactorY = document.documentElement.clientHeight / window.innerHeight;
let pageHasZoom = !(zoomFactorX === 1 && zoomFactorY === 1);
if(pageHasZoom) {
// page is zoomed
if(zoomFactorX !== prevZoomFactorX || zoomFactorY !== prevZoomFactorY) {
// page is zoomed with this event
}
}
prevZoomFactorX = zoomFactorX;
prevZoomFactorY = zoomFactorY;
});
이것은 9 살짜리 질문이지만 문제는 지속됩니다!
프로젝트에서 확대 / 축소를 제외하는 동안 크기 조정을 감지 했으므로 크기를 조정하고 확대 / 축소를 독점적으로 감지하도록 코드를 편집했습니다. 대부분 의 시간에 작동 하므로 대부분 프로젝트에 충분하면 도움이 될 것입니다! 내가 지금까지 테스트 한 시간의 100 % 확대를 감지합니다. 유일한 문제는 사용자가 미치거나 (예 : 창 크기를 조정) 창 지연이 발생하면 창 크기 조정 대신 확대 / 축소로 실행될 수 있다는 것입니다.
그것은 변화를 감지하여 작동 window.outerWidth
또는 window.outerHeight
A의 변화를 감지하면서 크기를 조절 창으로 window.innerWidth
또는 window.innerHeight
줌으로 크기 조절 창에서 독립을.
//init object to store window properties
var windowSize = {
w: window.outerWidth,
h: window.outerHeight,
iw: window.innerWidth,
ih: window.innerHeight
};
window.addEventListener("resize", function() {
//if window resizes
if (window.outerWidth !== windowSize.w || window.outerHeight !== windowSize.h) {
windowSize.w = window.outerWidth; // update object with current window properties
windowSize.h = window.outerHeight;
windowSize.iw = window.innerWidth;
windowSize.ih = window.innerHeight;
console.log("you're resizing"); //output
}
//if the window doesn't resize but the content inside does by + or - 5%
else if (window.innerWidth + window.innerWidth * .05 < windowSize.iw ||
window.innerWidth - window.innerWidth * .05 > windowSize.iw) {
console.log("you're zooming")
windowSize.iw = window.innerWidth;
}
}, false);
참고 : 내 솔루션은 KajMagnus와 비슷하지만 나에게 더 효과적이었습니다.
0.05
적어도 좋은 설명을 제공하지 않는 등의 마법 번호를 사용하지 않는 것이 좋습니다 . ;-) 예를 들어 Chrome에서는 특히 10 %가 브라우저가 확대 할 수있는 최소 크기이지만 다른 브라우저에서는 이것이 사실인지 확실하지 않습니다. 참고로, 항상 코드가 테스트되었는지 확인하고 방어하거나 개선 할 수 있도록 준비하십시오.
깨끗한 해결책은 다음과 같습니다.
// polyfill window.devicePixelRatio for IE
if(!window.devicePixelRatio){
Object.defineProperty(window,'devicePixelRatio',{
enumerable: true,
configurable: true,
get:function(){
return screen.deviceXDPI/screen.logicalXDPI;
}
});
}
var oldValue=window.devicePixelRatio;
window.addEventListener('resize',function(e){
var newValue=window.devicePixelRatio;
if(newValue!==oldValue){
// TODO polyfill CustomEvent for IE
var event=new CustomEvent('devicepixelratiochange');
event.oldValue=oldValue;
event.newValue=newValue;
oldValue=newValue;
window.dispatchEvent(event);
}
});
window.addEventListener('devicepixelratiochange',function(e){
console.log('devicePixelRatio changed from '+e.oldValue+' to '+e.newValue);
});
resize 이벤트 는 이벤트를 on에 첨부 window
한 다음 body
( .getBoundingClientRect () ) 와 같은 다른 요소 의 값을 읽어 최신 브라우저에서 작동합니다 .
일부 이전 브라우저에서는 모든 HTML 요소에 크기 조정 이벤트 핸들러를 등록 할 수있었습니다. onresize 속성을 설정하거나 addEventListener ()를 사용하여 요소에 핸들러를 설정할 수 있습니다. 그러나 크기 조정 이벤트는 윈도우 객체에서만 발생합니다 (즉, document.defaultView에 의해 반환 됨). window 객체에 등록 된 핸들러 만 크기 조정 이벤트를 수신합니다 .
window.addEventListener("resize", getSizes, false)
function getSizes(){
let body = document.body
console.log(body.clientWidth +"px x "+ body.clientHeight + "px")
}
다른 대안 : ResizeObserver API
레이아웃에 따라 특정 요소의 크기 조정을 볼 수 있습니다.
확대 / 축소 할 때 컨테이너 상자의 크기가 조정되므로«반응 형»레이아웃에서 잘 작동합니다.
function watchBoxchange(e){
// console.log(e[0].contentBoxSize.inlineSize+" "+e[0].contentBoxSize.blockSize)
info.textContent = e[0].contentBoxSize.inlineSize+" * "+e[0].contentBoxSize.blockSize + "px"
}
new ResizeObserver(watchBoxchange).observe(fluid)
#fluid {
width: 200px;
height:100px;
overflow: auto;
resize: both;
border: 3px black solid;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 8vh
}
<div id="fluid">
<info id="info"></info>
</div>
사용자 제스처 이벤트에서 자바 스크립트 작업을 오버로드하지 않도록주의하십시오 . 다시 그리기가 필요할 때마다 requestAnimationFrame을 사용하십시오 .
MDN에 따르면 "matchMedia"는이를 수행하는 올바른 방법입니다 https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
각 인스턴스는 한 번에 하나의 MQ를 볼 수 있기 때문에 관심있는 그렇다면 그것은 조금 까다로운의 모든 당신이 매처 (matcher)의 무리를 할 필요 줌 레벨 변경 ..하지만 브라우저가 이벤트를 발광을 담당하고 있기 때문에 그것은 아마 여전히 폴링보다 성능이 뛰어나며 콜백을 조절하거나 디 바운싱하거나 애니메이션 프레임이나 그 밖의 것에 고정시킬 수 있습니다. 여기서 매우 딱딱한 구현이 있습니다.
코드 스 니펫을 실행하고 브라우저에서 확대 및 축소하고 마크 업의 업데이트 된 값을 확인하십시오. Firefox에서만 테스트했습니다! lemme는 문제가 있는지 알고 있습니다.
const el = document.querySelector('#dppx')
if ('matchMedia' in window) {
function observeZoom(cb, opts) {
opts = {
// first pass for defaults - range and granularity to capture all the zoom levels in desktop firefox
ceiling: 3,
floor: 0.3,
granularity: 0.05,
...opts
}
const precision = `${opts.granularity}`.split('.')[1].length
let val = opts.floor
const vals = []
while (val <= opts.ceiling) {
vals.push(val)
val = parseFloat((val + opts.granularity).toFixed(precision))
}
// construct a number of mediamatchers and assign CB to all of them
const mqls = vals.map(v => matchMedia(`(min-resolution: ${v}dppx)`))
// poor person's throttle
const throttle = 3
let last = performance.now()
mqls.forEach(mql => mql.addListener(function() {
console.debug(this, arguments)
const now = performance.now()
if (now - last > throttle) {
cb()
last = now
}
}))
}
observeZoom(function() {
el.innerText = window.devicePixelRatio
})
} else {
el.innerText = 'unable to observe zoom level changes, matchMedia is not supported'
}
<div id='dppx'>--</div>
3 살짜리 링크에 답장을했지만 여기에 더 적합한 답변이 있다고 생각합니다.
다음과 같이 .css 파일을 만듭니다.
@media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
EG :-
@media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
위의 코드는 화면이 약 125 %로 확대 될 때 글꼴 '10px'의 크기를 만듭니다. '1000px'의 값을 변경하여 다른 줌 레벨을 확인할 수 있습니다.
max-width
확대 / 축소 비율과 의 관계는 무엇입니까 ?