首页 > web前端 > js教程 > 正文

NgSysV.响应式/自适应设计

Susan Sarandon
发布: 2024-11-27 21:13:09
原创
578 人浏览过

NgSysV.Responsive/Adaptive Design

此帖子系列已在 NgateSystems.com 建立索引。您还可以在那里找到超级有用的关键字搜索工具。

最后评论:24 年 11 月

一、简介

帖子 4.2 透露,如果您希望您的 web 应用程序出现在网络搜索中,您必须确保:

  • 您的网络应用程序在手机小屏幕上查看时效果良好,并且
  • 您想要被搜索引擎索引的所有内容都可以在移动版本上看到。

如果您的软件主要面向桌面用户,这是一个巨大的麻烦 - 但这就是生活。让我们看看您如何系统地解决这个问题。

2.使用Tailwind的响应式设计

响应式设计使用 CSS 样式的“内置”功能来测试显示设备的宽度并相应地调整格式。这一切都会在浏览器中自动发生 - 但您仍然必须提供有关每个“断点”(要应用新的特定于宽度的样式的屏幕宽度)处发生的情况的明确说明。

到目前为止,您在本系列中使用的标准 CSS 样式通过使用一种称为“媒体查询”的技术来实现这些自适应效果。但在这篇文章中,我将向您介绍一个名为 Tailwind 的“开放库”。这是为响应式样式量身定制的,并且具有许多额外的优点。

以下是 Tailwind 样式的示例,它将在宽度不超过 768 像素的屏幕上将居中标题限制为屏幕宽度的 95%。在此宽度之上,居中标题被限制为屏幕宽度的 60%:

<h1>



<p>Previously in this series, you've seen styles applied to HTML elements like <p> by adding>

<p>The essence of Tailwind is that it provides a system of single-purpose "utility classes", each of which applies a specific set of styles to an element. The class names are chosen judiciously to provide a meaningful and practical expression of styling intentions. The example below styles a <p> element with 4rem padding on all four sides and a  background color of light gray.<br>
</p>

<pre class="brush:php;toolbar:false"><div>



<p>Here, in bg-blue-500, bg says that this is a background style, blue sets the background colour to blue and 500 sets the colour "intensity" to a mid-value on a scale of 100 (light) to 900 (dark).</p>

<p>This is fine in its way, but the system may only become of interest to you when I tell you that you can make the tailwind utility classes responsive by simply adding a prefix to the style.</p>

<p>Tailwind recognizes the following screen-width "breakpoints":</p>

<div><table>
<thead>
<tr>
<th>Prefix</th>
<th>Screen Size</th>
<th>Minimum Width</th>
</tr>
</thead>
<tbody>
<tr>
<td>sm</td>
<td>Small devices</td>
<td>640px</td>
</tr>
<tr>
<td>md</td>
<td>Medium devices</td>
<td>768px</td>
</tr>
<tr>
<td>lg</td>
<td>Large devices</td>
<td>1024px</td>
</tr>
<tr>
<td>xl</td>
<td>Extra large devices</td>
<td>1280px</td>
</tr>
<tr>
<td>2xl</td>
<td>2x Extra large devices</td>
<td>1536px</td>
</tr>
</tbody>
</table></div>

<p>A style class such as "bg-gray-200" might thus be made to apply only to screens larger than 640px by specifying it as "sm:bg-gray-200".</p>

<p>The "This div has padding on all sides." example above could thus be made to display its paragraph with a blue background on screens with a maximum width of 640px and green on screens larger than this by styling it as follows:<br>
</p>

<pre class="brush:php;toolbar:false"><p>



<p>Because classes to the right take precedence, this makes the default background blue and overrides this with green when the screen is large enough. </p>

<p>For a fuller account of the Tailwind system and instructions on how to istall this in your project please see the Tailwind Website.</p>

<h3>
  
  
  3. Adaptive design for Server-side rendered webapps
</h3>

