搜索
首页web前端js教程使用 Next.js 构建动态博客仪表板

介绍

你好,你好吗?我是 Vítor,带着一个新项目回来了,可以帮助您提高编程技能。自从我上次发布教程以来已经有一段时间了。在过去的几个月里,我花了一些时间休息并专注于其他活动。在此期间,我开发了一个小型网络项目:博客,它成为本教程的重点。

在本指南中,我们将创建能够渲染 Markdown 的博客页面的前端。该应用程序将包括公共和私人路由、用户身份验证以及编写 Markdown 文本、添加照片、显示文章等功能。

随意定制您的应用程序,无论您喜欢什么——我什至鼓励这样做。

您可以在此处访问此应用程序的存储库:

Building a Dynamic Blog Dashboard with Next.js 冈德拉克08 / 博客平台

使用 Next.js/typescript 制作的博客平台。

博客平台

  • 文本教程

成分

  • next-auth - Next.js 的autenticação 图书馆
  • github.com/markdown-it/markdown-it - markdown biblioteca。
  • github.com/sindresorhus/github-markdown-css- Para dar estilo ao nosso markdown 编辑器。
  • github.com/remarkjs/react-markdown - Biblioteca para renderizar markdown em nosso 组件react。
  • github.com/remarkjs/remark-react/tree/4722bdf - React 中 Markdown 转换插件。
  • codemirror.net - 网络编辑器组件。
  • react-icons - 反应图标库。

科莫美国

npm i
npm run start

服务器

você pode encontrar o server dessa aplicação em server


在 GitHub 上查看


本教程还包括本指南中将使用的 Node.js 服务器的编写:

希望您喜欢。

编码愉快!

图书馆

以下是此项目中使用的库的摘要:

  • next-auth - Next.js 的身份验证库
  • github.com/markdown-it/markdown-it - Markdown 库。
  • github.com/sindresorhus/github-markdown-css - 用于设计我们的 Markdown 编辑器。
  • github.com/remarkjs/react-markdown - 用于在 React 组件中渲染 Markdown 的库。
  • github.com/remarkjs/remark-react/tree/4722bdf - 将 Markdown 转换为 React 的插件。
  • codemirror.net - Web 组件编辑器。
  • react-icons - React 的图标库。

创建 React 项目

我们将使用最新版本的 Next.js 框架,在编写本教程时,版本为 13.4。

运行以下命令来创建项目:

npm i
npm run start

安装过程中,选择模板设置。在本教程中,我将使用 TypeScript 作为编程语言,并使用 Tailwind CSS 框架来设计我们的应用程序。

配置

现在让我们安装我们将使用的所有库。

降价
npx create-next-app myblog
反应备注
npm i  markdown-it @types/markdown-it markdown-it-style github-markdown-css react-markdown
代码镜像
remark remark-gfm remark-react
图标
npm @codemirror/commands @codemirror/highlight @codemirror/lang-javascript @codemirror/lang-markdown @codemirror/language @codemirror/language-data @codemirror/state @codemirror/theme-one-dark @codemirror/view

然后通过删除我们不会使用的所有内容来清理安装的初始结构。

建筑学

这是我们应用程序的最终结构。

npm i react-icons @types/react-icons

第一步

配置next.config

在项目根目录的 next.config.js 文件中,让我们配置用于访问文章图像的域地址。对于本教程,或者如果您使用本地服务器,我们将使用 localhost。

确保包含此配置以确保在应用程序中正确加载图像。

src-
  |- app/
  |    |-(pages)/
  |    |      |- (private)/
  |    |      |       |- (home)
  |    |      |       |- editArticle/[id]
  |    |      |       |
  |    |      |       |- newArticle
  |    |      | - (public)/
  |    |              | - article/[id]
  |    |              | - login
  |    |
  |   api/
  |    |- auth/[...nextAuth]/route.ts
  |    |- global.css
  |    |- layout.tsx
  |
  | - components/
  | - context/
  | - interfaces/
  | - lib/
  | - services/
middleware.ts

配置中间件

在应用程序 src/ 的根文件夹中,创建一个 middleware.ts 以验证对私有路由的访问。

const nextConfig = {
   images: {
    domains: ["localhost"],
  },
};

要了解有关中间件以及可以使用它们执行的所有操作的更多信息,请查看文档。

配置认证路由

在 /app 文件夹内,在 api/auth/[...nextauth] 中创建一个名为 Route.ts 的文件。它将包含我们的路由配置,使用 CredentialsProvider 连接到我们的身份验证 API。

