表白墙 -- 前后端代码详解

2023-10-31

一、前端

先提供一个之前写过的表白墙的前端代码:

<!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>表白墙</title>
</head>
<body>
    <style>
        .container {
            width: 400px;
            /* margin 外边距. 第一个数字上下外边距, 第二个数字表示水平外边距. 如果水平设置成 auto 表示元素就水平居中~~ */
            margin: 0 auto;
        }

        h1 {
            text-align: center;
        }

        p {
            text-align: center;
            color: #666;
        }

        .row {
            height: 40px;
            display: flex;
            /* 水平居中 */
            justify-content: center;
            /* 垂直居中 */
            align-items: center;
        }

        .row span {
            width: 100px;
        }

        .row input {
            width: 200px;
            height: 30px;
        }

        .row button {
            width: 306px;
            height: 40px;
            color: white;
            background: orange;
            border: none;
        }

        .row button:active {
            background-color: #666;
        }
    </style>

    <div class="container">
        <h1>表白墙</h1>
        <p>输入后点击提交, 就会把信息显示在表格中</p>
        <div class="row">
            <span>谁: </span><input type="text">
        </div>
        <div class="row">
            <span>对谁: </span><input type="text">
        </div>
        <div class="row">
            <span>说: </span><input type="text">
        </div>
        <div class="row">
            <button>提交</button>
        </div>
    </div>

    <script>
        let container = document.querySelector('.container');
        let button = document.querySelector('button');
        button.onclick = function() {
            // 1. 获取到输入框的内容
            let inputs = document.querySelectorAll('input');
            let from = inputs[0].value;
            let to = inputs[1].value;
            let message = inputs[2].value;
            if (from == '' || to == '' || message == '') {
                alert('当前输入框内容为空!');
                return;
            }
            console.log(from + ", " + to + ", " + message);
            // 2. 能够构造出新的 div, 用来保存用户提交的内容
            let rowDiv = document.createElement('div');
            rowDiv.className = 'row';
            rowDiv.innerHTML = from + " 对 " + to + " 说: " + message;
            container.appendChild(rowDiv);
            // 3. 提交完之后, 清空输入框的内容
            for (let i = 0; i < inputs.length; i++) {
                inputs[i].value = '';
            }
        }
    </script>
</body>
</html>

形如:
在这里插入图片描述

二、后端实现

2.1 需求

当我们输入一些内容:
在这里插入图片描述
但是一旦刷新后,所有数据都没了!
因为当前的数据只是在内存中存储的!关了再开,内存中原来的数据就没了 ~~
这样显然不能达到我们的预期。解决方案:
需要让用户留言的数据能够在服务器这边保存,就可以保证即使页面关闭,数据也不会丢失!!!

  • 点击提交,希望数据能够在服务器这里保存,势必要把数据发给服务器 (存档)
    在这里插入图片描述

  • 当关闭页面再打开的时候,就需要从服务器获取到之前保存过的数据,在页面上显示出来 (读档)
    在这里插入图片描述

2.2 创建项目及初始化

参考博客:https://blog.csdn.net/yyhgo_/article/details/128468738?spm=1001.2014.3001.5501
创建一个新的 Maven 项目!(引入 Servlet 依赖Jackson 依赖)

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>MessageWall</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.4</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

    </dependencies>
</project>

把之前实现的表白墙前端页面文件拷贝到 webapp 目录中!

2.3 实现提交数据 (存档)

在这里插入图片描述

2.3.1 实现 doPost

首先创建一个 Message 类:

public class Message {
    private String from;
    private String to;
    private String message;

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

MessageServlet 类:

import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    // 这个对象在多个方法中都需要使用
    private ObjectMapper objectMapper = new ObjectMapper();

    private List<Message> messageList = new ArrayList<>();

