在 JavaScript 中使用媒体查询或在 CSS 中使用 if/else 语句

Posted

技术标签:

【中文标题】在 JavaScript 中使用媒体查询或在 CSS 中使用 if/else 语句【英文标题】:Using media queries in JavaScript or if/else statements in CSS 【发布时间】:2021-05-12 18:35:02 【问题描述】:

我正在构建一个具有可自定义打印设置的网页。发生的情况是,每当单击打印按钮时,都会打开一个对话框(我使用 onclick 属性和一些 js)。对话框中有一些复选框,命名如下:

删除菜单 删除侧边栏 删除链接和按钮 删除 cmets

所以,我想要的是,每当用户点击复选框时,链接的项目就会从 @media print 查询中删除。

所以,我能想到的方法是在 javascript 中使用媒体查询或在 css 中使用条件语句。

是否可能或需要其他语言?

【问题讨论】:

【参考方案1】:

我建议改为向项目添加/删除类,并将它们包含在您的打印 CSS 中。可以这么简单:

.hidden 
  display: none;

然后,在你的 JavaScript 中:

document.querySelector('.comments').classList.add('hidden');

另请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

【讨论】:

这将无法自定义... 打印时会自动剪裁这些项目。我希望它是用户删除或保留项目的选择 @WebDevelopmentPro 我不明白问题所在。当然,它是可定制的。您是否在问如何处理输入复选框上的change 事件?只有当用户在表单中表明这是他们想要的内容时,您才添加/删除 hidden 类(或任何您最终调用的类)。 我想要的是,在单击复选框时,链接项目从打印 css 设置为display: none;,一旦取消选中,项目设置为display: block;打印 css @Brad @WebDevelopmentPro 没错,完全正确。我告诉你,你可以简单地通过基于复选框状态添加/删除一个类来做到这一点。这样,您就可以将 CSS 保留在 CSS 中。 @WebDevelopmentPro 我会使用onchange,但是可以。【参考方案2】:

工作:

点击更新打印信息按钮更新打印信息,然后点击提交。

模式关闭后点击打印按钮查看变化。

我希望这段代码将来也能帮助很多用户。

祝大家好运。

function update_print()

  var style = "<style>@media print ";
    if (document.getElementById('remove_menu').checked)
    
        style += ".menu  display: none; ";
    
    if (document.getElementById('remove_sidebars').checked)
    
        style += ".sidebars  display: none; ";
    
    if (document.getElementById('remove_links_buttons').checked)
    
        style += ".links_buttons  display: none; ";
    
    if (document.getElementById('remove_comments').checked)
    
        style += ".comments  display: none; ";
    
    style += "</style>";
    document.getElementById("div_for_style").innerhtml = style;
  $('#myModal').modal('hide');
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<div id="print_box">
    <p class="menu">This is Menu</p>
    <p class="sidebars">This is Sidebar</p>
    <p class="links_buttons">This is Links & Buttons</p>
    <p class="comments">This is Comments</p>
</div>

<style>
@media print 
  .hide_while_print
  
      display: none;
  

</style>

<div class="container">
  <div class="hide_while_print">
  <button type="button" class="btn btn-info btn-md" data-toggle="modal" data-target="#myModal">Update Print Info</button>
  <button type="button" class="btn btn-info btn-md" onclick="window.print();">Print</button>
  </div>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">

  <!-- Modal content-->
  <div class="modal-content">
    <div class="modal-header">
      <button type="button" class="close" data-dismiss="modal">&times;</button>
      <h4 class="modal-title">Print Information</h4>
    </div>
    <div class="modal-body">
        <input type="checkbox" id="remove_menu" /> <label for="remove_menu">Remove Menu</label>
        <br />
        <input type="checkbox" id="remove_sidebars" /> <label for="remove_sidebars">Remove sidebars</label>
        <br />
        <input type="checkbox" id="remove_links_buttons" /> <label for="remove_links_buttons">Remove Links & Buttons</label>
        <br />
        <input type="checkbox" id="remove_comments" /> <label for="remove_comments">Remove Comments</label>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <input type="button" class="btn btn-success btn-sm" onclick="update_print();" value="Submit" />
    </div>
  </div>
  
</div>
</div>

<div id="div_for_style"></div>

【讨论】:

