Có thể phát hiện, sử dụng JavaScript, khi người dùng thay đổi thu phóng trong một trang không? Tôi chỉ đơn giản muốn bắt một sự kiện "phóng to" và trả lời nó (tương tự như sự kiện window.onresize).
Cảm ơn.
Có thể phát hiện, sử dụng JavaScript, khi người dùng thay đổi thu phóng trong một trang không? Tôi chỉ đơn giản muốn bắt một sự kiện "phóng to" và trả lời nó (tương tự như sự kiện window.onresize).
Cảm ơn.
Câu trả lời:
Không có cách nào để chủ động phát hiện nếu có zoom. Tôi tìm thấy một mục tốt ở đây về cách bạn có thể cố gắng thực hiện nó.
Tôi đã tìm thấy hai cách để phát hiện mức thu phóng. Một cách để phát hiện các thay đổi mức thu phóng phụ thuộc vào thực tế là các giá trị phần trăm không được phóng to. Giá trị phần trăm liên quan đến chiều rộng khung nhìn và do đó không bị ảnh hưởng bởi thu phóng trang. Nếu bạn chèn hai yếu tố, một yếu tố có vị trí theo tỷ lệ phần trăm và một yếu tố có cùng vị trí tính bằng pixel, chúng sẽ di chuyển xa nhau khi trang được phóng to. Tìm tỷ lệ giữa các vị trí của cả hai yếu tố và bạn đã có mức thu phóng. Xem trường hợp thử nghiệm. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
Bạn cũng có thể làm điều đó bằng cách sử dụng các công cụ của bài viết trên. Vấn đề là bạn ít nhiều đưa ra những phỏng đoán có giáo dục về việc trang có được phóng to hay không. Điều này sẽ hoạt động tốt hơn trong một số trình duyệt hơn so với khác.
Không có cách nào để biết trang có được phóng to hay không nếu họ tải trang của bạn trong khi thu phóng.
document.body.offsetWidth
Tôi đang sử dụng đoạn JavaScript này để phản ứng với các "sự kiện" Thu phóng.
Nó thăm dò chiều rộng cửa sổ. (Như được đề xuất trên trang này (mà Ian Elliott đã liên kết đến): http://novemberborn.net/javascript/page-zoom-ff3 [archive] )
Đã thử nghiệm với Chrome, Firefox 3.6 và Opera, không phải IE.
Trân trọng, Magnus
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);
})();
Tin tốt tất cả mọi ngườimột số người! Các trình duyệt mới hơn sẽ kích hoạt sự kiện thay đổi kích thước cửa sổ khi thu phóng được thay đổi.
Hãy xác định px_ratio như sau:
tỷ lệ px = tỷ lệ pixel vật lý với css px.
nếu có bất kỳ thu phóng Trang nào, pxes của khung nhìn (px khác với pixel) sẽ giảm và phải vừa với Màn hình để tỷ lệ (pixel vật lý / CSS_px) phải lớn hơn.
nhưng trong cửa sổ Thay đổi kích thước, kích thước màn hình giảm cũng như pxes. do đó tỷ lệ sẽ duy trì.
nhưng
thay đổi kích thước: kích hoạt sự kiện windows.resize -> không thay đổi 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;
}
}
Điểm mấu chốt là sự khác biệt giữa CSS PX và Pixel vật lý.
https://gist.github.com/abilogos/66aba96bb0fb27ab3ed4a13245817d1e
Điều này làm việc cho tôi:
var deviceXDPI = screen.deviceXDPI;
setInterval(function(){
if(screen.deviceXDPI != deviceXDPI){
deviceXDPI = screen.deviceXDPI;
... there was a resize ...
}
}, 500);
Nó chỉ cần trên IE8. Tất cả các trình duyệt khác tự nhiên tạo ra một sự kiện thay đổi kích thước.
Có một plugin tiện lợi được xây dựng từ yonran
đó có thể thực hiện phát hiện. Đây là câu hỏi được trả lời trước đây của anh ấy trên StackOverflow. Nó hoạt động cho hầu hết các trình duyệt. Ứng dụng đơn giản như thế này:
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
nút trong tùy chọn Trợ năng. Bản demo sẽ không phản ứng với sự thay đổi.
Tôi muốn đề xuất một cải tiến cho giải pháp trước đó với việc theo dõi các thay đổi về chiều rộng cửa sổ. Thay vì giữ mảng trình lắng nghe sự kiện của riêng bạn, bạn có thể sử dụng hệ thống sự kiện javascript hiện có và kích hoạt sự kiện của riêng bạn khi thay đổi độ rộng và liên kết các trình xử lý sự kiện với nó.
$(window).bind('myZoomEvent', function() { ... });
function pollZoomFireEvent()
{
if ( ... width changed ... ) {
$(window).trigger('myZoomEvent');
}
}
Điều tiết / gỡ lỗi có thể giúp giảm tỷ lệ cuộc gọi của trình xử lý của bạn.
Bạn cũng có thể lấy các sự kiện thay đổi kích thước văn bản và hệ số thu phóng bằng cách chèn một div chứa ít nhất một không gian không thể phá vỡ (có thể, bị ẩn) và thường xuyên kiểm tra chiều cao của nó. Nếu chiều cao thay đổi, kích thước văn bản đã thay đổi, (và bạn biết bao nhiêu - điều này cũng kích hoạt, tình cờ, nếu cửa sổ được phóng to ở chế độ toàn trang và bạn vẫn sẽ có được hệ số thu phóng chính xác, với cùng chiều cao / tỷ lệ chiều cao).
<script>
var zoomv = function() {
if(topRightqs.style.width=='200px){
alert ("zoom");
}
};
zoomv();
</script>
Trên iOS 10 có thể thêm người nghe sự kiện vào touchmove
sự kiện và phát hiện, nếu trang được phóng to với sự kiện hiện tại.
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;
});
Mặc dù đây là một câu hỏi cũ 9 năm, vấn đề vẫn tồn tại!
Tôi đã phát hiện thay đổi kích thước trong khi loại trừ thu phóng trong một dự án, vì vậy tôi đã chỉnh sửa mã của mình để làm cho nó hoạt động để phát hiện cả thay đổi kích thước và thu phóng độc quyền với nhau. Nó hoạt động hầu hết thời gian, vì vậy nếu hầu hết là đủ tốt cho dự án của bạn, thì điều này sẽ hữu ích! Nó phát hiện thu phóng 100% thời gian trong những gì tôi đã thử nghiệm cho đến nay. Vấn đề duy nhất là nếu người dùng bị điên (tức là thay đổi kích thước cửa sổ một cách khó khăn) hoặc cửa sổ bị trễ, nó có thể kích hoạt dưới dạng phóng to thay vì thay đổi kích thước cửa sổ.
Nó hoạt động bằng cách phát hiện thay đổi trong window.outerWidth
hoặc window.outerHeight
thay đổi kích thước cửa sổ trong khi phát hiện thay đổi trong window.innerWidth
hoặc window.innerHeight
độc lập với thay đổi kích thước cửa sổ dưới dạng phóng to.
//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);
Lưu ý: Giải pháp của tôi giống như của KajMagnus, nhưng điều này đã làm việc tốt hơn với tôi.
0.05
ít nhất là không cung cấp một lời giải thích tốt. ;-) Ví dụ: tôi biết rằng trong Chrome, cụ thể, 10% là số tiền nhỏ nhất mà trình duyệt sẽ phóng to trong mọi trường hợp, nhưng không rõ ràng rằng điều này đúng với các trình duyệt khác. fyi, luôn đảm bảo mã của bạn được kiểm tra và sẵn sàng bảo vệ hoặc cải thiện nó.
Đây là một giải pháp sạch:
// 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);
});
Sự kiện thay đổi kích thước hoạt động trên các trình duyệt hiện đại bằng cách đính kèm sự kiện trên window
, sau đó đọc các giá trị của body
hoặc phần tử khác với ví dụ ( .getBoundingClientRect () ).
Trong một số trình duyệt trước đó, có thể đăng ký thay đổi kích thước trình xử lý sự kiện trên bất kỳ phần tử HTML nào. Vẫn có thể đặt thuộc tính onresize hoặc sử dụng addEventListener () để đặt trình xử lý trên bất kỳ phần tử nào. Tuy nhiên, thay đổi kích thước các sự kiện chỉ được kích hoạt trên đối tượng cửa sổ (tức là được trả về bởi document.defaultView). Chỉ các trình xử lý được đăng ký trên đối tượng cửa sổ sẽ nhận được các sự kiện thay đổi kích thước .
window.addEventListener("resize", getSizes, false)
function getSizes(){
let body = document.body
console.log(body.clientWidth +"px x "+ body.clientHeight + "px")
}
Một cách khác : API ResizeObserver
Tùy thuộc vào bố cục của bạn, bạn có thể xem để thay đổi kích thước trên một yếu tố cụ thể.
Điều này hoạt động tốt trên các bố trí «đáp ứng», vì hộp chứa được thay đổi kích thước khi thu phóng.
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>
Hãy cẩn thận để không làm quá tải các tác vụ javascript từ các sự kiện cử chỉ của người dùng. Sử dụng requestAnimationFrame bất cứ khi nào bạn cần vẽ lại.
Theo MDN, "matchMedia" là cách thích hợp để thực hiện điều này https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Monitoring_screen_resolution_or_zoom_level_changes
hơi khó hiểu vì mỗi phiên bản chỉ có thể xem một MQ tại một thời điểm, vì vậy nếu bạn quan tâm đến bất kỳ thay đổi mức thu phóng nào, bạn cần tạo ra một loạt các công cụ đối sánh .. nhưng vì trình duyệt có trách nhiệm phát ra các sự kiện nên có thể vẫn hiệu quả hơn so với bỏ phiếu và bạn có thể điều tiết hoặc gỡ bỏ cuộc gọi lại hoặc ghim nó vào khung hình động hoặc một cái gì đó - đây là một triển khai có vẻ khá thú vị, hãy thoải mái trao đổi trong _thrption hoặc bất cứ điều gì nếu bạn đã phụ thuộc vào điều đó.
Chạy đoạn mã và phóng to và thu nhỏ trong trình duyệt của bạn, lưu ý giá trị được cập nhật trong đánh dấu - Tôi chỉ thử nghiệm điều này trong Firefox! Để tôi biết nếu bạn thấy bất kỳ vấn đề.
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>
Tôi đang trả lời một liên kết 3 năm tuổi nhưng tôi đoán đây là một câu trả lời dễ chấp nhận hơn,
Tạo tập tin .css như,
@media screen and (max-width: 1000px)
{
// things you want to trigger when the screen is zoomed
}
VÍ DỤ:-
@media screen and (max-width: 1000px)
{
.classname
{
font-size:10px;
}
}
Đoạn mã trên làm cho kích thước của phông chữ '10px' khi màn hình được phóng to lên khoảng 125%. Bạn có thể kiểm tra mức thu phóng khác nhau bằng cách thay đổi giá trị '1000px'.
max-width
tỷ lệ và tỷ lệ thu phóng là gì?