<p>Responsive design won't help you achieve more drastic effects where the desktop and mobile versions of a webapp are seriously different. Whereas a <strong>responsive design</strong> adjusts a standard pattern"fluidly" to accommodate different screen sizes, an <strong>adaptive</strong> design is prepared to give screen widths tailor-made solutions. </p>

<p>Expanding on the "tailoring" theme, you might think of responsive design as creating a single suit made of stretchable fabric that fits anyone. By contrast, adaptive design is like creating multiple tailored suits for different body types.</p>

<p>So if, for example, you felt that the mobile customers for your webapp were completely different from your desktop fans, you might want to give each community a tailor-made design (while delivering both under the same URL). </p>

<p>Conceptually, the obvious way to express this arrangement would be a displayIsMobile boolean guiding the display of MobileLayout and DesktopLayout components, as follows:<br>
</p>

<pre class="brush:php;toolbar:false">{#if displayIsMobile}
  <MobileLayout />
{:else}
  <DesktopLayout />
{/if}
登录后复制
登录后复制
登录后复制

但是您现在会问“这个 displayIsMobile 布尔值如何初始化?”

当服务器收到对 myURL/myPage 的浏览器请求时,首先运行的通常是 page.server.js 文件中的 load() 函数,运行 服务器端 来提供初始数据对于页面。当 myPage 的 page.svelte - 也在服务器端运行 - 接收到此数据时,它将想要执行其“模板”部分的初始渲染,并将 HTML 块发送回浏览器。但要做到这一点,它需要一个 displayIsMobile 的值。

如果您运行的是“客户端”,那么答案很简单 - 使用“window”对象来检查 window.width 并相应地设置 displayIsMobile。但在这种情况下,page.server.js 和 page.svelte 文件(像它们一样在服务器端运行)都无法直接询问客户端。

一种选择可能是为 displayIsMobile 选择适当的默认值并返回默认显示。然后,您可以在客户端上使用 onMount() 函数来检查其窗口属性并更适当地重新呈现默认显示。然而,会产生两个后果:

  • 当每个页面启动然后重新渲染时,初始显示的重新渲染会在客户端设备上产生令人不快的“闪烁”效果。
  • SEO 可能会受到严重损害,因为网络爬虫(可能并不总是执行 JavaScript)可能看不到正确的内容。

因此,如果您想正确处理此问题,您必须找到一种在服务器上适当设置 displayisMobile 的方法。 这样您就可以尽快向客户端发送完全渲染的页面,从而优化性能和 SEO。

如果您阅读过 Post 3.5,您会记得服务器请求附带的“标头”可用于传输有用的信息。浏览器请求页面 myURL/myPage 的标头可能包含任何有用的内容吗?

值得庆幸的是,答案是“是的 - 他们确实如此”。例如,浏览器请求用户代理标头包含一个“引擎和浏览器”组件,该组件可用于告诉您该请求来自移动浏览器而不是桌面浏览器。但用户代理请求标头的根源在于计算最黑暗的过去,其功能一直在努力平衡多种相互竞争的利益。

这里的主要问题是对用户环境的过于精确的描述(标题还包括用户浏览器、操作系统类型和版本等的详细信息)可能会被用来在用户导航时识别和跟踪用户。网络。这个问题还没有解决。

这是一个“用户代理”示例:

<h1>



<p>Previously in this series, you've seen styles applied to HTML elements like <p> by adding>

<p>The essence of Tailwind is that it provides a system of single-purpose "utility classes", each of which applies a specific set of styles to an element. The class names are chosen judiciously to provide a meaningful and practical expression of styling intentions. The example below styles a <p> element with 4rem padding on all four sides and a  background color of light gray.<br>
</p>

<pre class="brush:php;toolbar:false"><div>



<p>Here, in bg-blue-500, bg says that this is a background style, blue sets the background colour to blue and 500 sets the colour "intensity" to a mid-value on a scale of 100 (light) to 900 (dark).</p>

<p>This is fine in its way, but the system may only become of interest to you when I tell you that you can make the tailwind utility classes responsive by simply adding a prefix to the style.</p>

<p>Tailwind recognizes the following screen-width "breakpoints":</p>

<div><table>
<thead>
<tr>
<th>Prefix</th>
<th>Screen Size</th>
<th>Minimum Width</th>
</tr>
</thead>
<tbody>
<tr>
<td>sm</td>
<td>Small devices</td>
<td>640px</td>
</tr>
<tr>
<td>md</td>
<td>Medium devices</td>
<td>768px</td>
</tr>
<tr>
<td>lg</td>
<td>Large devices</td>
<td>1024px</td>
</tr>
<tr>
<td>xl</td>
<td>Extra large devices</td>
<td>1280px</td>
</tr>
<tr>
<td>2xl</td>
<td>2x Extra large devices</td>
<td>1536px</td>
</tr>
</tbody>
</table></div>

<p>A style class such as "bg-gray-200" might thus be made to apply only to screens larger than 640px by specifying it as "sm:bg-gray-200".</p>

<p>The "This div has padding on all sides." example above could thus be made to display its paragraph with a blue background on screens with a maximum width of 640px and green on screens larger than this by styling it as follows:<br>
</p>

<pre class="brush:php;toolbar:false"><p>



<p>Because classes to the right take precedence, this makes the default background blue and overrides this with green when the screen is large enough. </p>

<p>For a fuller account of the Tailwind system and instructions on how to istall this in your project please see the Tailwind Website.</p>

<h3>
  
  
  3. Adaptive design for Server-side rendered webapps
</h3>

<p>Responsive design won't help you achieve more drastic effects where the desktop and mobile versions of a webapp are seriously different. Whereas a <strong>responsive design</strong> adjusts a standard pattern"fluidly" to accommodate different screen sizes, an <strong>adaptive</strong> design is prepared to give screen widths tailor-made solutions. </p>

<p>Expanding on the "tailoring" theme, you might think of responsive design as creating a single suit made of stretchable fabric that fits anyone. By contrast, adaptive design is like creating multiple tailored suits for different body types.</p>

<p>So if, for example, you felt that the mobile customers for your webapp were completely different from your desktop fans, you might want to give each community a tailor-made design (while delivering both under the same URL). </p>

<p>Conceptually, the obvious way to express this arrangement would be a displayIsMobile boolean guiding the display of MobileLayout and DesktopLayout components, as follows:<br>
</p>

<pre class="brush:php;toolbar:false">{#if displayIsMobile}
  <MobileLayout />
{:else}
  <DesktopLayout />
{/if}
登录后复制
登录后复制
登录后复制

我认为很容易看出解析这个烂摊子时会遇到的问题!

但是还有其他选择。 Google 最近的一项举措建议浏览器应该提供一个新的、更简单的标头,称为 sec-ch-ua-mobile。它包含一个简单的字符串,告诉您浏览器是否期望移动响应(有关详细信息,请参阅 Sec-CH-UA-Mobile)。

但是,虽然 Chrome 和 Edge 现在可以使用 sec-ch-ua-mobile 标头,但其他浏览器不一定支持该计划。无论如何,sec-ch-ua-mobile 标头不会为您提供足够的详细信息来完善您的响应并提供明确的“平板电脑”版本。

这一切都非常乏味,但可能足以让您得出结论,您很乐意使用 sec-ch-ua-mobile 作为第一个停靠点,并使用 user-agent 作为后备。在这种情况下,这里有一些代码可以为 page.svelte 文件提供一个 displayIsMobile 变量。

令人困惑的是,它以一种名为 hooks.server.js 文件的新型 Svelte 文件开头。

虽然您可能在 load() 函数中放置为 page.svelte 文件设置 displayIsMobile 的代码,但并非每个 page.svelte 页面都会具有其中之一。即使确实如此(当然,您总是可以创建一个),您也会发现必须在 all load() 函数中复制 displayIsMobile 代码。

相比之下,hooks.server.js 文件是一种“超级”load() 函数,Svelte 会针对提交到服务器的每个 请求启动。它在执行任何其他活动之前运行。这使得它成为检查 sec-ch-ua-mobile 标头并为 displayIsMobile 创建值的完美位置。

下面的代码显示了如何通过 hooks.server.js 文件构建 displayIsMobile。它还显示了如何将此值传回预期的 page.svelte 文件。


<h1>



<p>Previously in this series, you've seen styles applied to HTML elements like <p> by adding>

<p>The essence of Tailwind is that it provides a system of single-purpose "utility classes", each of which applies a specific set of styles to an element. The class names are chosen judiciously to provide a meaningful and practical expression of styling intentions. The example below styles a <p> element with 4rem padding on all four sides and a  background color of light gray.<br>
</p>

<pre class="brush:php;toolbar:false"><div>



<p>Here, in bg-blue-500, bg says that this is a background style, blue sets the background colour to blue and 500 sets the colour "intensity" to a mid-value on a scale of 100 (light) to 900 (dark).</p>

<p>This is fine in its way, but the system may only become of interest to you when I tell you that you can make the tailwind utility classes responsive by simply adding a prefix to the style.</p>

<p>Tailwind recognizes the following screen-width "breakpoints":</p>

<div><table>
<thead>
<tr>
<th>Prefix</th>
<th>Screen Size</th>
<th>Minimum Width</th>
</tr>
</thead>
<tbody>
<tr>
<td>sm</td>
<td>Small devices</td>
<td>640px</td>
</tr>
<tr>
<td>md</td>
<td>Medium devices</td>
<td>768px</td>
</tr>
<tr>
<td>lg</td>
<td>Large devices</td>
<td>1024px</td>
</tr>
<tr>
<td>xl</td>
<td>Extra large devices</td>
<td>1280px</td>
</tr>
<tr>
<td>2xl</td>
<td>2x Extra large devices</td>
<td>1536px</td>
</tr>
</tbody>
</table></div>

<p>A style class such as "bg-gray-200" might thus be made to apply only to screens larger than 640px by specifying it as "sm:bg-gray-200".</p>

<p>The "This div has padding on all sides." example above could thus be made to display its paragraph with a blue background on screens with a maximum width of 640px and green on screens larger than this by styling it as follows:<br>
</p>

<pre class="brush:php;toolbar:false"><p>



<p>Because classes to the right take precedence, this makes the default background blue and overrides this with green when the screen is large enough. </p>

<p>For a fuller account of the Tailwind system and instructions on how to istall this in your project please see the Tailwind Website.</p>

<h3>
  
  
  3. Adaptive design for Server-side rendered webapps
</h3>

<p>Responsive design won't help you achieve more drastic effects where the desktop and mobile versions of a webapp are seriously different. Whereas a <strong>responsive design</strong> adjusts a standard pattern"fluidly" to accommodate different screen sizes, an <strong>adaptive</strong> design is prepared to give screen widths tailor-made solutions. </p>

<p>Expanding on the "tailoring" theme, you might think of responsive design as creating a single suit made of stretchable fabric that fits anyone. By contrast, adaptive design is like creating multiple tailored suits for different body types.</p>

<p>So if, for example, you felt that the mobile customers for your webapp were completely different from your desktop fans, you might want to give each community a tailor-made design (while delivering both under the same URL). </p>

<p>Conceptually, the obvious way to express this arrangement would be a displayIsMobile boolean guiding the display of MobileLayout and DesktopLayout components, as follows:<br>
</p>

<pre class="brush:php;toolbar:false">{#if displayIsMobile}
  <MobileLayout />
{:else}
  <DesktopLayout />
{/if}
登录后复制
登录后复制
登录后复制
现在,displayIsMobile 位于浏览器请求的事件对象中。该事件是 SvelteKit 构造的一个复杂对象,用于表示当前请求。它包含以下属性:

    event.request:这是原始的 Request 对象,包含 HTTP 方法(GET、POST 等)、标头、URL 和正文等详细信息。
  • event.locals:在请求的后续生命周期中提供此数据的位置。
正如您所想象的,由于 event 现在可以在任何需要它的地方使用,event.locals 正是您为 displayIsMobile 提供一个家所需要的。

handle() 的 {event, response} 参数的形式可能会让您感到困惑。这是“解构”语法的示例。这使您能够直接从对象中提取特定属性,而无需引用对象本身。假设有一个超级对象 args,其中包含事件和响应作为属性。然后而不是使用传统的


User-Agent: Mozilla/4.9 Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
登录后复制
“解构语法”允许您将其写为


// src/hooks.server.js
export async function handle({ event, resolve }) {

    let displayIsMobile;
    console.log("event.request.headers['sec-ch-ua-mobile']: ", event.request.headers.get('sec-ch-ua-mobile'));
    // First, try to get the mobile flag from the 'sec-ch-ua-mobile' header. This is a string header
    // and its value is '?1' if the user agent is a mobile device, otherwise it is '?0'.
    if (event.request.headers.get('sec-ch-ua-mobile') !== undefined) {
        displayIsMobile = event.request.headers.get('sec-ch-ua-mobile') === '?1' ? true : false;
    } else {
        // Otherwise, try the 'user-agent' header. For robust mobile detection, you might consider using
        // the ua-parser-js library. It provides consistent results across various edge cases.
        if (event.request.headers.get('user-agent') !== undefined) {
            displayIsMobile = event.request.headers.get('user-agent').toLowerCase().includes('mobile');
        } else {
            displayIsMobile = false
        }
    }

    // Put displayIsMobile into event.locals. This is an object provided by SvelteKit that is specific to a
    // particular browser request and which is acessible in every page and layout. In brief, event.locals lets
    // you pass data throughout the lifecycle of a request in SvelteKit. It provides a convenient way to share
    // computed values or state without needing to repeat logic or fetch data multiple times.
    event.locals.displayIsMobile = displayIsMobile;

    // Proceed with the request. In SvelteKit, resolve(event) is crucial for handling the request lifecycle.
    // It processes the current request and generates the final response that will be sent back to the client.
    const response = await resolve(event);
    return response;
}
登录后复制
本质上,这是一种在不知道父对象名称(args)的情况下引用对象 args 的属性(args.event 等)的方法。这会导致代码更紧凑、更有弹性。

无论如何,尽管如此,由于 displayIsMobile 现在位于浏览器请求的事件对象中,显然要做的事情就是在 page.server.js 文件中使用 load() 函数将其挖掘出来并返回它到 page.svelte。


function handle(args) {
    const event = args.event;
    const resolve = args.resolve;
    // ... (code referencing variables "event" and "resolve")
}
登录后复制
最后,这是一个非常简单的 page.svelte 文件,用于提供自适应页面


function handle({ event, resolve }) {
    // ...(code referencing variables "event" and "resolve")
}
登录后复制
希望您喜欢!

总而言之,完整的顺序是:

  1. Sveltekit 服务器处理浏览器的 myURL/myPage 请求并启动项目的 hooks.server.js 文件。在这里,检索请求标头,确定适当的 displayIsMobile 值,并将结果隐藏在 Sveltekit 事件对象中。
  2. myPage 路由的 page.server.j 文件中的 load() 函数从事件中检索 displayIsMobile 并将其返回给 page.svelte
  3. page.svelte 文件检索 data.displayIsMobile 值并在其模板部分中使用该值来生成适当的 HTML。
  4. Sveltekit 为浏览器构建脚本来添加交互行为。 Tailwind 引用在页面构建期间已被转换为 CSS 媒体查询。
  5. 浏览器接收此 HTML,使用 Sveltekit 脚本“水合”它,并根据媒体查询的指示将其呈现在客户端设备上。

页面水合后,反应性就纯粹是客户端关心的问题了。 代码模板部分中的 SvelteKit {#if popupIsVisible 将成为一个编译函数,根据 popupIsVisible 切换 DOM 元素。

以上是NgSysV.响应式/自适应设计的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板