    // 负责让页面获取到数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    // 提交数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取到 body 中的数据并解析
        Message message = objectMapper.readValue(req.getInputStream(), Message.class);
        // 把这个 message 保存一下. 简单的办法就是保存在内存中.
        messageList.add(message);
        resp.setStatus(200);
        System.out.println("提交数据成功: from=" + message.getFrom()
                + ", to=" + message.getTo() + ", message=" + message.getMessage());
    }

}

2.3.2 构造请求 (修改 html 文件)

补充 第4步
点击发送按钮,给服务器发个 post 请求 ~~

<!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>表白墙</title>
</head>
<body>
    <style>
        .container {
            width: 400px;
            /* margin 外边距. 第一个数字上下外边距, 第二个数字表示水平外边距. 如果水平设置成 auto 表示元素就水平居中~~ */
            margin: 0 auto;
        }

        h1 {
            text-align: center;
        }

        p {
            text-align: center;
            color: #666;
        }

        .row {
            height: 40px;
            display: flex;
            /* 水平居中 */
            justify-content: center;
            /* 垂直居中 */
            align-items: center;
        }

        .row span {
            width: 100px;
        }

        .row input {
            width: 200px;
            height: 30px;
        }

        .row button {
            width: 306px;
            height: 40px;
            color: white;
            background: orange;
            border: none;
        }

        .row button:active {
            background-color: #666;
        }
    </style>

    <div class="container">
        <h1>表白墙</h1>
        <p>输入后点击提交, 就会把信息显示在表格中</p>
        <div class="row">
            <span>谁: </span><input type="text">
        </div>
        <div class="row">
            <span>对谁: </span><input type="text">
        </div>
        <div class="row">
            <span>说: </span><input type="text">
        </div>
        <div class="row">
            <button>提交</button>
        </div>

        <!-- 需要构造出一个形如 -->
        <!-- <div class="row">
            黑猫 对 白猫 说: 喵
        </div> -->
    </div>

    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

    <script>
        let container = document.querySelector('.container');
        let button = document.querySelector('button');
        button.onclick = function() {
            // 1. 获取到输入框的内容
            let inputs = document.querySelectorAll('input');
            let from = inputs[0].value;
            let to = inputs[1].value;
            let message = inputs[2].value;
            if (from == '' || to == '' || message == '') {
                alert('当前输入框内容为空!');
                return;
            }
            console.log(from + ", " + to + ", " + message);
            // 2. 能够构造出新的 div, 用来保存用户提交的内容
            let rowDiv = document.createElement('div');
            rowDiv.className = 'row';
            rowDiv.innerHTML = from + " 对 " + to + " 说: " + message;
            container.appendChild(rowDiv);
            // 3. 提交完之后, 清空输入框的内容
            for (let i = 0; i < inputs.length; i++) {
                inputs[i].value = '';
            }

            // 4. 点击发送按钮, 给服务器发个 post 请求. 
            let data = {
                from: from,
                to: to,
                message: message
            };
            $.ajax({
                type: 'post',
                url: 'message',
                // url: '/java105/message',
                // 这里放的是 body 的内容
                data: JSON.stringify(data),
                contentType: "application/json; charset=utf8",
                success: function(body) {
                    console.log("提交数据成功");
                }
            });
        }

    </script>
</body>
</html>

细节:
在这里插入图片描述
在这里插入图片描述

2.3.3 验证

1)启动 tomcat 服务器
在这里插入图片描述

2)通过 表白墙.html 发送请求

访问 http://127.0.0.1:8080/MessageWall/表白墙.html:

在这里插入图片描述

过程中使用 Fiddler 抓包:
请求:
在这里插入图片描述
服务器解析结果:
在这里插入图片描述
响应:
在这里插入图片描述

2.4 实现获取数据 (读档)

在这里插入图片描述

2.4.1 实现 doGet

MessageServlet 类:

