防止跨浏览器缩放

Prevent zoom cross-browser

本文关键字:缩放 浏览器      更新时间:2023-09-26

对于类似地图的工具,我想禁用浏览器缩放功能(我知道这通常是一个坏主意,但对于某些特定的网站,这是必需的)。

我通过聆听键盘快捷键 CTRL +/CTRL- 并添加e.preventDefault()等成功地做到了。但这并不能阻止从浏览器的缩放菜单更改缩放。

我试过了:

  • 使用 CSS: zoom: reset; 它适用于 Chrome(有关工作示例,请参阅此页面),但在 Firefox 上根本不起作用。

  • 在各种问题/答案中,我还发现

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

    但这似乎仅适用于移动设备。


如何防止跨浏览器缩放?

我还没有真正找到一个"权威"的答案,这意味着浏览器开发人员的明确声明。但是,我发现的类似问题的所有答案(例如这个或那个)都表明了同样的事情 - 浏览器的缩放功能是为了用户的利益而存在的,而某些浏览器(如 Firefox)根本不允许您作为网站创建者,从他们那里拿走此选项。


本文档可能会阐明为什么允许作者在移动设备上禁用缩放可能是一个好主意,但在台式机上则不然。

简而言之,如果您知道移动设备计算的自动缩放不合适,则可能需要阻止移动设备最初自动缩放您的网站。在台式机上,没有自动缩放功能,因此当用户访问您的网站时,他们会看到的完全符合预期。如果他们随后决定需要缩放页面,则没有充分的理由让您阻止他们这样做。


至于您列出的解决方案:

  • zoom 是 Firefox 不支持的非标准属性,并且
  • <meta name="viewport">只关注布局视口视觉视口不是一回事的设备,即移动设备。
使用此代码使用 Ctrl + + 或 Ctrl + - 或 Ctrl + 鼠标滚轮向上

Ctrl+鼠标滚轮向下时,可以禁用浏览器中的放大。

$(document).keydown(function(event) {
if (event.ctrlKey==true && (event.which == '61' || event.which == '107' || event.which == '173' || event.which == '109'  || event.which == '187'  || event.which == '189'  ) ) {
        event.preventDefault();
     }
    // 107 Num Key  +
    // 109 Num Key  -
    // 173 Min Key  hyphen/underscore key
    // 61 Plus key  +/= key
});
$(window).bind('mousewheel DOMMouseScroll', function (event) {
       if (event.ctrlKey == true) {
       event.preventDefault();
       }
});

在此处查看演示:JSFiddle。

HTML 中插入以下内容:

对于手机:插入"<头>...' 标签。

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">

对于跨浏览器的桌面:在开始"<正文>..."之后插入标记。

<script>
  document.body.addEventListener("wheel", e=>{
    if(e.ctrlKey)
      e.preventDefault();//prevent zoom
  });
</script>

我认为您可以做的是,收听浏览器缩放事件(ctrl + "+"),然后检查 window.devicePixelRatio。

然后相应地,对正文元素应用 HTML5 缩放转换,以按相同的比率缩小。因此,基本上您无法阻止该功能,但可以应用相同幅度的负面影响。