CredentialsProvider 允许您处理使用任意凭据的登录,例如用户名和密码、域、双因素身份验证、硬件设备等。

首先,在项目的根目录中,创建一个 .env.local 文件并添加一个令牌,该令牌将用作我们的秘密

npm i
npm run start

接下来,让我们编写我们的身份验证系统,这个 NEXTAUTH_SECRET 将被添加到 src/app/auth/[...nextauth]/routes.ts 文件中的秘密中。

npx create-next-app myblog

认证提供者

让我们创建一个身份验证提供程序,一个上下文,它将在我们的私有路由的页面上共享用户的数据。稍后我们将使用它来包装我们的layout.tsx 文件之一。

在 src/context/auth-provider.tsx 中创建一个包含以下内容的文件:

npm i  markdown-it @types/markdown-it markdown-it-style github-markdown-css react-markdown

全球风格

总的来说,在我们的应用程序中,我们将使用 Tailwind CSS 来创建我们的样式。但是,在某些地方,我们将在页面和组件之间共享自定义 CSS 类。

remark remark-gfm remark-react

布局

现在让我们编写私有和公共的布局。

应用程序/布局.tsx

npm @codemirror/commands @codemirror/highlight @codemirror/lang-javascript @codemirror/lang-markdown @codemirror/language @codemirror/language-data @codemirror/state @codemirror/theme-one-dark @codemirror/view

页面/layout.tsx

npm i react-icons @types/react-icons

API调用

我们的应用程序将多次调用我们的 API,您可以调整此应用程序以使用任何外部 API。在我们的示例中,我们使用本地应用程序。如果你还没有看过后端教程和服务器创建,请查看。

在 src/services/ 中,我们编写以下函数:

  1. authService.ts:负责在服务器上验证用户身份的函数。
src-
  |- app/
  |    |-(pages)/
  |    |      |- (private)/
  |    |      |       |- (home)
  |    |      |       |- editArticle/[id]
  |    |      |       |
  |    |      |       |- newArticle
  |    |      | - (public)/
  |    |              | - article/[id]
  |    |              | - login
  |    |
  |   api/
  |    |- auth/[...nextAuth]/route.ts
  |    |- global.css
  |    |- layout.tsx
  |
  | - components/
  | - context/
  | - interfaces/
  | - lib/
  | - services/
middleware.ts

2.refreshAccessToken.tsx:

const nextConfig = {
   images: {
    domains: ["localhost"],
  },
};
  1. getArticles.tsx:负责获取数据库中保存的所有文章的函数:
export { default } from "next-auth/middleware";
export const config = {
  matcher: ["/", "/newArticle/", "/article/", "/article/:path*"],
};
  1. postArticle.tsx:负责将文章数据提交到我们的服务器的函数。
.env.local
NEXTAUTH_SECRET = SubsTituaPorToken
  1. editArticle.tsx:负责修改数据库中特定文章的函数。
