防止缩放跨浏览器

Posted

技术标签:

【中文标题】防止缩放跨浏览器【英文标题】:Prevent zoom cross-browser 【发布时间】:2015-01-22 20:05:35 【问题描述】:

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

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

我试过了:

使用 CSS:zoom: reset; 它适用于 Chrome(请参阅 this page for a working example),但在 Firefox 上根本不起作用。

在各种问题/答案中,我也发现了

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

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


如何防止跨浏览器缩放?

【问题讨论】:

@Skoua:可以覆盖这些快捷方式。我成功地做到了(使用window.onkeydowne.preventDefault())。我的问题是:如何防止从浏览器的菜单中缩放(查看>缩放设置等) 只听 'ctrl' 和 '鼠标滚轮' - 大多数用户在按住 ctrl 并滚动滚轮时放大和缩小。 . 对于那些一直到菜单放大/缩小的人 - 让他们成为:) 如果这是在闪存上,那就是另一回事了。无论如何,我一直在尝试构建一个脚本来检测浏览器的缩放级别,并使用 zoom 对 css 应用相反的效果,但这比我想象的要困难。 (使用tombigel.github.io/detect-zoom) 我可以轻松地调整浏览器窗口的大小,或更改分辨率,布局方式与缩放效果相同。那么,您实际上要防止什么?您真的要让您的网站只使用一种分辨率吗? @David:这是我的网站,你会明白我为什么要避免“标准”浏览器缩放:bigpicture.bi/demo 【参考方案1】:

我还没有真正找到“权威”的答案,即浏览器开发人员的明确声明。但是,我发现的所有类似问题的答案(如this one 或that one)都暗示了同样的事情 - 浏览器的缩放功能是为了用户的利益而存在的,而某些浏览器(如 Firefox)根本不允许你,作为网站创建者,请远离他们。


This documentation 可能会解释为什么允许作者禁用缩放在移动设备上可能是个好主意,但在台式机上却不行。

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


至于您列出的解决方案:

zoom 是非标准属性 not supported by Firefox,并且 <meta name="viewport"> 仅关注 layout viewportvisual viewport 为not the same thing 的设备,即移动设备。

【讨论】:

您在问题评论中链接的应用程序都是关于缩放的,这使我的回答与您的特定情况不太相关。不过,总的来说,我猜它可能会有所帮助。 检查我的答案如下,只需在 addEventerListener 时添加 passive: false window.addEventListener("wheel", handleWheel, passive: false); ***.com/questions/27116221/prevent-zoom-cross-browser/…【参考方案2】:

您可以在使用 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。

【讨论】:

Ctrl 和 + 使其缩放 是的,它在 chrome 浏览器中放大,现在再次检查我有更新条件。 从 2020 年起,这在我测试的任何浏览器中都不再有效【参考方案3】:

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

然后相应地,对 body 元素应用 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>

【讨论】:

【参考方案4】:

在您的 HTML 中插入以下内容:

对于手机:在“

...”标签之间插入。
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">

对于跨浏览器的桌面:在 start '

...' 标记之后插入。
<script>
  document.body.addEventListener("wheel", e=>
    if(e.ctrlKey)
      e.preventDefault();//prevent zoom
  );
</script>

【讨论】:

【参考方案5】:

所以,如前所述,这确实是不可能的。但是,您仍然可以通过一些方法对其保持精明。

五个主要浏览器中的三个都允许您查看浏览器的缩放级别,此外,如果浏览器被缩放,则会触发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 的解决方案时遇到的 detect-zoom 脚本。

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

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

【讨论】:

这可能是最好的方法,涵盖所有场景。 detect-zoom 脚本不适用于新版本的 Chrome 和 Firefox。但如前所述,支持 Safari 和 Opera。 您认为@David 是否可以更新此 HTML 页面gget.it/vtn8i8rb/NFB92BF.HTML,以便尽可能禁用缩放(当然,它不会在每个浏览器上都有效)与您在这里提出的技术?目前在这个页面上只有 CTRL + / CTRL - 被禁用 @Basj,这篇文章中提到的方法依赖于你的设计。这些属性是只读的,所以你能做的最好的就是抵消它们。例如。如果您在223% zoom,并且用户将其更改为150% zoom,那么您将阅读该内容,然后转到1.486% zoom 您的代码。 (如果我做对了数学:223/150)。如果用户再次更改,那么您会假装 150%100% 并以此为基础进行数学计算。您给出的页面之类的内容是纯文本,因此不起作用。此外,您不希望阻止缩放该类型的页面。【参考方案6】:

我更新了代码 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)。

【讨论】:

我将您的代码粘贴到 jsfiddle.net 中,我仍然可以使用 Command + 在 Mac 上放大 @NestMan,我想你忘了放 );最后。 这可以防止它缩放,很好,但是如果你真的尝试滚动缩放它仍然会在 chrome 上缩放。 在我的 macbook 上,我在触控板上伸出手指(同时在触控板上移动两个手指) - 浏览器调用“mousewheel”事件并且脚本不起作用,因为没有按下 crtlKey (两者都不是 Cmd 键)。【参考方案7】:
$(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();
               

      );
  )

【讨论】:

【参考方案8】:

很简单:

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>

【讨论】:

PS:您可以使用 CSS 为 webkit 浏览器做到这一点,如下所示: Control + Numpad +/- ?【参考方案9】:

你试过了吗……

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

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

【讨论】:

【参考方案10】:

这将为 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;
);

【讨论】:

目前无法在 MacOS 上的 Chrome 上运行。【参考方案11】:

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

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

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

【讨论】:

请完整阅读问题。这与对鼠标滚轮事件的反应无关。 是的,你是对的。有人说它不再适用于现代鲍泽。几天前我解决了车轮事件的缩放问题。也许它对某人有帮助。我提到这段代码不能阻止浏览器菜单触发的缩放。

以上是关于防止缩放跨浏览器的主要内容,如果未能解决你的问题,请参考以下文章

防止跨站攻击——CSRFToken

JSONP解决跨域问题,防止表单重复提交,防止XSS攻击

跨浏览器规范鼠标滚轮速度

详解浏览器跨域

关于跨域问题

浏览器跨域