import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    // 这个对象在多个方法中都需要使用
    private ObjectMapper objectMapper = new ObjectMapper();

    private List<Message> messageList = new ArrayList<>();

    // 负责让页面获取到数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // body 就是响应的 body 内容 (json 数组).
        // jquery 非常智能的帮我们把 json 数组给解析成了 js 对象数组
        // 但是有个前提条件, 就是响应的 Content-Type 得是 application/json
        resp.setContentType("application/json; charset=utf8");
        // 把 messageList 转成 json 字符串,并且返回给页面就行了.
        resp.getWriter().write(objectMapper.writeValueAsString(messageList));
    }

    // 提交数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取到 body 中的数据并解析
        Message message = objectMapper.readValue(req.getInputStream(), Message.class);
        // 把这个 message 保存一下. 简单的办法就是保存在内存中.
        messageList.add(message);
        resp.setStatus(200);
        System.out.println("提交数据成功: from=" + message.getFrom()
                + ", to=" + message.getTo() + ", message=" + message.getMessage());
    }

}

2.4.2 构造请求 (修改 html 文件)

什么时候来发这个请求呢?
页面加载的时候,我们就希望进行读档操作!
==================================================================================
在 html 文件中,哪里是页面加载的时候呢?
直接写在 script 标签里的代码,都是在页面加载的时候执行的!

<!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>表白墙</title>
</head>
<body>
    <style>
        .container {
            width: 400px;
            /* margin 外边距. 第一个数字上下外边距, 第二个数字表示水平外边距. 如果水平设置成 auto 表示元素就水平居中~~ */
            margin: 0 auto;
        }

        h1 {
            text-align: center;
        }

        p {
            text-align: center;
            color: #666;
        }

        .row {
            height: 40px;
            display: flex;
            /* 水平居中 */
            justify-content: center;
            /* 垂直居中 */
            align-items: center;
        }

        .row span {
            width: 100px;
        }

        .row input {
            width: 200px;
            height: 30px;
        }

        .row button {
            width: 306px;
            height: 40px;
            color: white;
            background: orange;
            border: none;
        }

        .row button:active {
            background-color: #666;
        }
    </style>

    <div class="container">
        <h1>表白墙</h1>
        <p>输入后点击提交, 就会把信息显示在表格中</p>
        <div class="row">
            <span>谁: </span><input type="text">
        </div>
        <div class="row">
            <span>对谁: </span><input type="text">
        </div>
        <div class="row">
            <span>说: </span><input type="text">
        </div>
        <div class="row">
            <button>提交</button>
        </div>

        <!-- 需要构造出一个形如 -->
        <!-- <div class="row">
            黑猫 对 白猫 说: 喵
        </div> -->
    </div>

    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

    <script>
        let container = document.querySelector('.container');
        let button = document.querySelector('button');
        button.onclick = function() {
            // 1. 获取到输入框的内容
            let inputs = document.querySelectorAll('input');
            let from = inputs[0].value;
            let to = inputs[1].value;
            let message = inputs[2].value;
            if (from == '' || to == '' || message == '') {
                alert('当前输入框内容为空!');
                return;
            }
            console.log(from + ", " + to + ", " + message);
            // 2. 能够构造出新的 div, 用来保存用户提交的内容
            let rowDiv = document.createElement('div');
            rowDiv.className = 'row';
            rowDiv.innerHTML = from + " 对 " + to + " 说: " + message;
            container.appendChild(rowDiv);
            // 3. 提交完之后, 清空输入框的内容
            for (let i = 0; i < inputs.length; i++) {
                inputs[i].value = '';
            }

            // 4. 点击发送按钮, 给服务器发个 post 请求. 
            let data = {
                from: from,
                to: to,
                message: message
            };
            $.ajax({
                type: 'post',
                url: 'message',
                // url: '/java105/message',
                // 这里放的是 body 的内容
                data: JSON.stringify(data),
                contentType: "application/json; charset=utf8",
                success: function(body) {
                    console.log("提交数据成功");
                }
            });
        }

        // 直接写在 script 标签里的代码, 都是在页面加载的时候执行的. 
        // 来获取服务器的数据
        function getMessages() {
            $.ajax({
                type: 'get' ,
                url: 'message',
                success: function(body) {
                    // body 就是响应的 body 内容 (json 数组). 
                    // jquery 非常智能的帮我们把 json 数组给解析成了 js 对象数组
                    // 但是有个前提条件, 就是响应的 Content-Type 得是 application/json
                    let container = document.querySelector('.container');
                    // 观察 html, .row 都是在 .container 中存放的,所以获取到.container,把新的 .row 都加进去!  
                    for (let i = 0; i < body.length; i++) {
                        let message = body[i];
                        // 根据这个元素构造一个 div.row, 来容纳数据
                        // <div class="row">
                        //     黑猫 对 白猫 说: 喵
                        // </div>
                        let row = document.createElement('div');
                        row.className = 'row';
                        row.innerHTML = message.from + " 对 " + message.to + " 说: " + message.message;
                        container.appendChild(row);
                    }
                }
            });
        }

        getMessages();
    </script>