import NextAuth from "next-auth/next";
import type { AuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { authenticate } from "@/services/authService";
import refreshAccessToken from "@/services/refreshAccessToken";

export const authOptions: AuthOptions = {
  providers: [
    CredentialsProvider({
      name: "credentials",
      credentials: {
        email: {
          name: "email",
          label: "email",
          type: "email",
          placeholder: "Email",
        },
        password: {
          name: "password",
          label: "password",
          type: "password",
          placeholder: "Password",
        },
      },
      async authorize(credentials, req) {
        if (typeof credentials !== "undefined") {
          const res = await authenticate({
            email: credentials.email,
            password: credentials.password,
          });
          if (typeof res !== "undefined") {
            return { ...res };
          } else {
            return null;
          }
        } else {
          return null;
        }
      },
    }),
  ],

  session: { strategy: "jwt" },
  secret: process.env.NEXTAUTH_SECRET,
  callbacks: {
    async jwt({ token, user, account }: any) {
      if (user && account) {
        return {
          token: user?.token,
          accessTokenExpires: Date.now() + parseInt(user?.expiresIn, 10),
          refreshToken: user?.tokenRefresh,
        };
      }

      if (Date.now() 



<ol>
<li>
deleteArticle.tsx:负责从数据库中删除特定文章的函数。
</li>
</ol>

<pre class="brush:php;toolbar:false">'use client';
import React from 'react';
import { SessionProvider } from "next-auth/react";
export default function Provider({
    children,
    session
}: {
    children: React.ReactNode,
    session: any
}): React.ReactNode {
    return (
        <sessionprovider session="{session}">
            {children}
        </sessionprovider>
    )
};

成分

接下来,让我们编写整个应用程序中使用的每个组件。

组件/Navbar.tsx

一个带有两个导航链接的简单组件。

/*global.css*/
.container {
  max-width: 1100px;
  width: 100%;
  margin: 0px auto;
}

.image-container {
  position: relative;
  width: 100%;
  height: 5em;
  padding-top: 56.25%; /* Aspect ratio 16:9 (dividindo a altura pela largura) */
}

.image-container img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@keyframes spinner {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.loading-spinner {
  width: 50px;
  height: 50px;
  border: 10px solid #f3f3f3;
  border-top: 10px solid #293d71;
  border-radius: 50%;
  animation: spinner 1.5s linear infinite;
}

组件/Loading.tsx

一个简单的加载组件,在等待 API 调用完成时使用。

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Provider from "@/context/auth-provider";
import { getServerSession } from "next-auth";
import { authOptions } from "./api/auth/[...nextauth]/route";
const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Markdown Text Editor",
  description: "Created by ",
};

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const session = await getServerSession(authOptions);
  return (
    <provider session="{session}">
      
        {children}
      
    </provider>
  );
}

组件/分页.tsx

我们页面上使用的分页组件,在我们的私有路径中显示我们的所有文章。您可以在这里找到有关如何编写此组件的更详细的文章

npm i
npm run start

组件/ArticleCard.tsx

用于显示书面文章的卡片组件。

该组件还包含一个链接,该链接将指向文章显示页面和编辑先前撰写的文章的页面。

npx create-next-app myblog

组件/ArticleList.tsx

负责进行 API 调用并显示响应的组件。

在这里,我们将通过我们编写的函数使用两个 API 调用:

  1. getArticles.ts - 返回将在组件中显示的所有文章。
  2. removeArticle - 从我们的列表和服务器中删除特定的文章。

我们将使用之前编写的 Pagination.tsx 组件来跨页面分割文章数量。

npm i  markdown-it @types/markdown-it markdown-it-style github-markdown-css react-markdown

页数

接下来,我们将按各自的路线划分浏览每个页面。

公共页面

登录

这是我们应用程序的主页。这是一个简单的页面,您可以根据需要对其进行修改。在这个页面中,我们将使用next-auth导航库提供的登录功能。

在文件 src/app/pages/public/login/page.tsx 中。

remark remark-gfm remark-react

文章页

为了创建文章阅读页面,我们将开发一个动态页面。

您访问过的每个博客平台可能都有一个用于阅读文章的专用页面,可通过 URL 访问。其原因是动态页面路由。幸运的是,Next.js 通过其新的 AppRouter 方法使这一切变得简单,使我们的生活变得更加简单。

首先:我们需要通过添加 [id] 文件夹在结构中创建路由。这将产生以下结构:pages/(public)/articles/[id]/pages.tsx.

  • id 对应于我们导航路线的 slug。
  • params 是通过包含导航 slug 的应用程序树传递的属性。
npm @codemirror/commands @codemirror/highlight @codemirror/lang-javascript @codemirror/lang-markdown @codemirror/language @codemirror/language-data @codemirror/state @codemirror/theme-one-dark @codemirror/view

第二:使用MarkdownIt库,使页面能够显示Markdown格式的文本。

npm i react-icons @types/react-icons

最后,

页面准备好后,例如通过在浏览器中访问 localhost:3000/articles/1,您将能够使用提供的 ID 查看文章。

在我们的例子中,当单击其中一个 ArticleCards.tsx 组件时,ID 将通过导航传递,该组件将呈现在我们的私有路由的主页上。

src-
  |- app/
  |    |-(pages)/
  |    |      |- (private)/
  |    |      |       |- (home)
  |    |      |       |- editArticle/[id]
  |    |      |       |
  |    |      |       |- newArticle
  |    |      | - (public)/
  |    |              | - article/[id]
  |    |              | - login
  |    |
  |   api/
  |    |- auth/[...nextAuth]/route.ts
  |    |- global.css
  |    |- layout.tsx
  |
  | - components/
  | - context/
  | - interfaces/
  | - lib/
  | - services/
middleware.ts

私人页面

这是我们的私人页面,只有用户在我们的应用程序中通过身份验证后才能访问。

在我们的app/pages/文件夹中,当在()内声明一个文件时,就意味着该路由对应于/。

在我们的例子中,(Home) 文件夹指的是我们私人路线的主页。这是用户在系统中进行身份验证后看到的第一个页面。此页面将显示我们数据库中的文章列表。

数据将由我们的 ArticlesList.tsx 组件处理。如果您还没有编写此代码,请参阅组件部分。

在应用程序/(页面)/(私人)/(主页)/page.tsx中。

npm i
npm run start

新文章

这是我们应用程序中最重要的页面之一,因为它允许我们注册我们的文章。

此页面将使用户能够:

  1. 以 Markdown 格式写一篇文章。
  2. 为文章分配图像。
  3. 在将 Markdown 文本提交到服务器之前预览它。

页面使用了多个钩子

  1. useCallback - 用于记忆函数。
  2. useState - 允许您向我们的组件添加状态变量。
  3. useSession - 让我们检查用户是否经过身份验证并获取身份验证令牌。

为此,我们将使用两个组件:

  1. TextEditor.tsx:我们之前编写的文本编辑器。
  2. Preview.tsx:用于显示 Markdown 格式文件的组件。

在构建此页面时,我们将使用我们的 API:

  1. POST:使用我们的函数 postArticle,我们将把文章发送到服务器。

我们还将使用 next-auth 库提供的 useSession 钩子来获取用户的身份验证令牌,该令牌将用于在服务器上注册文章。

这将涉及三个不同的 API 调用。
在 app/pages/(private)/newArticle/page.tsx.

“使用客户端”;
从“react”导入 React, { ChangeEvent, useCallback, useState };
从“next-auth/react”导入{useSession};
从“下一步/导航”导入{重定向};
从“@/services/postArticle”导入 postArtical;
从“react-icons/ai”导入{AiOutlineFolderOpen};
从“react-icons/ri”导入 { RiImageEditLine };

从“下一个/图像”导入图像;
从“@/components/textEditor”导入文本编辑器;
从“@/components/PreviewText”导入预览;
从“react-icons/ai”导入{AiOutlineSend};
从“react-icons/bs”导入{BsBodyText};

导出默认函数 NewArticle(params:any) {
  const { 数据:会话 }:任何 = useSession({
    要求:真实,
    onUnauthenticated(){
      重定向(“/登录”);
    },
  });
  const [imageUrl, setImageUrl] = useState<object>({});
  const [previewImage, setPreviewImage] = useState<string>("");
  const [previewText, setPreviewText] = useState<boolean>(false);
  const [标题,setTitle] = useState<string>("");
  const [doc, setDoc] = useState<string>("# Escreva o seu texto... n");
  const handleDocChange = useCallback((newDoc: any) => {
    setDoc(newDoc);
  }, []);

  if (!session?.user) 返回 null;

  const handleArticleSubmit = async (e:any) =>; {
        e.preventDefault();
    const token: string = session.user.token;
    尝试 {
      const res = 等待 postArtical({
        id: session.user.userId.toString(),
        令牌:令牌,
        图片网址: 图片网址,
        标题:“标题”
        文档: 文档,
      });
      console.log('re--->', res);
      重定向('/成功');
    } 捕获(错误){
      console.error('提交文章时出错:', error);
      // 如果需要,处理错误
      抛出错误;
    }
  };

  const handleImageChange = (e: React.ChangeEvent<htmlinputelement>) =>; {
    if (e.target.files && e.target.files.length > 0) {
      const 文件 = e.target.files[0];
      const url = URL.createObjectURL(文件);
      设置预览图像(网址);
      setImageUrl(文件);
    }
  };

  const handleTextPreview = (e: 任意) => {
    e.preventDefault();
    setPreviewText(!previewText);
  };
  返回 (
    <section classname="w-full h-full min-h-screenrelative py-8">
      {预览文本&&(
        <div classname="absolute right-16 top-5 p-5 border-2 border-slate-500 bg-slate-100 rounded-xl w-full max-w-[33em] z-30">;
          ; setPreviewText(!previewText)}
          >>
        </div>;
      )}

      <form classname="relative mx-auto max-w-[700px] h-full min-h-[90%] w-full p-2 border-2 border-slate-200 rounded-md bg-slate-50 drop-shadow-xl flex flex-col 间隙-2“>
        {“”}
        <div className=" flex justify- between items-center>
          
            <bsbodytext></bsbodytext>>
            预览
          按钮>{" "}
          
            恩维亚尔·特克斯托
            <aioutlinesend classname="w-5 h-5 group-hover:text-red-500"></aioutlinesend>
          按钮>
        ;
        <div classname="header-wrapper flex flex-col gap-2">
          <div classname="image-box">
            {previewImage.length === 0 && (
              <div classname="select-image">
                
                  <aioutlinefolderopen classname="w-7 h-7"></aioutlinefolderopen>
                  拖放图像
                标签>
                



<h4>
  
  
  编辑文章
</h4>

<p>与<em>新文章</em>(newArticle)类似的页面,但有一些差异。</p>

<p>首先,我们定义一条动态路线,在其中接收 id 作为导航参数。这与文章阅读页面上所做的非常相似。 <br>
app/(pages)/(private)/editArticle/[id]/page.tsx<br>
</p>
<pre class="brush:php;toolbar:false">“使用客户端”;
从“react”导入 React, { useState, useEffect, useCallback, useRef, ChangeEvent };
从“next-auth/react”导入{useSession};
从“下一步/导航”导入{重定向};
从“下一个/图像”导入图像;

从“@/interfaces/article.interface”导入{IArticle};
从“react-icons/ai”导入{AiOutlineEdit};
从“react-icons/bs”导入{BsBodyText};
从“react-icons/ai”导入{AiOutlineFolderOpen};
从“react-icons/ri”导入 { RiImageEditLine };

从“@/components/PreviewText”导入预览;
从“@/components/textEditor”导入文本编辑器;
从'@/components/Loading'导入加载;
从“@/services/editArticle”导入 editArtical;

导出默认函数 EditArticle({ params }: { params: any }) {
 const { 数据:会话 }:任何 = useSession({
    要求:真实,
    onUnauthenticated(){
      重定向(“/登录”);
    },
  });
  const id: 数字 = params.id;
  const [文章,setArticle] = useState<iarticle>(空);
  const [imageUrl, setImageUrl] = useState<object>({});
  const [previewImage, setPreviewImage] = useState<string>("");
  const [previewText, setPreviewText] = useState<boolean>(false)
  const [标题,setTitle] = useState<string>("");
  const [doc, setDoc] = useState<string>('');
  const handleDocChange = useCallback((newDoc: any) => {
    setDoc(newDoc);
  }, []);
  const inputRef= useRef<htmlinputelement>(null);

  const fetchArticle = async (id: number) =>; {
    尝试 {
      常量响应 = 等待获取(
        `http://localhost:8080/articles/getById/${id}`,
      );
      const jsonData = 等待响应.json();
      setArticle(jsonData);
    } 捕获(错误){
      console.log("出了点问题:", err);
    }
  };
  useEffect(() => {
    if (文章 !== null || 文章 !== 未定义) {
      获取文章(id);
    }
  }, [ID]);

  useEffect(()=>{
    if(文章!= null && 文章.内容){
        setDoc(文章.内容)
    }

    if(文章!=null && 文章.image){
      setPreviewImage(`http://localhost:8080/` 文章.image)
    }
  },[文章])

  const handleArticleSubmit = async (e:any) =>; {
     e.preventDefault();
    const token: string = session.user.token;
    尝试{
      const res = 等待 editArtical({
      身份证号: 身份证号,
      令牌:令牌,
      图片网址:图片网址,
      标题: 标题,
      文档: 文档,
      });
        console.log('re--->',res)
        返回资源;
    } 捕获(错误){
    console.log(“错误:”,错误)
    }
  };
  const handleImageClick = ()=>{
      console.log('hiii')
    if(inputRef.current){
      inputRef.current.click();
    }
  }const handleImageChange = (e: React.ChangeEvent<htmlinputelement>) =>; {
    if (e.target.files && e.target.files.length > 0) {
      const 文件 = e.target.files[0];
      const url = URL.createObjectURL(文件);
      设置预览图像(网址);
      setImageUrl(文件);
    }

  };
   const handleTextPreview = (e: 任意) => {
    e.preventDefault();
    setPreviewText(!previewText);
    console.log('预览版你好!')
  };

  if(!article) return >
  if(文章?.内容)
  返回 (
    <section classname="w-full h-full min-h-screenrelative py-8">
      {预览文本&&(
        <div classname="absolute right-16 top-5 p-5 border-2 border-slate-500 bg-slate-100 rounded-xl w-full max-w-[33em] z-30">;
          ; setPreviewText(!previewText)}
          >>
        </div>
      )}

      <div classname="relative mx-auto max-w-[700px] h-full min-h-[90%] w-full p-2 border-2 border-slate-200 rounded-md bg-white drop- Shadow-md flex flex-col 间隙-2">
        <form classname="relative mx-auto max-w-[700px] h-full min-h-[90%] w-full p-2 border-2 border-slate-200 rounded-md bg-slate-50 drop-shadow-md flex flex-col 间隙-2 ">
          {“”}
          <div classname="flex justify- Between items-center">;
            
              <bsbodytext></bsbodytext>>
              预览
            按钮>{" "}
            
                编辑阿蒂戈 
              <aioutlineedit classname="w-5 h-5 group-hover:text-red-500"></aioutlineedit>>
            按钮>
          </div>;
          <div classname="header-wrapper flex flex-col gap-2">;
            <div classname="image-box">;
              {previewImage.length === 0 && (
                <div classname="select-image">;
                  
                    <aioutlinefolderopen classname="w-7 h-7"></aioutlinefolderopen>>
                    拖放图像
                  标签>
                  



<h2>
  
  
  结论
</h2>

<p>首先,我要感谢您花时间阅读本教程,并且我还要祝贺您完成它。我希望它对您有帮助,并且分步说明很容易遵循。</p>

<p>其次,我想强调一下关于我们刚刚构建的内容的几点。这是博客系统的基础,还有很多东西需要添加,比如显示所有文章的公共页面、用户注册页面,甚至是自定义的 404 错误页面。如果在教程期间您对这些页面感到好奇并错过了它们,请知道这是故意的。本教程为您提供了足够的经验来自行创建这些新页面、添加许多其他页面以及实现新功能。</p>

<p>非常感谢,下次再见。哦/</p>


          </div>

            
        </div>
</div>
</form>
</div></section></htmlinputelement></htmlinputelement></string></string></boolean></string></object></iarticle>

以上是使用 Next.js 构建动态博客仪表板的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在JavaScript中替换字符串字符在JavaScript中替换字符串字符Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

自定义Google搜索API设置教程自定义Google搜索API设置教程Mar 04, 2025 am 01:06 AM

本教程向您展示了如何将自定义的Google搜索API集成到您的博客或网站中,提供了比标准WordPress主题搜索功能更精致的搜索体验。 令人惊讶的是简单!您将能够将搜索限制为Y

构建您自己的Ajax Web应用程序构建您自己的Ajax Web应用程序Mar 09, 2025 am 12:11 AM

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

示例颜色json文件示例颜色json文件Mar 03, 2025 am 12:35 AM

本文系列在2017年中期进行了最新信息和新示例。 在此JSON示例中,我们将研究如何使用JSON格式将简单值存储在文件中。 使用键值对符号,我们可以存储任何类型的

8令人惊叹的jQuery页面布局插件8令人惊叹的jQuery页面布局插件Mar 06, 2025 am 12:48 AM

利用轻松的网页布局:8个基本插件 jQuery大大简化了网页布局。 本文重点介绍了简化该过程的八个功能强大的JQuery插件,对于手动网站创建特别有用

什么是这个&#x27;在JavaScript?什么是这个&#x27;在JavaScript?Mar 04, 2025 am 01:15 AM

核心要点 JavaScript 中的 this 通常指代“拥有”该方法的对象,但具体取决于函数的调用方式。 没有当前对象时,this 指代全局对象。在 Web 浏览器中,它由 window 表示。 调用函数时,this 保持全局对象;但调用对象构造函数或其任何方法时,this 指代对象的实例。 可以使用 call()、apply() 和 bind() 等方法更改 this 的上下文。这些方法使用给定的 this 值和参数调用函数。 JavaScript 是一门优秀的编程语言。几年前,这句话可

通过来源查看器提高您的jQuery知识通过来源查看器提高您的jQuery知识Mar 05, 2025 am 12:54 AM

jQuery是一个很棒的JavaScript框架。但是,与任何图书馆一样,有时有必要在引擎盖下发现发生了什么。也许是因为您正在追踪一个错误,或者只是对jQuery如何实现特定UI感到好奇

10张移动秘籍用于移动开发10张移动秘籍用于移动开发Mar 05, 2025 am 12:43 AM

该帖子编写了有用的作弊表,参考指南,快速食谱以及用于Android,BlackBerry和iPhone应用程序开发的代码片段。 没有开发人员应该没有他们! 触摸手势参考指南(PDF) Desig的宝贵资源

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
1 个月前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版