97色伦色在线综合视频,无玛专区,18videosex性欧美黑色,日韩黄色电影免费在线观看,国产精品伦理一区二区三区,在线视频欧美日韩,亚洲欧美在线中文字幕不卡

河南省建設(shè)廳網(wǎng)站考試成績(jī)查詢北京網(wǎng)站設(shè)計(jì)方案

鶴壁市浩天電氣有限公司 2026/01/24 17:37:51
河南省建設(shè)廳網(wǎng)站考試成績(jī)查詢,北京網(wǎng)站設(shè)計(jì)方案,網(wǎng)絡(luò)規(guī)劃與設(shè)計(jì)報(bào)告,uilike學(xué)堂1分鐘看圖掌握核心觀點(diǎn)#x1f447;圖片一、前言在如今基于AI搜索的對(duì)話舞臺(tái)上#xff0c;如果一段文字像老式打字機(jī)一樣逐字逐句展現(xiàn)在屏幕上#xff0c;那將是一種具有獨(dú)特魅力的吸引力。話不多說(shuō)#xff0c;先來(lái)看下最終的實(shí)現(xiàn)效果。圖片二、引言在AI搜索場(chǎng)景中#xf…1分鐘看圖掌握核心觀點(diǎn)圖片一、前言在如今基于AI搜索的對(duì)話舞臺(tái)上如果一段文字像老式打字機(jī)一樣逐字逐句展現(xiàn)在屏幕上那將是一種具有獨(dú)特魅力的吸引力。話不多說(shuō)先來(lái)看下最終的實(shí)現(xiàn)效果。圖片二、引言在AI搜索場(chǎng)景中由于大模型基于流式輸出文本需要多次響應(yīng)結(jié)果到前端因此這種場(chǎng)景十分適合使用打字機(jī)效果。打字機(jī)效果是指在生成內(nèi)容的場(chǎng)景中文字逐字符動(dòng)態(tài)顯示模擬人工打字的過(guò)程主要是出于提升用戶體驗(yàn)、優(yōu)化交互邏輯和增強(qiáng)心理感知等方面的考量緩解等待焦慮降低“無(wú)反饋”的負(fù)面體驗(yàn)。內(nèi)容是逐步響應(yīng)的打字機(jī)效果可以很好地提供“實(shí)時(shí)反饋”用戶可以感知到系統(tǒng)正在工作從而減少了等待過(guò)程中的不確定性和焦慮感。模擬自然交互增強(qiáng)“類人對(duì)話”的沉浸感。對(duì)話交流具有停頓、強(qiáng)調(diào)等節(jié)奏感通過(guò)實(shí)時(shí)打字的模擬跟容易拉近與用戶的心理距離增強(qiáng)對(duì)話感和沉浸感。優(yōu)化信息接收效率避免“信息過(guò)載”。如果一次性展示大量密密麻麻的文字用戶需要花時(shí)間篩選重點(diǎn)容易產(chǎn)生抵觸通過(guò)打字機(jī)效果可以緩和閱讀節(jié)奏減少視覺和認(rèn)知負(fù)擔(dān)。強(qiáng)化“AI生成”的感知降低對(duì)“標(biāo)準(zhǔn)答案”的預(yù)期。使用戶感知到是AI實(shí)時(shí)計(jì)算結(jié)果而非預(yù)存的標(biāo)準(zhǔn)答案有助于用戶理性客觀地使用工具。三、早期實(shí)現(xiàn)方案——純文本逐字符打字效果最開始的產(chǎn)品功能需要根據(jù)用戶輸入的搜索詞流式輸出并逐字符展示到頁(yè)面上這可以說(shuō)是打字機(jī)效果的入門級(jí)實(shí)現(xiàn)了不依賴任何復(fù)雜的技術(shù)其流程圖大致如下所示。圖片3.1 詳細(xì)說(shuō)明前端會(huì)定義一個(gè)字段用來(lái)緩存全量的markdown文本每次服務(wù)端流式響應(yīng)markdown文本到前端時(shí)前端都會(huì)將其追加到這個(gè)緩存字段后然后基于marked依賴庫(kù)將全量的markdown文本轉(zhuǎn)換為html片段。要實(shí)現(xiàn)逐字符渲染的動(dòng)畫效果就需要定時(shí)更新文本。定時(shí)功能一般采用setTimeout或setInterval來(lái)實(shí)現(xiàn)而更新文本可以考慮innerHTML和appendChild的方式這里采用的innerHTML方式插入文本核心代碼如下所示。let fullText test text;// 全量的html文本let index 0;// 當(dāng)前打印到的下標(biāo)let timer window.setInterval(() {index;$dom.innerHTML fullText.substring(0, index);}, 40);3.2 innerHTML與appendChild的核心區(qū)別對(duì)比圖片為什么選擇innerHTML而非appendChild由于服務(wù)端是流式返回markdown文本因此每次返回的markdown文本可能不是完整的。舉個(gè)例子如下。先返回下面一段markdown文本** 這是一個(gè)再返回下面一段markdown文本標(biāo)題 **先返回的文本會(huì)當(dāng)作純文本展示再返回的文本會(huì)與先返回的文本結(jié)合生成html片段如下strong這是一個(gè)標(biāo)題/strong如果使用appendChild的話就不好處理上述場(chǎng)景。3.3 小結(jié)這種方式的優(yōu)點(diǎn)就是簡(jiǎn)單易懂很容易上手實(shí)現(xiàn)也沒有任何依賴。但是它的缺點(diǎn)也是顯而易見的。比如我們無(wú)法方便的添加一些額外的動(dòng)畫效果來(lái)增強(qiáng)視覺體驗(yàn)如光標(biāo)閃爍效果對(duì)于一些復(fù)雜文本內(nèi)容或者需要更加靈活地控制展示細(xì)節(jié)時(shí)也會(huì)顯得捉襟見肘并且每次通過(guò)innerHTML渲染文本時(shí)都觸發(fā)了dom的銷毀與創(chuàng)建性能消耗大。四、需求難度進(jìn)一步提升隨著產(chǎn)品的迭代業(yè)務(wù)要求打字內(nèi)容不僅是純文本還需要穿插展示卡片等復(fù)雜樣式效果如下圖所示??ㄆ念愋桶☉?yīng)用、股票、影視等需要可擴(kuò)展、可配置并且還會(huì)包括復(fù)雜的交互效果如點(diǎn)擊、跳轉(zhuǎn)等。圖片很明顯基于早期的實(shí)現(xiàn)方案已經(jīng)遠(yuǎn)遠(yuǎn)不能滿足日益增強(qiáng)的業(yè)務(wù)訴求了必須考慮更加靈活高效的技術(shù)方案。五、現(xiàn)代框架下的實(shí)現(xiàn)——基于Vue虛擬dom動(dòng)態(tài)更新通過(guò)上述的分析打字內(nèi)容中要穿插展示卡片顯然需要使用單例模式否則如果每次打字都重新創(chuàng)建元素的話不僅性能低下而且數(shù)據(jù)和狀態(tài)還無(wú)法保持一致。而要使用單例模式就必須根據(jù)現(xiàn)有數(shù)據(jù)對(duì)已插入節(jié)點(diǎn)進(jìn)行插入、更新、移除等操作以保持?jǐn)?shù)據(jù)的一致性這就很自然地會(huì)想到使用現(xiàn)代前端框架來(lái)對(duì)打字機(jī)效果進(jìn)行改進(jìn)。Vue是基于虛擬dom的漸進(jìn)式j(luò)avascript框架僅在數(shù)據(jù)變化時(shí)計(jì)算差異并更新必要的部分因此可以借助其數(shù)據(jù)驅(qū)動(dòng)開發(fā)、組件化開發(fā)等特性輕松地構(gòu)建一個(gè)可復(fù)用的打字機(jī)效果組件。5.1 設(shè)計(jì)思路要實(shí)現(xiàn)打字正文中穿插卡片的效果首先需要定義好返回的數(shù)據(jù)結(jié)構(gòu)它需要具備可擴(kuò)展方便解析兼容markdown等特性所以使用html標(biāo)簽是一種比較合適的方式例如要展示一個(gè)應(yīng)用卡片可以下發(fā)如下所示數(shù)據(jù)。app id /從下發(fā)的數(shù)據(jù)中可以獲取到標(biāo)簽名和屬性鍵值對(duì)這樣就可以通過(guò)標(biāo)簽名來(lái)渲染關(guān)聯(lián)到的組件模板通過(guò)屬性鍵值對(duì)去服務(wù)端加載對(duì)應(yīng)的數(shù)據(jù)于是就可以水到渠成的把應(yīng)用卡片展示出來(lái)其流程圖如下圖所示。圖片5.2 詳細(xì)說(shuō)明組件模板文件按照一定規(guī)則組織在特定的目錄下在構(gòu)建時(shí)打包到資源里關(guān)鍵代碼如下所示。privateinit(){let fileList require.context(/components/common/box, true, /.vue$/);fileList.keys().forEach((filePath) {let startIndex filePath.lastIndexOf(/);let endIndex filePath.lastIndexOf(.);let tagName filePath.substring(startIndex 1, endIndex);this.widgetMap[tagName] fileList(filePath).default;});}之前版本在每次接收到服務(wù)端下發(fā)的markdown文本時(shí)都會(huì)做一次轉(zhuǎn)換成html的操作如果多次響應(yīng)之間的間隔時(shí)間很短則會(huì)出現(xiàn)略微卡頓的現(xiàn)象因此這里轉(zhuǎn)換為html時(shí)再增加一個(gè)防抖功能可以很有效的避免卡頓。每次定時(shí)截取到待渲染的html文本以后會(huì)基于ultrahtml庫(kù)將其轉(zhuǎn)換為dom樹并過(guò)濾掉注釋、腳本等標(biāo)簽核心代碼如下。let toRenderHtml this.rawHtml.substring(0, this.curIndex);let dom {type: ELEMENT_NODE,name: p,children: parse(toRenderHtml).children};最后就是全局注冊(cè)一個(gè)遞歸組件用來(lái)渲染轉(zhuǎn)換后的dom樹核心代碼如下。render(h: any) {// 此處省略若干代碼// 處理子節(jié)點(diǎn)let children this.dom[children] || [];let renderChildren children.map((child: any, index: number) {return h(CommonDisplay, {props: {dom: child,displayCursor: this.displayCursor,lastLine: this.lastLine index children.length - 1,ignoreBoxTag: this.ignoreBoxTag}});});// 此處省略若干代碼// 處理文本節(jié)點(diǎn)if (this.dom[type] TEXT_NODE) {returnthis.renderTextNode({h, element: this.dom});}// 處理自定義組件標(biāo)簽let tagName this.dom[type] ELEMENT_NODE ? this.dom[name] : div;if (this.$factory.hasTag(tagName)) {// 此處省略若干代碼let widget this.$factory.getWidget(tagName);return h(widget, {key: tagId,props: {displayCursor: this.displayCursor,lastLine: this.lastLine,text,...attributes}}, isLastLeaf this.displayCursor ? [h(commonCursor)] : []);}// 處理html原始標(biāo)簽return h(tagName, {attrs: {displayCursor: this.displayCursor,lastLine: this.lastLine,...this.dom[attributes]}}, renderChildren);}5.3 問(wèn)題整理和解決打字機(jī)功能終于正常運(yùn)行了流暢度還是不錯(cuò)的但是在體驗(yàn)的過(guò)程中也發(fā)現(xiàn)了一些細(xì)節(jié)問(wèn)題。①打字文本中如果存在標(biāo)簽如 pxxx/p 會(huì)出現(xiàn)先展示 ,再展示 p 最后展示空的效果也就是字符回退極大影響閱讀體驗(yàn)。原因分析定時(shí)截取待渲染文本時(shí)是通過(guò)定義一個(gè)下標(biāo)遞增逐字符截取的這就導(dǎo)致標(biāo)簽并沒有作為一個(gè)原子結(jié)構(gòu)被整體截取于是就出現(xiàn)了字符回退的現(xiàn)象。解決方案當(dāng)下標(biāo)指向的字符為 時(shí)則往后截取到 的位置核心代碼如下。if (curChar ) {let lastGtIndex this.rawHtml.indexOf(, this.curIndex);if (lastGtIndex -1) {this.curIndex lastGtIndex 1;returnfalse;}}② 打字文本中如果存在轉(zhuǎn)義字符如 quot; 則會(huì)依次出現(xiàn)這些字符最后再展示 也就是字符閃爍也十分影響閱讀體驗(yàn)。原因分析原因同上述字符回退一樣也是沒有把轉(zhuǎn)義字符當(dāng)作一個(gè)整體截取。解決方案當(dāng)下標(biāo)指向的字符為 時(shí)則往后截取到轉(zhuǎn)義字符結(jié)束的位置核心代碼如下。// 大模型大概率只下發(fā)有限類別的轉(zhuǎn)義字符做成配置動(dòng)態(tài)下發(fā)不僅解析方便定制下發(fā)也很及時(shí)if (curChar ) {let matchEscape this.config[writer][escapeArr].find((item: any) {returnthis.rawHtml.indexOf(item, this.curIndex) this.curIndex;});if (matchEscape) {this.curIndex matchEscape.length;returnfalse;}}③ 打字過(guò)程中的速度是固定的缺少一點(diǎn)抑揚(yáng)頓挫的節(jié)奏感不夠自然。原因分析定時(shí)器的間隔時(shí)間是固定的一個(gè)數(shù)值所以表現(xiàn)為一個(gè)固定不變的打字節(jié)奏。解決方案可以根據(jù)未打印字符數(shù)來(lái)動(dòng)態(tài)調(diào)整每次打字的速度一種可選的實(shí)現(xiàn)方案如下。假設(shè)未打印字符數(shù)為 N 速度平滑指數(shù)為 a 實(shí)際打字速度為 Vcurrent 邏輯應(yīng)達(dá)到的打字速度為 Vnew 。if N 10 , Vnew 100 ms / 1字符if 10 N 20 , Vnew 100 - 8 * ( N - 10 ) ms / 1字符if 20 N , Vnew 20 ms / 4字符Vcurrent a * Vcurrent ( 1 - a ) * Vnew上述策略可能會(huì)比較多而且上線以后還有可能更換數(shù)值對(duì)照效果因此為了支持配置化我們可以對(duì)Vnew進(jìn)行表達(dá)式歸納如下所示。Vnew Vinit - w * ( N - min ) bVinit 為默認(rèn)初始打字速度w 為每條策略的權(quán)重值N 為未打印字符數(shù)min 為每條策略的最小字符數(shù)量比較值b 為每條策略的偏置。關(guān)鍵代碼如下所示。privatespeedFn({curSpeed, curIndex, totalLength}: any){let leftCharLength Math.max(0, totalLength - curIndex);let matchStrategy this.config[writer][strategy].find((item: any) {return (!item[min] || item[min] leftCharLength) (!item[max] || item[max] leftCharLength);});let speed this.config[writer][initSpeed] - matchStrategy[w] * (leftCharLength - (matchStrategy[min] || 0)) matchStrategy[b];returnthis.config[writer][smoothParam] * curSpeed (1 - this.config[writer][smoothParam]) * speed;}④ 打字過(guò)程中會(huì)時(shí)不時(shí)的回退到之前字符的位置重新開始打字例如當(dāng)前展示 a b c 等到下一次渲染時(shí)會(huì)從 a 開始重新打完這一段。原因分析由于markdown文本結(jié)合會(huì)生成html標(biāo)簽從而導(dǎo)致字符數(shù)量增多那么當(dāng)前下標(biāo)指向的字符就相對(duì)之前落后了。let curIndex 5;// 當(dāng)前下標(biāo)let prevMarkdown **hello;// 上一次打印時(shí)的全量markdown文本let prevHtml p**hello/p;// 上一次打印時(shí)的全量html片段let prevRenderHtml p**p;// 上一次打印到頁(yè)面上的html片段// 頁(yè)面上會(huì)渲染 **// 當(dāng)服務(wù)端繼續(xù)下發(fā)了 ** 的markdown文本時(shí)curIndex會(huì)遞增1變?yōu)?let curMarkdown **hello**;// 當(dāng)前打印時(shí)的全量markdown文本let curHtml pstronghello/strong/p;// 當(dāng)前打印時(shí)的全量html片段let curRenderHtml pstrong/strongp;// 當(dāng)前打印到頁(yè)面上的html片段// 頁(yè)面上會(huì)渲染空標(biāo)簽然后重新開始打字尤其是在數(shù)學(xué)公式場(chǎng)景中非常容易復(fù)現(xiàn)解決方案解決這個(gè)問(wèn)題需要分兩步走。首先需要判斷打印到頁(yè)面上的html片段是否有變化因?yàn)橹挥凶兓瘯r(shí)才會(huì)出現(xiàn)這種情況而判斷是否有變化只需要記錄一下上一次的html片段和這一次的html片段是否不同即可比較好處理。其次就是需要重新定位下標(biāo)到上一次打印到的位置這里相對(duì)比較難處理因?yàn)閔tml的結(jié)構(gòu)和內(nèi)容都在變化很難準(zhǔn)確的定位到下標(biāo)應(yīng)該移動(dòng)到什么位置。雖然我們不能準(zhǔn)確定位但是只要能夠使當(dāng)前打印到頁(yè)面上的字符比上一次的字符多就可以滿足訴求了。于是我想到了textContent這個(gè)屬性它可以獲取當(dāng)前節(jié)點(diǎn)及其后代的所有文本內(nèi)容。那么問(wèn)題就轉(zhuǎn)化為找到一個(gè)下標(biāo)使得當(dāng)前截取的html片段的textContent長(zhǎng)度要比上一次的textContent長(zhǎng)度大。綜上所述可以得到核心代碼如下所示。if (this.isHtmlChanged()) {let domRange: any document.createRange();let prevFrag domRange.createContextualFragment(this.prevRenderHtml);let prevTextContent prevFrag.textContent;let diffNum 1;do {this.curIndex diffNum;let curHtml this.rawHtml.substring(0, this.curIndex);let curFrag domRange.createContextualFragment(curHtml);let curTextContent curFrag.textContent;diffNum prevTextContent.length - curTextContent.length;if (diffNum 0) {break;}} while (this.curIndex this.rawHtml.length);}5.4 小結(jié)通過(guò)現(xiàn)代前端框架構(gòu)建打字機(jī)組件不僅減少了不必要的渲染和性能消耗而且還能高效靈活的穿插各種酷炫的樣式效果實(shí)現(xiàn)更多復(fù)雜的產(chǎn)品功能。六、未來(lái)展望本文詳細(xì)介紹了AI搜索中前端打字機(jī)效果的實(shí)現(xiàn)方案演進(jìn)過(guò)程從最初的純文本逐字符打字效果到借助現(xiàn)代前端框架實(shí)現(xiàn)靈活可復(fù)用的打字機(jī)組件每一個(gè)技術(shù)難點(diǎn)的技術(shù)突破無(wú)不體現(xiàn)了前端技術(shù)的持續(xù)進(jìn)步和產(chǎn)品不斷追求卓越的態(tài)度。同時(shí)我也希望本文可以拋磚引玉為讀者打開思路提供借鑒。隨著人工智能和前端技術(shù)的不斷發(fā)展和創(chuàng)新生態(tài)的日益完善未來(lái)一定會(huì)不斷涌現(xiàn)大量的新技術(shù)和新理念。我相信只要時(shí)刻保持積極學(xué)習(xí)和不斷嘗試的探索精神就能開拓出更多精彩創(chuàng)新的實(shí)現(xiàn)方案和應(yīng)用場(chǎng)景。
版權(quán)聲明: 本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)聯(lián)系我們進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