</body>
</html>

function 中的参数 body 就是响应的 body 内容 (json 数组)!
jquery 非常智能地帮我们把 json 数组给解析成了 js 对象数组!但是有个前提条件,就是响应的 Content-Type 得是 application/json 格式!
在这里插入图片描述
如果 jquery 没做这个事情,就需要使用 JSON.parse 来完成 ~~

2.4.3 验证

1)重新启动 tomcat 服务器
在这里插入图片描述

2)访问 http://127.0.0.1:8080/MessageWall/表白墙.html

此时提交数据后,无论怎样刷新,数据仍然保留!!!成功 ~

在这里插入图片描述

服务器重启,原有的数据就没了 ~~

页面刷新过程中使用 Fiddler 抓包:
请求:
在这里插入图片描述
响应:
在这里插入图片描述

三、JDBC 版本 (MySQL)

我们这个程序目前最大的问题就是:数据在内存中,服务器一旦重启就没了。我们需要让数据在数据库中持久化保存!JDBC!!!

3.1 引入 JDBC 驱动包

中央仓库中搜索 mysql,选择:
在这里插入图片描述

这里选择 5.1.49:
在这里插入图片描述

将代码拷贝到 pom.xml 中:
在这里插入图片描述
在这里插入图片描述

3.2 设计数据库表结构

设计有几张表,表里有什么 ~~

1.message 表;
2.三个列:from、to、message

在这里插入图片描述

注意: from 等关键字,需要加上反引号 `` !!!

在这里插入图片描述

3.3 修改代码

Java的JDBC编程 博客链接:https://blog.csdn.net/yyhgo_/article/details/128061324?spm=1001.2014.3001.5501

通过数据库来 存 / 读 数据,就不再需要 ArrayList 了 ~~
主要是两个方法:

  • private void save(Message message) :把数据保存到数据库中
  • private List<Message> load() :从数据库查询数据

完整代码:

public class Message {
    private String from;
    private String to;
    private String message;

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;

// 使用这个类来封装 DataSource 的单例
public class DBUtil {
    private static volatile DataSource dataSource = null;

    private DBUtil() {}

    public static DataSource getDataSource() {
        if (dataSource == null) {
            synchronized (DBUtil.class) {
                if (dataSource == null) {
                    dataSource = new MysqlDataSource();
                    ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java105?characterEncoding=utf8&useSSL=false");
                    ((MysqlDataSource)dataSource).setUser("root");
                    // 数据库密码.
                    ((MysqlDataSource)dataSource).setPassword("632yyh..");
                }
            }
        }
        return dataSource;
    }

}
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/message")
public class MessageServlet extends HttpServlet {
    // 这个对象在多个方法中都需要使用
    private ObjectMapper objectMapper = new ObjectMapper();

    // 负责让页面获取到数据
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 显式声明当前的响应数据格式 不要让客户端去猜!!!
        resp.setContentType("application/json; charset=utf8");
        // 把 messageList 转成 json 字符串, 并且返回给页面就行了.
        List<Message> messageList = null;
        try {
            messageList = load();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        resp.getWriter().write(objectMapper.writeValueAsString(messageList));
    }

    // 提交数据
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取到 body 中的数据并解析
        Message message = objectMapper.readValue(req.getInputStream(), Message.class);
        // 把这个 message 保存一下. 简单的办法就是保存在内存中.
        // messageList.add(message);
        try {
            save(message);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        resp.setStatus(200);

        System.out.println("提交数据成功: from=" + message.getFrom()
                + ", to=" + message.getTo() + ", message=" + message.getMessage());
    }

    private void save(Message message) throws SQLException {
        // 把数据保存到数据库中

        // 1. 先有一个数据源
        DataSource dataSource = DBUtil.getDataSource();

        // 2. 建立连接
        Connection connection = dataSource.getConnection();

        // 3. 构造 SQL
        String sql = "insert into message values(?, ?, ?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setString(1, message.getFrom());
        statement.setString(2, message.getTo());
        statement.setString(3, message.getMessage());

        // 4. 执行 SQL
        int ret = statement.executeUpdate();
        System.out.println("ret = " + ret);

        // 5. 关闭连接
        statement.close();
        connection.close();
    }

    private List<Message> load() throws SQLException {
        // 从数据库查询数据

        // 1. 先有一个数据源
        DataSource dataSource = DBUtil.getDataSource();

        // 2. 建立连接
        Connection connection = dataSource.getConnection();

        // 3. 构造 SQL
        String sql = "select * from message";
        PreparedStatement statement = connection.prepareStatement(sql);

        // 4. 执行 SQL
        ResultSet resultSet = statement.executeQuery();

        // 5. 遍历结果集合
        List<Message> messageList = new ArrayList<>();
        while (resultSet.next()) {
            Message message = new Message();
            message.setFrom(resultSet.getString("from"));
            message.setTo(resultSet.getString("to"));
            message.setMessage(resultSet.getString("message"));
            messageList.add(message);
        }

        // 6. 关闭连接
        statement.close();
        connection.close();
        return messageList;
    }

}

细节:
数据源不需要创建多份,因此可以使用单例模式:单独构造一个 类DBUtil !

Servlet 代码中是否涉及到 多线程/线程安全 的问题呢?
Servlet 写的是一个服务器。同一时刻,可能要处理多个客户端的请求!
一旦同时有多个客户端都发来请求,服务器势必就需要同时处理多个请求。Tomcat 内部正是使用了多线程的方式来处理的 ~~

3.4 验证

1)重新启动 tomcat 服务器
在这里插入图片描述

2)访问 http://127.0.0.1:8080/MessageWall/表白墙.html

此时提交数据后,无论怎样刷新,还是重新启动服务器,数据仍然保留!!!成功 ~

在这里插入图片描述

此时查看数据库中 message 表的数据:
在这里插入图片描述


完!提前祝大家 2023 新年快乐!~~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

表白墙 -- 前后端代码详解 的相关文章

  • 主干关系事件未触发?

    class TheModel extends Backbone RelationalModel relations type Backbone HasMany key subModels relatedModel SubModel coll
  • Typescript:按值检查对象是否存在于数组中

    我有这个数据 roles roleId 69801 role ADMIN roleId 69806 role SUPER ADMIN roleId 69805 role RB roleId 69804 role PILOTE roleId
  • 如何理解 Angular JS 中的控制台错误消息?有什么工具吗?

    我是 Angular JS 的新手 我的第一个问题是如何理解 Angular JS 中控制台的错误消息 我编写了这段用于匹配密码的代码片段 它在控制台上抛出错误 但它工作正常 它是有线的 我无法从这些控制台消息中理解任何内容 谁能指出我为什
  • 我可以从 HTTP 请求中找到无线接入点的 BSSID(MAC 地址)吗?

    假设有人在咖啡店里无线连接到互联网 并向 johnsveryownserver com 发送 HTTP 请求 服务器端 有什么方法可以确定我的MAC地址吗 无线接入点他们连接到什么 请注意 我对他们机器的 MAC 地址不感兴趣 如果我无法使
  • jQuery 中的 Javascript .files[0] 属性

    jQuery 中是否有与此语句等效的语句 var value document getElementById id files 0 使用附加 files 0 的标准 jQuery 选择器似乎不起作用 并且我找不到与 files 等效的 jQ
  • 如何使用键盘和鼠标控制相机 - Three.js

    我在 WEB GL 中有一个带有 Three js 的 3D 环境 并且我曾经使用 Orbitcontrols js http codepen io nireno pen cAoGI http codepen io nireno pen c
  • 限制文本区域中每行的字符数

    我整个周末都在寻找解决这个难题的方法 但尚未找到一个可以正常工作的解决方案 我想要实现的是限制文本区域中每行的字符数 不是相同地限制它们 而是我选择的每行不同的字符数 例如 我只想在我的文本区域中包含 4 行 第 1 2 和 3 行将限制为
  • ant-d upload中如何为removeFile添加PopConfirm一个图片文件

    我正在使用 Ant d Upload 通过本地系统上传文件 然后单击文件预览图像上的删除图标 图像文件将被删除 我想添加一个弹出确认 所以我尝试在 onRemovefunction 中添加确认作为承诺但它不起作用 它在浏览器中显示警报 on
  • 将音频与视频流合并 Node.js

    我正在创建 YouTube 视频下载器并且正在使用ytdl core库 它无法下载带有音频的高质量视频 因为 youtube 将其放在另一个文件中 但我需要将其全部下载到一个文件中 我已经这样做了 app get download asyn
  • 如何在 d3 js 中突出显示从根到选定节点的路径?

    我使用 d3 js 创建了一棵树 现在我创建了一个下拉菜单 其中包含树中所有节点的列表 现在 从下拉菜单中选择一个节点时 我想突出显示从根到该特定节点的路径 这个怎么做 首先创建一个 flatten 函数 它将分层数据变成一个 n 数组 f
  • 创建 Cookie 时需要帮助

    我有一个名为yes和另一个名叫no
  • Ember.JS - 如何在同一页面中使用多个模型、控制器和视图?

    我主要了解 Ember JS 的基础知识 大多数示例实际上只处理单个控制器和模型以在页面上显示某些内容 我真的很想用 Ember 构建一个完整的 Web 应用程序 所以有人能告诉我如何组织和连接多个控制器 模型和视图到一个页面中吗 例如 如
  • Android httpclient文件上传数据损坏和超时问题

    我在 Android 中上传图像时遇到问题 我正在使用 apache httpmime 4 1 lib 代码是这样的 MultipartEntity reqEntity new MultipartEntity HttpMultipartMo
  • 如何改变HTML5视频的播放速度?

    如何更改 HTML5 中的视频播放速度 我查过视频标签的属性 https www w3schools com html html5 video asp在 w3school 但无法做到这一点 根据这个网站 http www chipwreck
  • 如何从顺序键盘导航中删除 Vuetify 附加图标

    在带有 Vuetify 的 Vue js 应用程序中 我有一组用v text field并且其中有一个append icon为了切换文本可见性 如下所示
  • 如何清除WebGL中的矩形区域?

    WebGL 有一个clear清除整个表面的方法 清除表面的特定矩形的最佳方法是什么 例如 我想将一个从 50 50 开始的 100x100 像素框设置为全零 ARGB 0 0 0 0 我现在能想到的就是用一个写入零的片段着色器绘制一个四边形
  • 如何滚动到div内的元素?

    我有一个滚动的div我想在点击它时发生一个事件 它会强制执行此操作div滚动以查看内部元素 我写的JavasCript是这样的 document getElementById chr scrollIntoView true 但这会在滚动时滚
  • 如何在网页上实现文件上传进度条?

    当用户将文件上传到我的网络应用程序时 我想显示比动画 gif 更有意义的内容 我还有哪些可能性 编辑 我正在使用 Net 但我不介意是否有人向我展示与平台无关的版本 如果您对这一切在客户端通常如何工作感兴趣 就是这样 所有解决方案都通过 J
  • React Native - 跨屏幕传递数据

    我遇到了一些麻烦react native应用程序 我不知道如何跨屏幕传递数据 我意识到还有其他类似的问题在 SO 上得到了回答 但是这些解决方案对我来说不起作用 我正在使用StackNavigator 这是我的设置App js file e
  • 在 javascript 中使用 xPath 解析具有默认命名空间的 XML

    我需要创建一个 XML xPath 解析器 所有解析都必须在客户端进行 使用 JavaScript 我创建了一个 javascript 来执行此操作 在默认名称空间发挥作用之前 一切看起来都正常 我根本无法查询具有默认命名空间的 XML 我