好的,你的 sn-p 工作正常,但可能有一些问题。单击“更新打印设置”时,对话框打开,但单击“提交”时不会关闭。好吧,这不是一个严重的问题,但是在单击“关闭”按钮并打印 sn-p 后,打印预览中会出现一些类似 css 的文本... 好的,谢谢!但是是否可以不链接外部样式表或脚本?另外,我不明白你为什么使用innerHTML... 这是因为整个文档已经很大了。 让我们continue this discussion in chat。【参考方案3】:

作为对this one 的补充回答:提供的 sn-p 可以从重构中受益,以避免常见的陷阱:

    Do not use 内联事件属性,现代方法是使用 addEventListener 代替(如果您绝对必须支持旧浏览器,请使用 polyfill 和捆绑程序,但不要这样编写源代码)。 避免字符串连接和if 语句集,使代码可维护。有一种修改 Element 类的本地方法 - 通过 classList 属性公开 DOMTokenList 方法,如 addremove。 避免使用innerHTML 更新节点(例如,请参阅here 了解详细信息)和元素样式(您可以使用style 属性以编程方式更新特定值)。

以下是处理上述问题的重新设计的 sn-p(请注意 HTML 标记的更改):

(() => 
  const $ = (selector) => document.querySelector(selector);
  const $$ = (selector) => document.querySelectorAll(selector);

  const submitBtn = $("#submit");
  const modal = $("#myModal");
  const inputs = $$("input[type=checkbox]");
  const hideClass = "hide_while_print";

  submitBtn.addEventListener("click", (event) => 
    inputs.forEach((
      id,
      checked
    ) => 
      const 
        classList
       = $(`.$id.replace("remove_", "")`);
      checked ? classList.add(hideClass) : classList.remove(hideClass);
    );

  );

  $("#print").addEventListener("click", () => window.print());
)();
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<div id="print_box">
  <p class="menu">This is Menu</p>
  <p class="sidebars">This is Sidebar</p>
  <p class="links_buttons">This is Links & Buttons</p>
  <p class="comments">This is Comments</p>
</div>

<style>
  @media print 
    .hide_while_print 
      display: none;
    
  
</style>

<div class="container">
  <div class="hide_while_print">
    <button type="button" class="btn btn-info btn-md" data-toggle="modal" data-target="#myModal">Update Print Info</button>
    <button id="print" type="button" class="btn btn-info btn-md">Print</button>
  </div>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
  <div class="modal-dialog">

    <!-- Modal content-->
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">&times;</button>
        <h4 class="modal-title">Print Information</h4>
      </div>
      <div class="modal-body">
        <input type="checkbox" id="remove_menu" /> <label for="remove_menu">Remove Menu</label>
        <br />
        <input type="checkbox" id="remove_sidebars" /> <label for="remove_sidebars">Remove sidebars</label>
        <br />
        <input type="checkbox" id="remove_links_buttons" /> <label for="remove_links_buttons">Remove Links & Buttons</label>
        <br />
        <input type="checkbox" id="remove_comments" /> <label for="remove_comments">Remove Comments</label>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-success" data-dismiss="modal" id="submit">Submit</button>
      </div>
    </div>

  </div>
</div>

在 sn-p 中,我隐藏了 $ 以使用 DOM API 定义一个轻量级实用程序。如果您不使用 Bootstrap(将 JQuery 作为 hard dependency),$$$ 实用程序可以让您避免加载 JQuery 来选择元素。

【讨论】:

【参考方案4】:

你可以使用:checked:

@media print 
  .checkbox-class:checked + .remove-me 
    display: none;
  

记住类.remove-me 的元素应该是相邻的兄弟元素。像这样:

<label for="checkbox-id">Click Me</label>
<input type="checkbox" id="checkbox-id" class="checkbox-class">

<div class="remove-me">
  Lorem ipsum dolor sit amet consectetur adipisicing elit.
</div>

在 Codepen 上查看它:Editor ViewDebug Mode

【讨论】:

这个有帮助,但是菜单和侧边栏不相邻,也不是所有的链接都与侧边栏相邻

以上是关于在 JavaScript 中使用媒体查询或在 CSS 中使用 if/else 语句的主要内容,如果未能解决你的问题,请参考以下文章

如何在带有 javascript 条件的媒体查询中使用 css?

使用 JavaScript 检测动态媒体查询而不在脚本中硬编码断点宽度?

javascript 命令无法使用媒体查询打印

如何使用 Javascript 或 CSS 在 DIV 上应用媒体查询 [重复]

如何将 css 变量传递给 Javascript 对象中的媒体查询? [复制]

如何使用 Javascript 获取“css-pixel”(媒体查询)宽度?