POC 代码:

 <body style="position: absolute;margin: 0px;">
        <div style="width: 300px; height: 200px; border: 1px solid black;">
            Something is written here
        </div>
        <script>
            var keyIncrease = [17, 61];
            var keyDecrease = [17, 173];
            var keyDefault = [17, 48];
            var listenMultiKeypress = function(keys, callback){
                var keyOn = [];
                for(var i=0; i<keys.length; i++){
                    keyOn[i] = false;
                }
                addEventListener('keydown', function(e){
                    var keyCode = e.which;
                    console.log(keyCode);
                    var idx = keys.indexOf(keyCode);
                    if(idx!=-1){
                        keyOn[idx] = true;
                    }
                    console.log(keyOn);
                    for(var i=0; i<keyOn.length; i++){
                        if(!keyOn[i]){
                            return;
                        }
                    }
                    setTimeout(callback, 100);
                });
                addEventListener('keyup', function(e){
                    var keyCode = e.which;
                    var idx = keys.indexOf(keyCode);
                    if(idx!=-1){
                        keyOn[idx] = false;
                    }
                    console.log(keyOn);
                });
            };
            var previousScale = 1;
            var previousDevicePixelRatio;
            var neutralizeZoom = function(){
                //alert('caught');
                var scale = 1/window.devicePixelRatio;
                document.body.style.transform = 'scale('+(1/previousScale)+')';
                document.body.style.transform = 'scale('+scale+')';
                var widthDiff = parseInt(getComputedStyle(window.document.body).width)*(scale-1);
                var heightDiff = parseInt(getComputedStyle(window.document.body).height)*(scale-1);
                document.body.style.left = widthDiff/2 + 'px';
                document.body.style.top = heightDiff/2 + 'px';
                previousScale = scale;
            };
            listenMultiKeypress(keyIncrease, neutralizeZoom);
            listenMultiKeypress(keyDecrease, neutralizeZoom);
            listenMultiKeypress(keyDefault, neutralizeZoom);
            neutralizeZoom();
        </script>
    </body>
</html>

所以,如前所述,这真的是不可能的。但是,有一些方法您仍然可以明智地使用它。

五种主要浏览器中的三种都允许您查看浏览器的缩放级别,此外,如果缩放浏览器,则会触发 window.onresize 事件。

IE:      event.view.devicePixelRatio           OR window.view.devicePixelRatio
Chrome:  event.currentTarget.devicePixelRatio  OR window.devicePixelRatio
Firefox: event.originalTarget.devicePixelRatio OR window.devicePixelRatio
Safari:  /* Not possible */
Opera:   /* Not possible */

我认为OR之后的东西是基于我在乱搞时注意到的东西。我知道的第一个至少在每个最新版本中工作。请注意,Safari 和 Opera 都有devicePixelRatio,但两者都永远不会改变。它总是只是1.

如果您不在乎那么多,以上是您的简单方法。如果你这样做,那么你可以尝试检测缩放脚本,这是我在寻找 Safari 和 Opera 解决方案时遇到的。

因此,您现在可以做的是获取缩放级别,然后将缩放偏移到它不执行任何操作的位置。因此,如果我强制浏览器缩放 50%,您只需缩放到 200%。因此,没有变化。当然,它会有点复杂,你必须存储最后一个浏览器缩放,新的浏览器缩放,并做一些稍微复杂的数学运算,但基于你已经拥有的东西,这应该是轻而易举的。

另一个想法可能是只侦听调整大小事件,并根据新的可见大小进行计算,但如果只是调整窗口大小,可能会导致问题。我认为以上将是你最好的选择,也许有一个后备alert来警告用户在必要时不要缩放。

我更新了代码Vijay代码:

$(document).ready(function(){
 var keyCodes = [61, 107, 173, 109, 187, 189];
 $(document).keydown(function(event) {   
   if (event.ctrlKey==true && (keyCodes.indexOf(event.which) != -1)) {
     alert('disabling zooming'); 
     event.preventDefault();
    }
 });
 $(window).bind('mousewheel DOMMouseScroll', function (event) {
    if (event.ctrlKey == true) {
      alert('disabling zooming'); 
      event.preventDefault();
    }
  });
});

此解决方案是针对桌面浏览器的跨平台(OS/Win)。

以下代码可以防止所有类型的鼠标缩放,键盘手势

document.addEventListener(
    "wheel",
    function touchHandler(e) {
      if (e.ctrlKey) {
        e.preventDefault();
      }
    }, { passive: false } );

对于移动设备,只需添加以下行 <meta name='viewport' content='width=device-width,initial-scale=1,user-scalable=no, maximum-scale=1.0, shrink-to-fit=no'>

