简体   繁体   English

防止缩放跨浏览器

[英]Prevent zoom cross-browser

For a map-like tool, I would like to disable the browser zooming feature .对于类似地图的工具,我想禁用浏览器缩放功能 (I know that this is generally a bad idea, but for some specific website, it is needed). (我知道这通常是个坏主意,但对于某些特定网站来说,这是必需的)。

I did it successfully by listening the keyboard shortcut CTRL + / CTRL - and adding e.preventDefault() , etc. But this doesn't prevent from changing the zoom from the browser's Zoom menu.我通过听键盘快捷键CTRL + / CTRL -并添加e.preventDefault()等成功地做到了。但这并不能阻止从浏览器的缩放菜单更改缩放。

I tried:我试过:

  • with CSS: zoom: reset;使用 CSS: zoom: reset; It works for Chrome (see this page for a working example ) but it doesn't work at all on Firefox.它适用于 Chrome(请参阅此页面以获取工作示例),但它在 Firefox 上根本不起作用。

  • in various questions/answers, I also found在各种问题/答案中,我还发现

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

    but this seems to work for mobile only.但这似乎只适用于移动设备。


How to prevent zooming cross-browser?如何防止缩放跨浏览器?

I haven't really found an "authoritative" answer, meaning a clear statement from browser developers.我还没有真正找到一个“权威”的答案,这意味着浏览器开发人员的明确声明。 However, all answers to similar questions I've found (like this one or that one ) suggest the same thing - the browser's zoom feature exists for the benefit of the users and some browsers (like Firefox) simply don't allow you, as a website creator, to take this option away from them.但是,我发现的类似问题的所有答案(比如这个那个)都暗示了同样的事情——浏览器的缩放功能是为了用户的利益而存在的,而某些浏览器(比如 Firefox)根本不允许你,因为网站创建者,从他们那里拿走这个选项。


This documentation might shed some light into why allowing authors to disable zoom might be a good idea on mobile devices, but not on desktops. 该文档可能会阐明为什么允许作者禁用缩放在移动设备上可能是一个好主意,但在台式机上却不是。

In short, you might need to prevent mobile devices from initially auto-zooming your website, if you know their calculated auto-zoom will be inappropriate.简而言之,如果您知道移动设备计算的自动缩放不合适,您可能需要阻止移动设备最初自动缩放您的网站。 On desktops, there is no auto-zoom, so when users come to your website, they see it exactly as it was meant to be seen.在台式机上,没有自动缩放功能,因此当用户访问您的网站时,他们会完全按照预期看到它。 If they then decide they need to zoom the page, there's no good reason to let you prevent them from doing so.如果他们随后决定需要缩放页面,则没有充分的理由让您阻止他们这样做。


As for the solutions you've listed:至于您列出的解决方案:

  • zoom is a non-standard property not supported by Firefox , and zoomFirefox 不支持的非标准属性,并且
  • <meta name="viewport"> is concerned only with devices on which layout viewport and visual viewport are not the same thing , ie mobile devices. <meta name="viewport">只关注布局视口视觉视口不同的设备,即移动设备。

You can disable zoom in browser when using Ctrl + + or Ctrl + - or Ctrl + mouse wheel up or Ctrl + mouse wheel down with this code.使用此代码使用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();
       }
});

Check a demo here: JSFiddle .在此处查看演示: JSFiddle

I think what you can do is, listen to browser zoom event(ctrl + "+") and then check for window.devicePixelRatio.我认为您可以做的是,听浏览器缩放事件(ctrl +“+”),然后检查 window.devicePixelRatio。

Then accordingly, apply HTML5 scale transformation on the body element to scale down by the same ratio.然后相应地,对 body 元素应用 HTML5 缩放转换,以相同的比例缩小。 So, basically you cannot prevent the functionality but you can apply negative effect with the same magnitude.因此,基本上您无法阻止该功能,但您可以应用相同幅度的负面影响。

POC Code: 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>

Insert the following into your HTML:在您的 HTML 中插入以下内容:

For Mobiles: Insert between the '< head>...< /head>' tag.对于手机:在“<head>...</head>”标签之间插入。

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