php網(wǎng)站開發(fā)師網(wǎng)站建設(shè)人員組織

php網(wǎng)站開發(fā)師,網(wǎng)站建設(shè)人員組織,河北石家莊網(wǎng)絡(luò)公司,立網(wǎng)站系釘釘自動(dòng)打卡完整教程#xff1a;3步告別遲到煩惱 【免費(fèi)下載鏈接】AutoDingding 釘釘自動(dòng)打卡 項(xiàng)目地址: https:

2026/01/23 00:50:01

興化網(wǎng)站制作免費(fèi)咨詢男科

興化網(wǎng)站制作,免費(fèi)咨詢男科,wordpress本地mp3,蘇州好的做網(wǎng)站的公司有哪些GetQzonehistory完整指南#xff1a;5步輕松備份你的QQ空間記憶 【免費(fèi)下載鏈接】GetQzoneh

2026/01/23 06:30:01

公司網(wǎng)站公眾號(hào)維護(hù)怎么做我想做個(gè)網(wǎng)站找誰(shuí)做

公司網(wǎng)站公眾號(hào)維護(hù)怎么做,我想做個(gè)網(wǎng)站找誰(shuí)做,網(wǎng)站優(yōu)化師負(fù)責(zé)干什么,網(wǎng)站系統(tǒng)說(shuō)明如果你是那個(gè)正在深夜對(duì)著空白文檔發(fā)呆、焦慮查重費(fèi)用、擔(dān)心AI痕跡被導(dǎo)師發(fā)現(xiàn)的畢業(yè)生#xff0c;那么這篇文章就是為你準(zhǔn)備

2026/01/23 10:43:01

電大企業(yè)網(wǎng)站建設(shè)論文范文云南網(wǎng)架加工

電大企業(yè)網(wǎng)站建設(shè)論文范文,云南網(wǎng)架加工,云南工程建設(shè)投標(biāo)網(wǎng)上報(bào)名網(wǎng)站,新浪網(wǎng) 網(wǎng)站建設(shè)GORM 本身不封裝“存儲(chǔ)過(guò)程”概念#xff0c;但可以直接拿 *gorm.DB 當(dāng)原生 SQL 執(zhí)行器用#xff

2026/01/23 05:42:01