給自己網站增加一個免費的AI助手,純HTML

助手效果圖

看完這篇文章,你將免費擁有你自己的Ai助手,全程干貨,先到先得
在這里插入圖片描述

獲取免費的AI大模型接口

訪問這個地址 生成key https://openrouter.ai/mistralai/mistral-small-3.2-24b-instruct:free/api
或者調用其他的免費大模型,這個根據自己的需求更改,要先注冊這個網站
在這里插入圖片描述

修改默認的參數

最主要的就是你申請生成的key
在這里插入圖片描述

助手源碼

純HTML的源碼,嘎嘎夠勁

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title></title><style>body {font-family: 'Arial', sans-serif;margin: 0;padding: 0;height: 100vh;user-select: none;overflow: hidden;}#chat-container {position: fixed;bottom: 20px;right: 20px;width: 300px;height: 400px;background-color: white;border-radius: 10px;box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);display: flex;flex-direction: column;overflow: hidden;z-index: 1000;resize: both;min-width: 300px;min-height: 400px;transition: transform 0.2s ease, opacity 0.2s ease;transform-origin: bottom right;}#chat-container.minimized {transform: scale(0);opacity: 0;pointer-events: none;}#chat-header {background-color: #4a6bdf;color: white;padding: 12px 15px;cursor: move;display: flex;justify-content: space-between;align-items: center;}#chat-title {font-weight: bold;font-size: 16px;}#minimize-btn, #restore-btn {background: none;border: none;color: white;font-size: 18px;cursor: pointer;padding: 0;width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;}#minimized-chat {position: fixed;width: 50px;height: 50px;border-radius: 10px;background-color: #4a6bdf;box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);z-index: 1000;display: none;transition: transform 0.1s ease;}#minimized-chat:active {transform: scale(0.95);}#restore-btn {position: absolute;width: 100%;height: 100%;font-size: 24px;display: flex;align-items: center;justify-content: center;cursor: move;pointer-events: auto;}#chat-messages {flex: 1;padding: 15px;overflow-y: auto;background-color: #f9f9f9;}.message {margin-bottom: 12px;max-width: 80%;padding: 8px 12px;border-radius: 12px;line-height: 1.4;word-wrap: break-word;}.user-message {background-color: #e3effd;margin-left: auto;border-bottom-right-radius: 4px;}.ai-message {background-color: white;margin-right: auto;border-bottom-left-radius: 4px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);}#chat-input-area {display: flex;padding: 10px;border-top: 1px solid #eee;background-color: white;}#chat-input {flex: 1;padding: 10px;border: 1px solid #ddd;border-radius: 20px;outline: none;resize: none;height: 40px;max-height: 100px;font-family: inherit;}#send-btn {margin-left: 10px;padding: 0 15px;background-color: #4a6bdf;color: white;border: none;border-radius: 20px;cursor: pointer;transition: background-color 0.2s;}#send-btn.stop {background-color: #ff4d4d;}#send-btn:hover {background-color: #3a5bcf;}#send-btn.stop:hover {background-color: #e63c3c;}.typing-indicator {display: inline-block;margin-left: 5px;}.typing-dot {display: inline-block;width: 6px;height: 6px;border-radius: 50%;background-color: #999;margin-right: 3px;animation: typingAnimation 1.4s infinite ease-in-out;}.typing-dot:nth-child(1) {animation-delay: 0s;}.typing-dot:nth-child(2) {animation-delay: 0.2s;}.typing-dot:nth-child(3) {animation-delay: 0.4s;}@keyframes typingAnimation {0%, 60%, 100% {transform: translateY(0);}30% {transform: translateY(-5px);}}.stopped-message {color: #888;font-style: italic;}</style>
</head><body><div id="chat-container"><div id="chat-header"><div id="chat-title">AI助手</div><button id="minimize-btn">?</button></div><div id="chat-messages"></div><div id="chat-input-area"><textarea id="chat-input" placeholder="輸入消息..." rows="1"></textarea><button id="send-btn">發送</button></div></div><div id="minimized-chat"><button id="restore-btn">+</button></div><script>// 獲取DOM元素const chatContainer = document.getElementById('chat-container');const chatHeader = document.getElementById('chat-header');const minimizedChat = document.getElementById('minimized-chat');const minimizeBtn = document.getElementById('minimize-btn');const restoreBtn = document.getElementById('restore-btn');const chatInput = document.getElementById('chat-input');const sendBtn = document.getElementById('send-btn');const chatMessages = document.getElementById('chat-messages');// 全局變量let isDragging = false;let isMinimizedDragging = false;let offsetX, offsetY;let startX, startY;let restoreBtnClicked = false;let abortController = null; // 用于中止fetch請求let isWaitingForResponse = false; // 是否正在等待響應let isTypingEffectActive = false; // 是否正在打字效果中let typingTimeoutId = null; // 打字效果的timeout ID// 限制元素在窗口范圍內function constrainToWindow(element, x, y) {const rect = element.getBoundingClientRect();const windowWidth = window.innerWidth;const windowHeight = window.innerHeight;const maxX = windowWidth - rect.width;const maxY = windowHeight - rect.height;x = Math.max(0, Math.min(x, maxX));y = Math.max(0, Math.min(y, maxY));return { x, y };}// 主窗口拖動功能chatHeader.addEventListener('mousedown', (e) => {if (e.target.id !== 'chat-header' && e.target.id !== 'chat-title') return;isDragging = true;startX = e.clientX;startY = e.clientY;const rect = chatContainer.getBoundingClientRect();offsetX = startX - rect.left;offsetY = startY - rect.top;chatContainer.style.cursor = 'grabbing';chatContainer.style.transition = 'none';e.preventDefault();});// 恢復按鈕拖動功能restoreBtn.addEventListener('mousedown', (e) => {isMinimizedDragging = true;restoreBtnClicked = false;startX = e.clientX;startY = e.clientY;const rect = minimizedChat.getBoundingClientRect();offsetX = startX - rect.left;offsetY = startY - rect.top;minimizedChat.style.cursor = 'grabbing';minimizedChat.style.transition = 'none';e.preventDefault();e.stopPropagation();});// 恢復按鈕點擊功能restoreBtn.addEventListener('dblclick', (e) => {if (!isMinimizedDragging && !restoreBtnClicked) {restoreBtnClicked = true;restoreChatWindow();}e.stopPropagation();});document.addEventListener('mousemove', (e) => {if (isDragging) {let x = e.clientX - offsetX;let y = e.clientY - offsetY;const constrained = constrainToWindow(chatContainer, x, y);x = constrained.x;y = constrained.y;chatContainer.style.left = `${x}px`;chatContainer.style.top = `${y}px`;chatContainer.style.right = 'auto';chatContainer.style.bottom = 'auto';}if (isMinimizedDragging) {let x = e.clientX - offsetX;let y = e.clientY - offsetY;const constrained = constrainToWindow(minimizedChat, x, y);x = constrained.x;y = constrained.y;minimizedChat.style.left = `${x}px`;minimizedChat.style.top = `${y}px`;minimizedChat.style.right = 'auto';minimizedChat.style.bottom = 'auto';}});document.addEventListener('mouseup', () => {if (isDragging) {isDragging = false;chatContainer.style.cursor = 'default';chatContainer.style.transition = 'transform 0.2s ease, opacity 0.2s ease';}if (isMinimizedDragging) {isMinimizedDragging = false;minimizedChat.style.cursor = 'move';minimizedChat.style.transition = 'transform 0.1s ease';}});// 縮小/恢復功能minimizeBtn.addEventListener('click', (e) => {e.stopPropagation();const rect = chatContainer.getBoundingClientRect();minimizedChat.style.left = `${rect.left}px`;minimizedChat.style.top = `${rect.top}px`;minimizedChat.style.right = 'auto';minimizedChat.style.bottom = 'auto';const constrained = constrainToWindow(minimizedChat, parseFloat(minimizedChat.style.left || 0),parseFloat(minimizedChat.style.top || 0));minimizedChat.style.left = `${constrained.x}px`;minimizedChat.style.top = `${constrained.y}px`;chatContainer.classList.add('minimized');setTimeout(() => {minimizedChat.style.display = 'block';}, 200);});function restoreChatWindow() {chatContainer.style.left = 'auto';chatContainer.style.top = 'auto';chatContainer.style.right = '20px';chatContainer.style.bottom = '20px';chatContainer.classList.remove('minimized');minimizedChat.style.display = 'none';}// 聊天功能chatInput.addEventListener('input', function() {this.style.height = 'auto';this.style.height = (this.scrollHeight > 100 ? 100 : this.scrollHeight) + 'px';});function sendMessage() {const message = chatInput.value.trim();if (!message) return;addMessage(message, 'user');chatInput.value = '';chatInput.style.height = '40px';// 改變按鈕狀態setSendButtonState('stop');const typingId = showTypingIndicator();simulateAIResponse(message, typingId);}function stopRequest() {if (abortController) {abortController.abort();abortController = null;}if (isTypingEffectActive) {clearTimeout(typingTimeoutId);isTypingEffectActive = false;// 添加停止提示const stoppedDiv = document.createElement('div');stoppedDiv.className = 'message ai-message stopped-message';stoppedDiv.textContent = '已停止生成回復';chatMessages.appendChild(stoppedDiv);chatMessages.scrollTop = chatMessages.scrollHeight;}setSendButtonState('send');isWaitingForResponse = false;// 移除正在輸入指示器const typingElements = document.querySelectorAll('[id^="typing-"]');typingElements.forEach(el => el.remove());}function setSendButtonState(state) {if (state === 'stop') {sendBtn.textContent = '停止';sendBtn.classList.add('stop');sendBtn.removeEventListener('click', sendMessage);sendBtn.addEventListener('click', stopRequest);isWaitingForResponse = true;} else {sendBtn.textContent = '發送';sendBtn.classList.remove('stop');sendBtn.removeEventListener('click', stopRequest);sendBtn.addEventListener('click', sendMessage);isWaitingForResponse = false;}}chatInput.addEventListener('keydown', (e) => {if (e.key === 'Enter' && !e.shiftKey) {e.preventDefault();if (!isWaitingForResponse) {sendMessage();}}});// 初始化按鈕事件sendBtn.addEventListener('click', sendMessage);function addMessage(text, sender) {const messageDiv = document.createElement('div');messageDiv.className = `message ${sender}-message`;messageDiv.textContent = text;chatMessages.appendChild(messageDiv);chatMessages.scrollTop = chatMessages.scrollHeight;}function showTypingIndicator() {const typingDiv = document.createElement('div');typingDiv.className = 'message ai-message';typingDiv.id = 'typing-' + Date.now();const typingText = document.createElement('span');typingText.textContent = 'YiLin:';const typingDots = document.createElement('span');typingDots.className = 'typing-indicator';for (let i = 0; i < 3; i++) {const dot = document.createElement('span');dot.className = 'typing-dot';typingDots.appendChild(dot);}typingDiv.appendChild(typingText);typingDiv.appendChild(typingDots);chatMessages.appendChild(typingDiv);chatMessages.scrollTop = chatMessages.scrollHeight;return typingDiv.id;}function removeTypingIndicator(id) {const typingElement = document.getElementById(id);if (typingElement) {typingElement.remove();}}async function simulateAIResponse(userMessage, typingId) {abortController = new AbortController();try {const response = await fetch("https://openrouter.ai/api/v1/chat/completions", {method: "POST",headers: {"Authorization": "Bearer sk-or-v1-xxxxxxxxxxxx","HTTP-Referer": "https://nanwish.love","X-Title": "沂霖博客","Content-Type": "application/json"},body: JSON.stringify({"model": "mistralai/mistral-small-3.2-24b-instruct:free","messages": [{"role": "user","content": [{"type": "text","text": userMessage}]}]}),signal: abortController.signal});const data = await response.json();removeTypingIndicator(typingId);if (data.choices && data.choices[0].message.content) {typeWriterEffect(data.choices[0].message.content);} else {addMessage("抱歉,未能獲取有效回復", 'ai');setSendButtonState('send');}} catch (error) {if (error.name !== 'AbortError') {removeTypingIndicator(typingId);addMessage("抱歉,發生錯誤: " + error.message, 'ai');setSendButtonState('send');}} finally {abortController = null;}}function typeWriterEffect(text) {const messageDiv = document.createElement('div');messageDiv.className = 'message ai-message';chatMessages.appendChild(messageDiv);let i = 0;const speed = 20;isTypingEffectActive = true;function type() {if (i < text.length) {messageDiv.textContent += text.charAt(i);i++;chatMessages.scrollTop = chatMessages.scrollHeight;typingTimeoutId = setTimeout(type, speed);} else {isTypingEffectActive = false;setSendButtonState('send');}}type();}// 初始化window.addEventListener('DOMContentLoaded', () => {minimizedChat.style.display = 'none';setTimeout(() => {typeWriterEffect("你好!我是沂霖,我可以輔助你使用MarkDown,聊天,查資料!你可以輸入問題或指令,我會盡力回答。");}, 500);});// 窗口大小變化時重新限制位置window.addEventListener('resize', () => {if (!chatContainer.classList.contains('minimized')) {const rect = chatContainer.getBoundingClientRect();const constrained = constrainToWindow(chatContainer, rect.left, rect.top);chatContainer.style.left = `${constrained.x}px`;chatContainer.style.top = `${constrained.y}px`;}if (minimizedChat.style.display === 'block') {const rect = minimizedChat.getBoundingClientRect();const constrained = constrainToWindow(minimizedChat, rect.left, rect.top);minimizedChat.style.left = `${constrained.x}px`;minimizedChat.style.top = `${constrained.y}px`;}});</script>
</body></html>

把這個嵌入到你的網站頁面 就可以實現站點助手了

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89002.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89002.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89002.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ASProxy64.dll導致jetbrains家的IDE都無法打開。

在Windows11中,無法打開jetbrains的IDE的軟件,經過排查,發現與ASProxy64.dll有關。 E:\idea\IntelliJ IDEA 2024.1.7\bin>idea.bat CompileCommand: exclude com/intellij/openapi/vfs/impl/FilePartNodeRoot.trieDescend bool exclude = true # # A fatal error has bee…

springboot+Vue逍遙大藥房管理系統

概述 基于springbootVue開發的逍遙大藥房管理系統。該系統功能完善&#xff0c;既包含強大的后臺管理模塊&#xff0c;又具備用戶友好的前臺展示界面。 主要內容 一、后臺管理系統功能 ??核心管理模塊??&#xff1a; 用戶管理&#xff1a;管理員與普通用戶權限分級藥品分…

探索阿里云智能媒體管理IMM:解鎖媒體處理新境界

一、引言&#xff1a;開啟智能媒體管理新時代 在數字化浪潮的席卷下&#xff0c;媒體行業正經歷著前所未有的變革。從傳統媒體到新媒體的轉型&#xff0c;從內容生產到傳播分發&#xff0c;每一個環節都在尋求更高效、更智能的解決方案。而云計算&#xff0c;作為推動這一變革…

[附源碼+數據庫+畢業論文]基于Spring+MyBatis+MySQL+Maven+jsp實現的新生報道管理系統,推薦!

摘要 隨著信息技術在管理上越來越深入而廣泛的應用&#xff0c;管理信息系統的實施在技術上已逐步成熟。本文介紹了新生報道管理系統的開發全過程。通過分析高校新生入學報到信息管理的不足&#xff0c;創建了一個計算機管理高校新生入學報到信息的方案。文章介紹了新生報道管…

給定一個整型矩陣map,求最大的矩形區域為1的數量

題目: 給定一個整型矩陣map,其中的值只有0和1兩種,求其中全是1的 所有矩形區域中,最大的矩形區域為1的數量。 例如: 1 1 1 0 其中,最大的矩形區域有3個1,所以返回3。 再如: 1 0 1 1 1 1 1 1 1 1 1 0 其中,最大的矩形區域有6個1,所以返回6。 解題思…

第8章-財務數據

get_fund # 查看股票代碼000001.XSHE在2022年9月1日的總市值 q query( valuation ).filter( valuation.code 000001.XSHE ) df get_fundamentals(q, 2022-09-01) print(df[market_cap][0]) # 獲取第一行的market_cap值 這段代碼看起來是用于查詢股票在特定日期的總…

SQL關鍵字三分鐘入門:ROW_NUMBER() —— 窗口函數為每一行編號

在進行數據分析時&#xff0c;我們常常需要為查詢結果集中的每條記錄生成一個唯一的序號或行號。例如&#xff1a; 為每位員工按照入職時間排序并編號&#xff1b;按照訂單金額對訂單進行排序&#xff0c;并給每個訂單分配一個順序編號&#xff1b;在分組數據內為每條記錄編號…

微信小程序如何實現通過郵箱驗證修改密碼功能

基于騰訊云開發&#xff08;Tencent Cloud Base&#xff09;實現小程序郵箱驗證找回密碼功能的完整邏輯說明及關鍵代碼實現。結合安全性和開發效率&#xff0c;方案采用 ??云函數 小程序前端?? 的架構&#xff0c;使用 ??Nodemailer?? 發送郵件。Nodemailer 是一個專為…

C# VB.NET中Tuple輕量級數據結構和固定長度數組

C# VB.NET取字符串中全角字符數量和半角字符數量-CSDN博客 https://blog.csdn.net/xiaoyao961/article/details/148871910 在VB.NET中&#xff0c;使用Tuple和固定長度數組在性能上有細微差異&#xff0c;以下是詳細分析&#xff1a; 性能對比測試 通過測試 100 萬次調用&am…

建筑物年代預測與空間異質性分析解決方案

建筑物年代預測與空間異質性分析解決方案 1. 問題分析與創新點設計 核心任務:預測建筑物建造年代,并分析空間異質性對預測的影響 創新點設計: 空間權重矩陣集成:構建空間鄰接矩陣量化地理鄰近效應多尺度特征提取:融合建筑物微觀特征與街區宏觀特征異質性分區建模:基于…

FOUPK3system5XOS

Foupk3systemX5OS系統19.60內測版&#xff08;X9&#xff09;2023年4月16日正式發布 1.0Foupk3systemX5OS系統19.60&#xff08;X9&#xff09;2024年10月6日發布 Foupk3systemX5OS系統19.60增強版&#xff08;X9X5&#xff09;2024年10月6日發布Foupk3systemX5OS系統19.60正…

隨機生成的亂碼域名”常由**域名生成算法(DGA)** 產生

“隨機生成的亂碼域名”常由**域名生成算法&#xff08;DGA&#xff09;** 產生&#xff0c;是網絡攻擊&#xff08;尤其是僵尸網絡、惡意軟件控制場景 &#xff09;中躲避檢測的手段&#xff0c;以下是關鍵解析&#xff1a; ### 一、本質與產生邏輯 亂碼域名是攻擊者利用 **DG…

Solidity學習 - 繼承

文章目錄 前言繼承的基本概念繼承的基本用法單繼承實現函數重寫&#xff08;overriding&#xff09; 構造函數的繼承處理多重繼承抽象合約 前言 繼承是面向對象編程中的核心概念之一&#xff0c;Solidity作為一種面向對象的智能合約語言&#xff0c;同樣支持繼承機制。通過繼承…

依賴注入(Dependency Injection, DI)的核心概念和解決的核心問題

核心概念&#xff1a; 依賴注入是一種設計模式&#xff0c;也是實現控制反轉&#xff08;Inversion of Control, IoC&#xff09; 原則的一種具體技術。其核心思想是&#xff1a; 解耦&#xff1a; 將一個類&#xff08;客戶端&#xff09;所依賴的其他類或服務&#xff08;依…

Reactor Schedulers

Reactor 是一個基于響應式編程的庫&#xff0c;它提供了豐富的調度器&#xff08;Schedulers&#xff09;機制&#xff0c;用于管理異步操作的執行環境。Schedulers 是 Reactor 中的核心組件之一&#xff0c;它們允許開發者靈活地控制操作符和訂閱操作在哪個線程上執行&#xf…

設備樹引入

一、設備樹的基本知識 1、什么是設備樹&#xff1f;為什么會有設備樹&#xff1f; 2011年&#xff0c;Linux之父Linus Torvalds發現這個問題后&#xff0c;就通過郵件向ARM-Linux開發社區發了一封郵件&#xff0c;不禁的發出了一句“This whole ARM thing is a f*cking pain i…

【數據標注師】3D標注

目錄 一、 **3D標注知識體系框架**二、 **五階能力培養體系**? **階段1&#xff1a;空間認知筑基&#xff08;2-3周&#xff09;**? **階段2&#xff1a;核心標注技能深化**? **階段3&#xff1a;復雜場景解決方案**? **階段4&#xff1a;領域深度專精? **階段5&#xff1…

華為HN8145V光貓改華為藍色公版界面,三網通用,xgpon公版光貓

咸魚只賣20多元一個&#xff0c;還是xgpon的萬兆貓&#xff0c;性價比不錯哦 除了沒有2.5G網口&#xff0c;其他還行。 改成公版光貓后&#xff0c;運營商是無法納管光貓&#xff0c;無法后臺修改光貓數據及超密。 華為 HN8145V 光貓具有以下特點&#xff1a; 性能方面 高速接…

【LeetCode 熱題 100】438. 找到字符串中所有字母異位詞——(解法二)定長滑動窗口+數組

Problem: 438. 找到字符串中所有字母異位詞 題目&#xff1a;給定兩個字符串 s 和 p&#xff0c;找到 s 中所有 p 的 異位詞 的子串&#xff0c;返回這些子串的起始索引。不考慮答案輸出的順序。 【LeetCode 熱題 100】438. 找到字符串中所有字母異位詞——&#xff08;解法一&…

PAC 學習框架:機器學習的可靠性工程

PAC&#xff08;Probably Approximately Correct&#xff09; 是機器學習理論的核心框架&#xff0c;用于量化學習算法的可靠性。它回答了一個關鍵問題&#xff1a; “需要多少訓練樣本&#xff0c;才能以較高概率學到一個近似正確的模型&#xff1f;” 一、PAC 名稱拆解 術語…