For Desktops across-Browsers: Insert just after start '< body>...' tag.对于跨浏览器的桌面:在 start '<body>...' 标记之后插入。

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

So, as has been mentioned, that really isn't possible.所以,正如已经提到的,这确实是不可能的。 However, there are some ways you can still be smart about it.然而,有一些方法你仍然可以聪明地处理它。

Three of the five major browsers all allow you to see the zoom level of the browser, furthermore, should the browser be zoomed a window.onresize event is fired.五个主要浏览器中的三个都允许您查看浏览器的缩放级别,此外,如果浏览器被缩放,则会触发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 */

I think the stuff after OR works based on something I noticed as I was messing around.我认为 OR 之后的东西是基于我在胡闹时注意到的一些东西。 The first ones I know work in at least the latest version of each one.我知道的第一个至少在每个版本的最新版本中工作。 Note that Safari and Opera both have the devicePixelRatio , however both never change.请注意,Safari 和 Opera 都有devicePixelRatio ,但两者都不会改变。 It's always just 1 .它总是只有1

The above is your easy way if you don't care that much.如果您不太在意以上是您的简单方法。 If you do, then you could try out the detect-zoom script, which I came across while looking for solutions to Safari and Opera.如果你这样做了,那么你可以试试我在寻找 Safari 和 Opera 的解决方案时遇到的检测缩放脚本。

So what you can now do is get the zoom level, and then offset your zoom to where it doesn't do anything.所以你现在可以做的是获得缩放级别,然后将缩放偏移到它不做任何事情的地方。 So if I force my browser to 50% zoom, you just go to 200%.因此,如果我强制我的浏览器缩放 50%,您只需转到 200%。 Thus, no change.因此,没有变化。 Of course it will be a bit more complicated, you'll have to store the last browser zoom, the new browser zoom, and do some slightly more complicated math, but based on what you already have, that should be a breeze.当然它会更复杂一些,你必须存储上一次浏览器缩放,新浏览器缩放,并做一些稍微复杂的数学运算,但根据你已经拥有的,这应该是轻而易举的事。

Another idea might be to just listen for a resize event, and calculate based off the new visible size, but that might cause issues if the window is just resized.另一个想法可能是只监听一个调整大小事件,并根据新的可见大小进行计算,但如果窗口只是调整大小,这可能会导致问题。 I think the above is going to be your best option, with perhaps a fallback alert to warn the user not to zoom if necessary.我认为以上将是您最好的选择,也许还有一个后备alert ,以警告用户在必要时不要缩放。

I updated code Vijay code:我更新了代码 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();
    }
  });
});

This solution is cross-platform (OS / Win) for desktop browsers.该解决方案是针对桌面浏览器的跨平台 (OS/Win)。

Have you tried ...你有没有尝试过 ...

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

I've used this type of code to set or re-set the scale.我已经使用这种类型的代码来设置或重新设置比例。

$(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();
               }

      });
  })

It is simple:很简单:

 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>

Prevent browser zooming by keyboard is as same as above many answers.防止通过键盘缩放浏览器与上述许多答案相同。

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);

But prevent zooming by mouse wheel is different in modern browser now.但是现在在现代浏览器中防止鼠标滚轮缩放是不同的。 The new policy of Chrome need you use passive = false explicitly. Chrome 的新策略需要您明确使用 passive = false 。

{passive: false}

If not, event.preventDefault() can't stop the default action browser zooming by mouse wheel event, check it.如果不是,event.preventDefault()不能通过鼠标滚轮事件停止默认动作浏览器缩放,检查一下。

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

But we can't prevent clicking to zoom from the browser menu.但是我们不能阻止从浏览器菜单中点击放大。

Following code can prevent all types of zoom with mouse, keyboard gestures以下代码可以防止所有类型的鼠标、键盘手势缩放

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

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

Just tested this in the latest Chrome and it works fine.刚刚在最新的 Chrome 中对此进行了测试,它运行良好。 Give it a go.搏一搏。

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

This disables it for chrome and safari.这会为 chrome 和 safari 禁用它。 I haven't tested it on other browsers https://jsfiddle.net/gjqpLfht/我没有在其他浏览器上测试过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;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM