240828-Gradio结合Html+Css+Javascript制作年历

news2024/12/22 22:48:38

A. 最终效果

需求描述

html javascript css 按年生成2016年至2116年的日历,要求如下:

  1. 二行六例,每个单元是一个月,且每个单元包含周次信息
  2. 通过背景为红色的圆圈高亮显示当前的日期
  3. 第一页显示今年,鼠标左边或键盘左键更新上一年,鼠标右键或键盘右键更新到下一年
  4. 将html javascript css写到同一个html文件中
  5. 根据浏览器的宽度,自适应的调整每个月度单元的宽度及字体的大小
  6. 整个年历在浏览器中水平居中,年份位于日历的正上方

在这里插入图片描述


B. HTML代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Yearly Calendar</title>
    <style>
      body {
        display: flex;
        flex-direction: column;
        align-items: center;
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 0;
      }
      #year {
        margin: 20px 0;
        font-size: 2rem;
        text-align: center;
      }
      .calendar {
        display: grid;
        grid-template-columns: repeat(6, 1fr);
        gap: 10px;
        width: 90%;
        max-width: 1200px;
      }
      .month {
        border: 1px solid #ddd;
        padding: 10px;
        box-sizing: border-box;
      }
      .month h3 {
        margin: 0;
        font-size: 1.2rem;
        text-align: center;
      }
      .weekdays,
      .days {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        text-align: center;
        font-size: 0.9rem;
      }
      .weekdays div {
        font-weight: bold;
        padding: 5px 0;
      }
      .days div {
        padding: 5px;
        cursor: pointer;
      }
      .days .today {
        background-color: red;
        border-radius: 50%;
        color: white;
      }
      @media (max-width: 800px) {
        .calendar {
          grid-template-columns: repeat(3, 1fr);
        }
        .month h3 {
          font-size: 1rem;
        }
        .weekdays,
        .days {
          font-size: 0.8rem;
        }
      }
      @media (max-width: 500px) {
        .calendar {
          grid-template-columns: repeat(2, 1fr);
        }
        .month h3 {
          font-size: 0.9rem;
        }
        .weekdays,
        .days {
          font-size: 0.7rem;
        }
      }
    </style>
  </head>
  <body>
    <div id="year"></div>
    <div class="calendar" id="calendar"></div>
    <script>
      const monthNames = [
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December",
      ];
      const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
      let currentYear = new Date().getFullYear();

      document.addEventListener("DOMContentLoaded", () => {
        renderCalendar(currentYear);
        document.getElementById("year").innerText = currentYear;
      });

      document.addEventListener("keydown", (event) => {
        if (event.key === "ArrowLeft") {
          updateYear(-1);
        } else if (event.key === "ArrowRight") {
          updateYear(1);
        }
      });

      document.addEventListener("click", (event) => {
        if (event.button === 0) {
          // Left click
          updateYear(-1);
        }
      });

      document.addEventListener("contextmenu", (event) => {
        event.preventDefault(); // Prevent default context menu
        updateYear(1); // Right click
      });

      function updateYear(offset) {
        currentYear += offset;
        if (currentYear < 2016) currentYear = 2016;
        if (currentYear > 2116) currentYear = 2116;
        document.getElementById("year").innerText = currentYear;
        renderCalendar(currentYear);
      }

      function renderCalendar(year) {
        const calendar = document.getElementById("calendar");
        calendar.innerHTML = "";
        for (let i = 0; i < 12; i++) {
          const monthDiv = document.createElement("div");
          monthDiv.className = "month";
          const monthTitle = document.createElement("h3");
          monthTitle.innerText = monthNames[i];
          monthDiv.appendChild(monthTitle);

          const weekdaysDiv = document.createElement("div");
          weekdaysDiv.className = "weekdays";
          weekdays.forEach((day) => {
            const dayDiv = document.createElement("div");
            dayDiv.innerText = day;
            weekdaysDiv.appendChild(dayDiv);
          });
          monthDiv.appendChild(weekdaysDiv);

          const daysDiv = document.createElement("div");
          daysDiv.className = "days";
          const firstDay = new Date(year, i, 1).getDay();
          const daysInMonth = new Date(year, i + 1, 0).getDate();

          // Add empty divs for days before the first day of the month
          for (let j = 0; j < firstDay; j++) {
            daysDiv.appendChild(document.createElement("div"));
          }

          // Add days of the month
          for (let j = 1; j <= daysInMonth; j++) {
            const dayDiv = document.createElement("div");
            dayDiv.innerText = j;
            const today = new Date();
            if (
              year === today.getFullYear() &&
              i === today.getMonth() &&
              j === today.getDate()
            ) {
              dayDiv.className = "today";
            }
            daysDiv.appendChild(dayDiv);
          }

          monthDiv.appendChild(daysDiv);
          calendar.appendChild(monthDiv);
        }
      }
    </script>
  </body>
</html>

C. Gradio代码

import gradio as gr

html_iframe = """
<iframe srcdoc='
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Yearly Calendar</title>
    <style>
      body {
        display: flex;
        flex-direction: column;
        align-items: center;
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 0;
      }
      #year {
        margin: 20px 0;
        font-size: 2rem;
        text-align: center;
      }
      .calendar {
        display: grid;
        grid-template-columns: repeat(6, 1fr);
        gap: 10px;
        width: 90%;
        max-width: 1200px;
      }
      .month {
        border: 1px solid #ddd;
        padding: 10px;
        box-sizing: border-box;
      }
      .month h3 {
        margin: 0;
        font-size: 1.2rem;
        text-align: center;
      }
      .weekdays,
      .days {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        text-align: center;
        font-size: 0.9rem;
      }
      .weekdays div {
        font-weight: bold;
        padding: 5px 0;
      }
      .days div {
        padding: 5px;
        cursor: pointer;
      }
      .days .today {
        background-color: red;
        border-radius: 50%;
        color: white;
      }
      @media (max-width: 800px) {
        .calendar {
          grid-template-columns: repeat(3, 1fr);
        }
        .month h3 {
          font-size: 1rem;
        }
        .weekdays,
        .days {
          font-size: 0.8rem;
        }
      }
      @media (max-width: 500px) {
        .calendar {
          grid-template-columns: repeat(2, 1fr);
        }
        .month h3 {
          font-size: 0.9rem;
        }
        .weekdays,
        .days {
          font-size: 0.7rem;
        }
      }
    </style>
  </head>
  <body>
    <div id="year"></div>
    <div class="calendar" id="calendar"></div>
    <script>
      const monthNames = [
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December",
      ];
      const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
      let currentYear = new Date().getFullYear();

      document.addEventListener("DOMContentLoaded", () => {
        renderCalendar(currentYear);
        document.getElementById("year").innerText = currentYear;
      });

      document.addEventListener("keydown", (event) => {
        if (event.key === "ArrowLeft") {
          updateYear(-1);
        } else if (event.key === "ArrowRight") {
          updateYear(1);
        }
      });

      document.addEventListener("click", (event) => {
        if (event.button === 0) {
          // Left click
          updateYear(-1);
        }
      });

      document.addEventListener("contextmenu", (event) => {
        event.preventDefault(); // Prevent default context menu
        updateYear(1); // Right click
      });

      function updateYear(offset) {
        currentYear += offset;
        if (currentYear < 2016) currentYear = 2016;
        if (currentYear > 2116) currentYear = 2116;
        document.getElementById("year").innerText = currentYear;
        renderCalendar(currentYear);
      }

      function renderCalendar(year) {
        const calendar = document.getElementById("calendar");
        calendar.innerHTML = "";
        for (let i = 0; i < 12; i++) {
          const monthDiv = document.createElement("div");
          monthDiv.className = "month";
          const monthTitle = document.createElement("h3");
          monthTitle.innerText = monthNames[i];
          monthDiv.appendChild(monthTitle);

          const weekdaysDiv = document.createElement("div");
          weekdaysDiv.className = "weekdays";
          weekdays.forEach((day) => {
            const dayDiv = document.createElement("div");
            dayDiv.innerText = day;
            weekdaysDiv.appendChild(dayDiv);
          });
          monthDiv.appendChild(weekdaysDiv);

          const daysDiv = document.createElement("div");
          daysDiv.className = "days";
          const firstDay = new Date(year, i, 1).getDay();
          const daysInMonth = new Date(year, i + 1, 0).getDate();

          // Add empty divs for days before the first day of the month
          for (let j = 0; j < firstDay; j++) {
            daysDiv.appendChild(document.createElement("div"));
          }

          // Add days of the month
          for (let j = 1; j <= daysInMonth; j++) {
            const dayDiv = document.createElement("div");
            dayDiv.innerText = j;
            const today = new Date();
            if (
              year === today.getFullYear() &&
              i === today.getMonth() &&
              j === today.getDate()
            ) {
              dayDiv.className = "today";
            }
            daysDiv.appendChild(dayDiv);
          }

          monthDiv.appendChild(daysDiv);
          calendar.appendChild(monthDiv);
        }
      }
    </script>
  </body>
</html>' width="100%" height="800px" style="border:none;"></iframe>
"""

with gr.Blocks() as demo:
    gr.HTML(html_iframe)

demo.launch(inbrowser=True)

D. 问题分析

问题描述:

直接将html文件中的内容插入到gr.HTML()后无法显示

解决方案:

代码中没有任何显示的原因可能是由于 Gradio 的 gr.HTML 组件在显示 HTML 内容时的限制问题。gr.HTML 组件只能渲染纯 HTML 和 CSS 内容,对于包含 JavaScript 的代码,它不会自动执行脚本。因此,尽管 HTML 内容被正确加载,JavaScript 却没有执行,从而导致页面没有预期的动态效果。

为了在 Gradio 中正确展示和运行 JavaScript,可以尝试以下解决方案:

使用 IFrame: 将完整的 HTML 内容放入一个独立的 HTML 文件中,然后通过 Gradio 的 gr.HTML 加载一个 IFrame,将这个 HTML 文件嵌入其中。
托管网页并嵌入: 将 HTML 内容托管在一个 web 服务器上(例如 GitHub Pages),然后在 Gradio 中通过 IFrame 引入外部链接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2083866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电梯按钮检测检测系统源码分享 # [一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]

电梯按钮检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

RKNPU入门与实践 ---- 混合量化

目录 前言 一、混合量化 1.1 概念介绍 1.1.1 hybrid_quantization_step1 1.1.2 hybrid_quantization_step2 二、实际编写程序 2.1混合量化第一阶段 2.2 混合量化第二阶段 三、混合量化第一步接口参数proposal 前言 为什么要进行混合量化&#xff1f; 答案&#x…

Zookeeper未授权访问的漏洞处理

echo envi |nc 192.168.0.1 2181 这个命令可以用于获取Zookeepr&#xff08;下面有zk代替&#xff09;目标服务器的环境信息、部署路径、版本等敏感信息。如果这些信息被恶意利用&#xff0c;确实可能导致安全漏洞&#xff0c;进而对网络和服务器安全构成威胁。 1.执行zkCli.…

XSS LABS - Level 17 过关思路

关注这个靶场的其他相关笔记&#xff1a;XSS - LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;过关流程 进入靶场&#xff0c;空空如也&#xff0c;右击页面&#xff0c;查看网页源码&#xff0c;找找可疑点&#xff1a; 可以看到&#xff0c;靶场默认传参&#xff0c;都传…

初赛试题-2022年CSP-J2

目录 先言 二、阅读程序&#xff08;判断题1.5分&#xff0c;选择题3分&#xff0c;共40分&#xff09; &#xff08;1&#xff09; 16. 17. 18. 19. 20. 21. &#xff08;2&#xff09; 22. 23. 24. 25. 26. 27. &#xff08;3&#xff09; 28. 29. 30. 3…

18.神经网络 - 非线性激活

神经网络 - 非线性激活 使用到的pytorch网站: Padding Layers&#xff08;对输入图像进行填充的各种方式&#xff09; 几乎用不到&#xff0c;nn.ZeroPad2d&#xff08;在输入tensor数据类型周围用0填充&#xff09; nn.ConstantPad2d&#xff08;用常数填充&#xff09; 在 …

【图像】灰度图与RGB图像的窗宽、窗位的值范围二三问

1. 16位灰度图的窗宽、窗位的值范围&#xff1f; 对于16位的灰度图像&#xff0c;每个像素点可以表示从0到2^16-1&#xff08;即0至65535&#xff09;之间的强度值。在医学影像领域&#xff0c;如CT扫描图像中&#xff0c;窗宽和窗位是用来调整图像对比度和亮度的参数&#xf…

【Spring Boot 3】【Web】自定义过滤器

【Spring Boot 3】【Web】自定义过滤器 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费…

fabricjs 添加图片并实时更新小车位置

需求&#xff1a;添加小车图片到画布中&#xff0c; 后端通过ws实时更新小车位置 实际过程中遇到的问题&#xff1a; 设置中心点&#xff1a;我想把图片的中心设置为后端传来的坐标点&#xff0c;可以通过设置对象的originX和originY属性来改变对象的旋转和定位基点。让小车…

error:0308010C:digital envelope routines::unsupported【超详细图解】

目录 一、报错信息 二、分析原因 三、解决方案 一、报错信息 二、分析原因 node.js 18 不兼容oppsll&#xff0c;node.js v17以上版本中最近发布的OpenSSL3.0, 而OpenSSL3.0对允许算法和密钥大小增加了严格的限制 三、解决方案 方案1&#xff1a;打开终端&#xff0c;直接输入…

Zotero7最新(2024)安装、配置步骤

提醒&#xff1a; 绝大部分插件都已经适配了 Zotero 7&#xff0c;但是 ZotFile 插件已经停止对 Zotero 7 的支持&#xff0c;可以使用 Attanger 插件 替代。如果不适应还是建议装Zotero 6 一、安装 1、进入官网&#xff0c;点击下载进入下载界面 https://www.zotero.org/h…

OpenCV绘图函数(7)从一个椭圆定义中提取出多边形的顶点坐标函数ellipse2Poly()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 近似一个椭圆弧为一个多边形线。 函数 ellipse2Poly 计算近似指定椭圆弧的多边形线的顶点。它被 ellipse 函数所使用。如果 arcStart 大于 arcEn…

[羊城杯 2024] Crypto

文章目录 TH_Curvebaby_CurveRSA_lossTheoremPlus TH_Curve 题目描述&#xff1a; from Crypto.Util.number import * from secret import flagdef add_THcurve(P, Q):if P (0, 0):return Qif Q (0, 0):return Px1, y1 Px2, y2 Qx3 (x1 - y1 ** 2 * x2 * y2) * pow(a * …

使用统计方法在AMD GPU上使用JAX Profiler可靠地比较大型生成AI模型中的算法性能

Using statistical methods to reliably compare algorithm performance in large generative AI models with JAX Profiler on AMD GPUs — ROCm Blogs 摘要 本文提供了一份详细的指南&#xff0c;介绍如何在JAX实现的生成AI模型中测量和比较各种算法的性能。利用JAX Profiler…

Python编码系列—Docker容器的高效使用与实战应用

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

前后端分离项目实战-通用管理系统搭建(前端Vue3+ElementPlus,后端Springboot+Mysql+Redis)第八篇:Tab标签页的实现

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

【Selenium】UI自动化实践——输入验证码登录

文章目录 实战题目解题方案 实战题目 使用pythonselenium实现输入验证码的UI自动化。登录页面如图&#xff1a; 解题方案 验证码登录需要导入相关模块和库&#xff0c;本文使用的是opencv和ddddocr模块组合&#xff0c;导入方式采用pip3 install opencv-python、pip3 insta…

JMeter 工具安装以及简单使用

一、安装以及汉化 傻瓜式JMeter下载和环境配置及永久汉化-CSDN博客https://blog.csdn.net/weixin_45608163/article/details/136528719 二、发送GET请求 配置请求头: 配置该线程组的请求: 放在线程组统计,下面请求则共享配置

深度强化学习算法(三)(附带MATLAB程序)

深度强化学习&#xff08;Deep Reinforcement Learning, DRL&#xff09;结合了深度学习和强化学习的优点&#xff0c;能够处理具有高维状态和动作空间的复杂任务。它的核心思想是利用深度神经网络来逼近强化学习中的策略函数和价值函数&#xff0c;从而提高学习能力和决策效率…

光性能 -- 光功率平坦度

什么是光功率平坦度? 光功率平坦度指的是&#xff0c;光放各单波功率值与所有波平均值的功率差。 通过MCA&#xff08;多通道光谱分析单元&#xff09;扫描OMS&#xff08;光复用段&#xff09;上的所有单波光功率&#xff0c;计算经过光放的所有波长的功率平均值&#xff0…