$(document).ready(function () {
      $(document).keydown(function (event) {
          if (event.ctrlKey == true && (event.which == '107' || event.which == '109' || event.which == '187' || event.which == '189'))
           {
               event.preventDefault();
           }
       });
           $(window).bind('mousewheel DOMMouseScroll', function (event) {
               if (event.ctrlKey == true) {
                   event.preventDefault();
               }
      });
  })

很简单:

function load(){
  document.body.addEventListener("wheel", zoomShortcut); //add the event
}
function zoomShortcut(e){
  if(e.ctrlKey){            //[ctrl] pressed?
    event.preventDefault();  //prevent zoom
    if(e.deltaY<0){        //scrolling up?
                            //do something..
      return false;
    }
    if(e.deltaY>0){        //scrolling down?
                            //do something..
      return false;
    }
  }
}
p {
  display: block;
  background-color: #eeeeee;
  height: 100px;
}
<!DOCTYPE html>
<html>
  <head>
    <title>Mousewheel control!</title>
  </head>
  <body onload="load()">
    <p>If your Mouse is in this Box, you can't zoom.</p>
  </body>
</html>

你试过吗...

$("body").css({
     "-moz-transform":"scale(1)",
     "-webkit-transform":"scale(1)",
     "-o-transform":"scale(1)",
     "-ms-transform":"scale(1)"
});

我使用这种类型的代码来设置或重新设置比例。

通过键盘防止浏览器缩放与上述许多答案相同。

window.addEventListener('keydown', function (e) {
    if ((e.ctrlKey || e.metaKey) && (e.which === 61 || e.which === 107 || e.which === 173 || e.which === 109 || e.which === 187 || e.which === 189)) {
        e.preventDefault();
    }
}, false);

但是防止通过鼠标滚轮缩放现在在现代浏览器中是不同的。Chrome 的新政策要求您明确使用 passive = false。

{passive: false}

如果没有,event.preventDefault() 无法阻止默认操作浏览器通过鼠标滚轮缩放事件,请检查它。

const handleWheel = function(e) {
    if(e.ctrlKey || e.metaKey)
        e.preventDefault();
};
window.addEventListener("wheel", handleWheel, {passive: false});

但是我们无法阻止从浏览器菜单中单击以缩放。

刚刚在最新的Chrome中对此进行了测试,它工作正常。试一试。

window.addEventListener('wheel', e => {
  if (e.ctrlKey) {
    e.preventDefault();
  }
}, { passive: false });

如果您准备好暴力破解,则可以在 DOM 中设置px中的所有维度,以便在浏览器窗口调整大小或缩放网页时,所有尺寸保持不变。

尽管存在问题,但如果窗口调整大小时尺寸没有变化,则会破坏您网站的响应能力。为了防止这种情况,我相信您必须进行大量的媒体查询才能使网站逐步响应。

您可以尝试将身体尺寸保持在px,然后为其子级使用%。这样您只需要在媒体查询中更改正文尺寸。但这也意味着在媒体查询之间,您将溢出正文元素。而且我不知道如何解决这个问题

这将禁用它用于 chrome 和 safari。我还没有在其他浏览器上测试过它https://jsfiddle.net/gjqpLfht/

$(document).ready(function() {
    $(document).keydown(function(event) {
        if (event.ctrlKey == true && (event.which == '61' || event.which == '107' || event.which == '173' || event.which == '109' || event.which == '187' || event.which == '189')) {
            alert('disabling zooming');
            event.preventDefault();
            // 107 Num Key  +
            //109 Num Key  -
            //173 Min Key  hyphen/underscor Hey
            // 61 Plus key  +/=
        }
    });
    $(window).bind('mousewheel DOMMouseScroll', function(event) {
        if (event.ctrlKey == true) {
            alert('disabling zooming');
            event.preventDefault();
        }
    });
});

document.addEventListener("gesturestart", function(e) {
    e.preventDefault();
    document.body.style.zoom = 0.99;
});
document.addEventListener("gesturechange", function(e) {
    e.preventDefault();
    document.body.style.zoom = 0.99;
});
document.addEventListener("gestureend", function(e) {
    e.preventDefault();
    document.body.style.zoom = 1;
});