随机推荐

  • 各类打印机驱动官网下载安装

    前言概述 找驱动很简单 但是网上有时候找起来有点费劲呢 不安全 目前市面上打印机驱动搜索软件好用的基本都要付费 或者不全 比如下图这个就是付费的 常用的打印机品牌 惠普 HP 佳能 Canon 爱普生 Epson 京瓷 Kyocera 三星
  • 二流计算机学校,学校可以是二流的,但你不是

    我每天都会看大家在微博里给我的留言 时常看到深夜 私信的 每一条都看 问的最多的一种问题 是这么开头的 我的学校不好 或者 我是一个来自二 三 本学校的学生 我该怎么办 我不知道怎么回答 因为我不觉得来自一个二流的学校就应该过着二流的生活
  • C语言实现队列(链表实现)

    队列 Queue 也是运算受限的线性表 是一种先进先出 First In First Out 简称 FIFO 的线性表 只允许在表的一端进行插入 而在另一端进行删除 队首 front 允许进行删除的一端称为队首 队尾 rear 允许进行插入
  • 浅析Linux内核中的链表

    1 内核中的链表 linux内核链表与众不同 他不是把将数据结构塞入链表 而是将链表节点塞入数据 在2 1内核中引入了官方链表 从此内核中所有的链表使用都采用此链表 千万不要在重复造车轮子了 链表实现定义在
  • 第五届蓝桥杯Java A组决赛试题

    1 标题 海盗分金币 有5个海盗 相约进行一次帆船比赛 比赛中天气发生突变 他们被冲散了 恰巧 他们都先后经过途中的一个无名的荒岛 并且每个人都信心满满 觉得自己是第一个经过该岛的人 第一个人在沙滩上发现了一堆金币 他把金币分成5等份 发现
  • STM32CubeMX驱动MPU6050模块

    文章目录 1 MPU6050模块简介 2 MPU6050重要寄存器介绍 2 1 数字低通滤波器配置寄存器CONFIG 2 2 采样率分频寄存器SMPRT DIV 2 3 加速度计配置寄存器ACCEL CONFIG 2 4 角速度计配置寄存器
  • 区别:OrderedDict vs dict

    OrderedDict 和 dict 是两种字典类型 都用于存储键值对 key value pairs dict 是Python的内置字典类型 它是无序的 即它不会按照元素插入的顺序来保存键值对 当你通过键来访问 dict 中的值时 Pyt
  • sqoop query时单双引号选用以及$CONDITION使用的探究

    这段时间碰见了一个奇怪的sqoop导入问题 我的业务目标是想将postgresql库里的某张表内的数据导入到hive里 而且在导入的时候需要做一步查询 但在导入的时候 围绕着 CONDITION 这个参数 会有不同的运行结果 有的报错 有的
  • MySQL基础架构与日志详解

    一 MySQL基础架构 MySQL可以分为Server层和存储引擎层两部分 Server层包括连接器 查询缓存 分析器 优化器 执行器等 涵盖MySQL的大多数核心服务功能 以及所有的内置函数 如日期 时间 数学和加密函数等 所有跨存储引擎
  • 软件需求之DFD图

    DFD图是一种以数据和数据的封闭性为基础 从问题空间到某种表示的映射方法 是一种结构化分析方法 DFD图在软件的需求分析中发挥着不可替代的作用 DFD图在软考中是必考的内容 在软件工程中也是一个非常中要的图 下面是我结合网上的资料和自己的所
  • Linux系统里压缩PDF文件大小

    sudo apt get install ghostscript gs sDEVICE pdfwrite dCompatibilityLevel 1 4 dPDFSETTINGS screen dNOPAUSE dQUIET dBATCH
  • JavaFX 控件 ImageView

    ImageView 支持格式 BMP GIF JPEG PNG 加载图片 如果设置了 requestedXXX 尺寸 ImageView中 设置 FitXXX 尺寸是基于requestedXXX 尺寸缩放 Image image new I
  • Linux & Docker常用命令

    目录 一 Docker服务相关命令 二 镜像相关命令 查看镜像 查看本地所有的镜像 搜索镜像 从网络中查找需要的镜像 拉取镜像 删除镜像 三 容器相关命令 查看容器 创建容器 进入容器 启动容器 停止容器 重启应用 删除容器 查看容器信息
  • OpenCV教程——加载、修改、保存图像

    1 颜色空间 颜色空间 也称彩色模型 又称彩色空间或彩色系统 本质上 彩色模型是坐标系统和子空间的阐述 位于系统的每种颜色都有单个点表示 RGB 红绿蓝 是依据人眼识别的颜色定义出的空间 可表示大部分颜色 但在科学研究中一般不采用RGB颜色
  • ARouter 源码分析

    ARouter基本使用 在开始分析源码之前 先了解一下ARoute如何使用的 使用ARoute可以概括为以下3步 项目中引入ARouter 及配置 初始化ARouter 开始使用 下面详细的看下每一步怎么操作 项目中引入ARouter及配置
  • 计算机一级2010的试题,全国计算机等级考试一级office2010试题

    计算机一级是要求考生对基础的计算机知识进行掌握 下面给大家整理了全国计算机等级考试一级office2010试题 欢迎阅读 全国计算机等级考试一级office2010试题 选择题答案 1 5 C A D B B 6 10 B C D B D
  • Qt项目实战2:图片查看器QImageViewer

    在博文Qt学习笔记2 QMainWindow和QWidget的区别中介绍了使用空的Qt项目创建带有菜单栏 工具栏的界面 这里 使用一个简单的图片查看器项目 来熟悉一下Qt的图片显示和基本操作 该项目实现的主要功能 实现图片的打开 关闭 居中
  • Head First Design Mode(12)-状态模式

    该系列文章系个人读书笔记及总结性内容 任何组织和个人不得转载进行商业活动 状态模式 状态模式和策略模式是 双胞胎 在出生时才分开 策略模式是围绕可以互换的算法来创建成功业务的 状态模式则是通过改变对象内部的状态来帮助对象控制自己的行为 状态
  • 麻雀虽小五脏俱全,中小企业的知识管理须重视

    编者按 在知识资产越来越重要的市场发展环境下 做好企业知识管理对中小企业来说十分重要 本文从企业知识管理的重要性说起 分析了现代中小企业面临的知识管理困境 并进一步提出天翎KMS是如何帮助企业突破这种困境的 概要 1 知识管理的重要性 2
  • 表白墙 -- 前后端代码详解

    表白墙 前后端代码详解 一 前端 二 后端实现 2 1 需求 2 2 创建项目及初始化 2 3 实现提交数据 存档 2 3 1 实现 doPost 2 3 2 构造请求 修改 html 文件 2 3 3 验证 2 4 实现获取数据 读档 2