日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

keras 香草编码器_完善纯香草javascript中的拖放

發布時間:2025/3/19 javascript 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 keras 香草编码器_完善纯香草javascript中的拖放 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

keras 香草編碼器

Drag-and-drop functionality is the bread and butter of a modern web UX. It’s an aspect of the API, part of the HTML standard. Lots of UI libraries provide it out of box.

拖放功能是現代Web UX的基礎。 這是API的一個方面 ,是HTML標準的一部分。 許多UI庫都是開箱即用的。

Sometimes, though, we have to deal with situations where neither the standard API nor the libraries can help, and we have to implement the functionality ourselves. In this article we’ll do exactly that—we’ll implement:

但是,有時候,我們必須處理標準API和庫都無法提供幫助的情況,而我們必須自己實現功能。 在本文中,我們將完全做到這一點-我們將實現:

  • Cross-input (with blended mouse and touch-events support)

    交叉輸入(具有混合的鼠標和觸摸事件支持)
  • Cross-browser friendly

    跨瀏覽器友好
  • Performant (60 FPS)

    性能(60 FPS)
  • Efficient (no wasted JavaScript processing)

    高效(不浪費JavaScript處理)

1.先決條件 (1. Prerequisites)

For the sake of this article, we’re going to be dragging a few black square boxes (divs) around a container (div) element in a simple HTML page:

為了本文的目的,我們將在一個簡單HTML頁面中的容器(div)元素周圍拖動幾個黑色方框(divs):

<div class="container"><div style="top: 100px; left: 100px" class="box"></div><div style="top: 200px; left: 200px" class="box"></div><div style="top: 300px; left: 300px" class="box"></div><div style="top: 400px; left: 400px" class="box"></div> </div>.container {width: 600px;height: 600px;background-color: darkgrey;touch-action: none; } .box {position: absolute;width: 100px;height: 100px;background-color: black; }

Nothing fancy here, but note we’re applying the touch-action: none; CSS rule to prevent any browser level manipulations (such as scroll or zoom) for events inside the container.

這里沒什么好看的,但請注意,我們正在應用touch-action: none; CSS規則 ,可防止對容器內的事件進行任何瀏覽器級別的操作(例如,滾動或縮放)。

2.添加輸入監聽器 (2. Adding Input Listeners)

Pointer events provide the blender supporting both input types指針事件提供了支持兩種輸入類型的混合器

Since we want to support cross-input, we could write some detection mechanism for whether the user is using touch input or mouse input, but in the modern world, the user might be using both input types at the same time (touchscreen laptop, anyone?).

因為我們要支持交叉輸入,所以我們可以編寫一些檢測機制來確定用戶是使用觸摸輸入還是鼠標輸入,但是在現代世界中,用戶可能同時使用兩種輸入類型 (觸摸屏筆記本電腦,有人嗎?)。

Hence, we should aim to support both. One way would be to attach both types of listeners, but a better way is to leverage the Pointer Events API — the blender of two input types that nowadays has decent support by all of the major browsers.

因此,我們應該努力支持兩者。 一種方法是連接兩種類型的偵聽器,但更好的方法是利用Pointer Events API-兩種輸入類型的混合器,如今,所有主要瀏覽器都提供了不錯的支持。

Our drag-and-drop user experience can be mapped this way:

可以通過以下方式映射我們的拖放式用戶體驗:

  • User points at a box, presses the mouse button/screen (pointerdown)

    用戶指向一個框,按下鼠標按鈕/屏幕( pointerdown )

  • User drags the box by moving the mouse/their finger across the screen (pointermove)

    用戶通過在屏幕上移動鼠標/手指來拖動框( pointermove )

  • User drops the box by releasing the mouse/their finger from the screen (pointerup/pointercancel*)

    用戶通過從屏幕上釋放鼠標/手指來pointerup pointercancel ( pointerup / pointercancel *)

*Touch devices feature an additional touchcancel event — for the cases when the touch event gets disrupted (for example, when there are too many touch points on the screen).

*觸摸設備還具有一個附加的touchcancel事件-在觸摸事件中斷的情況下(例如,當屏幕上的觸摸點過多時)。

So let’s write some JavaScript and add our event listeners:

因此,讓我們編寫一些JavaScript并添加事件監聽器:

const container = document.querySelector('.container'); container.addEventListener('pointerdown', userPressed, { passive: true });function userPressed(event) {element = event.target;if (element.classList.contains('box')) {console.log("pick up!")container.addEventListener('pointermove', userMoved, { passive: true });container.addEventListener('pointerup', userReleased, { passive: true });container.addEventListener('pointercancel', userReleased, { passive: true });}; };function userMoved(event) {console.log("dragging!") };function userReleased(event) {console.log("dropped!")container.removeEventListener('pointermove', userMoved);container.removeEventListener('pointerup', userReleased);container.removeEventListener('pointercancel', userReleased); };

一些注意事項 (A few notes)

  • We’re only attaching the pointerdown event to the container and adding/removing other listeners dynamically to prevent event pollution — we’re using listeners on an as-needed basis, keeping things tight.

    我們只是將pointerdown事件附加到容器上,并動態添加/刪除其他偵聽器以防止事件污染—我們在需要時使用偵聽器,以保持緊密狀態。

  • The events are attached to the container, as we’re using event delegation.

    事件被附加到容器,因為我們正在使用事件委托 。

  • We’re also using the passive flag to ensure our events don’t interfere with our scrolling events.

    我們還使用passive標志來確保事件不會干擾滾動事件。

3.使盒子移動 (3. Making Boxes Move)

Our boxes feature absolute positioning and rely on left/top properties to be positioned inside of the container. Let’s add functionality to actually move the boxes around:

我們的盒子具有absolute定位功能,并依靠left / top屬性在容器內部定位。 讓我們添加功能以實際移動框:

const container = document.querySelector('.container'); container.addEventListener('pointerdown', userPressed, { passive: true });var element, bbox, startX, startY;function userPressed(event) {element = event.target;if (element.classList.contains('box')) {startX = event.clientX;startY = event.clientY;bbox = element.getBoundingClientRect();container.addEventListener('pointermove', userMoved, { passive: true });container.addEventListener('pointerup', userReleased, { passive: true });container.addEventListener('pointercancel', userReleased, { passive: true });}; };function userMoved(event) {let deltaX = event.clientX - startX;let deltaY = event.clientY - startY;element.style.left = bbox.left + deltaX + "px";element.style.top = bbox.top + deltaY + "px"; };function userReleased(event) {container.removeEventListener('pointermove', userMoved);container.removeEventListener('pointerup', userReleased);container.removeEventListener('pointercancel', userReleased); };

There are now more things going on here:

現在,這里還有更多事情要做:

  • Inside the userPressed event handler, we capture the coordinates of the starting point for the movement as well as the box element’s BoundingClientRect; both will help to calculate the amount of movement we need to apply to the box based on the pointer’s distance covered during the move.

    在userPressed事件處理程序內部,我們捕獲了運動起點的坐標以及box元素的BoundingClientRect ; 兩者都將有助于根據移動過程中指針所經過的距離來計算我們需要應用于框的移動量。

  • Inside the userMoved handler, we leverage startX and startY data to calculate the delta for which the box should visually move in relation to its previous position.

    在userMoved處理程序內部,我們利用startX和startY數據來計算框應相對于其先前位置在視覺上移動的delta 。

Now the user can, in fact, move the boxes and do so using touch or mouse input.

現在,用戶實際上可以移動盒子并使用觸摸或鼠標輸入進行移動。

4.調優性能 (4. Tuning Performance)

There are a few known approaches we can take to improve performance. In this simplistic case, we don’t perform any heavy calculations; hence, even as is the performance looks fine. But we can consider the following options:

我們可以采取幾種已知的方法來提高性能。 在這種簡單的情況下,我們不執行任何繁重的計算; 因此,即使性能看起來也不錯。 但是我們可以考慮以下選擇:

'transform3d' (‘transform3d’)

This trick might be out of date nowadays, as modern browsers learned to optimize for layout changes, but it’s still useful to know that instead of directly modifying our box’s left and top positions, we could apply transform during pointermove and only apply actual style changes on pointerup:

由于現代瀏覽器已學會優化布局更改,因此這種技巧可能已不合時宜,但了解而不是直接修改框的left和top位置,我們可以在pointermove期間應用transform并僅對pointerup :

const container = document.querySelector('.container'); container.addEventListener('pointerdown', userPressed, { passive: true });var element, bbox, startX, startY, deltaX, deltaY;function userPressed(event) {element = event.target;if (element.classList.contains('box')) {startX = event.clientX;startY = event.clientY;bbox = element.getBoundingClientRect();container.addEventListener('pointermove', userMoved, { passive: true });container.addEventListener('pointerup', userReleased, { passive: true });container.addEventListener('pointercancel', userReleased, { passive: true });}; };function userMoved(event) {deltaX = event.clientX - startX;deltaY = event.clientY - startY;element.style.transform = "translate3d("+deltaX+"px,"+deltaY+"px, 0px)"; };function userReleased(event) {container.removeEventListener('pointermove', userMoved);container.removeEventListener('pointerup', userReleased);container.removeEventListener('pointercancel', userReleased);element.style.left = bbox.left + deltaX + "px";element.style.top = bbox.top + deltaY + "px";element.style.transform = "translate3d(0px,0px,0px)"; };

'RequestAnimationFrame' (‘RequestAnimationFrame’)

We can also achieve smoother animation while dragging (~60 FPS) through the use of the requestAnimationFrame API:

通過使用requestAnimationFrame API,我們還可以在拖動(?60 FPS)的同時實現更流暢的動畫:

const container = document.querySelector('.container'); container.addEventListener('pointerdown', userPressed, { passive: true });var element, bbox, startX, startY, deltaX, deltaY, raf;function userPressed(event) {element = event.target;if (element.classList.contains('box')) {startX = event.clientX;startY = event.clientY;bbox = element.getBoundingClientRect();container.addEventListener('pointermove', userMoved, { passive: true });container.addEventListener('pointerup', userReleased, { passive: true });container.addEventListener('pointercancel', userReleased, { passive: true });}; };function userMoved(event) {// if no previous request for animation frame - we allow js to proccess 'move' event:if (!raf) {deltaX = event.clientX - startX;deltaY = event.clientY - startY;raf = requestAnimationFrame(userMovedRaf);} };function userMovedRaf() {element.style.transform = "translate3d("+deltaX+"px,"+deltaY+"px, 0px)";// once the paint job is done we 'release' animation frame variable to allow next paint job:raf = null; };function userReleased(event) {container.removeEventListener('pointermove', userMoved);container.removeEventListener('pointerup', userReleased);container.removeEventListener('pointercancel', userReleased);// if animation frame was scheduled but the user already stopped interaction - we cancel the scheduled frame:if (raf) {cancelAnimationFrame(raf);raf = null;};element.style.left = bbox.left + deltaX + "px";element.style.top = bbox.top + deltaY + "px";element.style.transform = "translate3d(0px,0px,0px)"; };

這里有幾點注意事項 (A few notes here)

  • We added the raf variable to helps us debounce pointermove events with help from the requestAnimationFrame timer, as we don’t want JavaScript to perform calculations that won’t be used since the animation frame was already scheduled and hasn’t yet completed.

    我們添加了raf變量,以幫助我們在requestAnimationFrame計時器的幫助下對pointermove事件進行反跳,因為我們不希望JavaScript執行由于已經安排好動畫框架且尚未完成而不會使用的計算。

  • We made sure the pointermove event, which fires many times per second, is lightweight and only contains the logic necessary to obtain the coordinates information and triggers the style change.

    我們確保了pointermove觸發多次的pointermove事件是輕量級的,并且僅包含獲取坐標信息并觸發樣式更改所需的邏輯。

3. CSS規則:“將改變”和“包含” (3. CSS Rules: ‘will-change’ and ‘contain’)

In addition to the above, there are CSS rules that you could explore to tune performance further.

除了上述內容,您還可以探索CSS規則來進一步調整性能。

The will-change CSS rule indicates to your browser the element’s attributes are expected to change and allows the browser to perform additional optimizations. But as the documentation says — use it with caution:

的 will-change CSS規則指示瀏覽器元素的屬性都有望改變,并允許瀏覽器執行額外的優化。 但正如文檔所述,請謹慎使用:

“Important: will-change is intended to be used as a last resort, in order to try to deal with existing performance problems. It should not be used to anticipate performance problems.”

“重要: will-change是不得已的手段,目的是試圖解決現有的績效問題。 它不應該被用來預測性能問題。”

.box {position: absolute;width: 100px;height: 100px;background-color: black;will-change: transform, left, top;contain: layout; }

The contain CSS rule isn’t fully supported by all browsers yet but can help indicate that a particular DOM’s element style or layout changes won’t affect another page’s elements and thus won’t trigger potential expensive reflows.

在 contain CSS規則沒有完全被所有的瀏覽器,但還可以幫助支持表示一個特定的DOM的元素風格或布局的變化不會影響其他頁面的元素,因而不會觸發潛在的昂貴的回流。

It isn’t really adding any value in our simplistic case (given that our boxes are positioned as absolute, but it’s a useful trick in more complex UI and dragging situations. You can watch this amazing video for more details.

在我們的簡單案例中,它并沒有真正增加任何價值(假設我們的盒子定位為absolute ,但這在更復雜的UI和拖動情況下是一個有用的技巧。您可以觀看此精彩視頻 ,了解更多詳細信息。

結論 (Conclusion)

We went through the basics of how drag-and-drop functionality can be implemented in pure JavaScript, and we outlined a few techniques and directions for performance optimization. The main things to remember:

我們介紹了如何在純JavaScript中實現拖放功能的基礎知識,并概述了一些性能優化的技術和方向。 要記住的主要事項:

  • Leverage blended input events to ensure hybrid devices are covered.

    利用混合輸入事件來確保涵蓋混合設備。
  • Attach/detach move/up/cancel events dynamically.

    動態附加/分離move / up / cancel事件。

  • Do as much of the heavy weight lifting upfront or inside the down and up handlers, but keep the move handler lightweight.

    做盡可能多的重型舉重前期的或內部down和up處理程序,但保持move處理器輕巧。

  • Leverage requestAnimationFrame for debouncing and smooth animation while dragging.

    利用requestAnimationFrame在拖動時進行反跳和平滑動畫處理。

  • Explore CSS rules that can help gain additional performance.

    探索有助于提高性能CSS規則。

Full implementation here:

完整的實現在這里:

演示地址

Thank you for reading the article, and happy coding!

感謝您閱讀本文,并祝您編程愉快!

翻譯自: https://medium.com/better-programming/perfecting-drag-and-drop-in-pure-vanilla-javascript-a761184b797a

keras 香草編碼器

總結

以上是生活随笔為你收集整理的keras 香草编码器_完善纯香草javascript中的拖放的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 狂野欧美性猛交免费视频 | 91色多多| 日韩六区 | 免费观看日韩 | 亚洲中文字幕无码专区 | 欧美日韩国产精品 | 丰满人妻一区二区三区在线 | 久久爱成人 | 在线一区二区三区四区 | 日韩毛片一级 | 欧美乱日| 黄频在线播放 | 97免费观看视频 | 91精选视频 | 黄av网 | 伊人久久五月天 | 黄色录像毛片 | 欧美草b| 久久av红桃一区二区小说 | 国产精品久久久久久久久免费看 | 日韩精品亚洲一区 | 夜夜嗨av一区二区三区免费区 | 婷婷丁香六月天 | 成人午夜视频在线观看 | 成人在线免费小视频 | 天天综合网久久综合网 | 午夜精品久久久内射近拍高清 | 最新av观看 | 国产极品美女在线 | 日本三级456 | 67194在线免费观看 | 一本久久精品一区二区 | 在线国产一区 | 久久夜色精品国产欧美乱极品 | 在线观看成人免费视频 | 91国内精品久久久久 | 国产私人影院 | 中文字幕av无码一区二区三区 | 日韩av福利 | 日本国产精品一区 | 中文字字幕在线中文乱码 | 草草影院欧美 | 欧美肉丝袜videos办公室 | 国产精品男女 | 欧美另类色图 | 少妇无套内谢久久久久 | 女人18毛片水真多18精品 | 91老司机在线 | 日本精品成人 | 成人在线免费小视频 | 国精产品一区一区三区在线 | 久久久久久久久久免费 | 北条麻妃一区二区三区四区五区 | 精品国产乱码一区二区三区99 | aaa亚洲 | 中文字幕一区二区在线观看视频 | 国产第一精品 | 天堂色播 | 亚洲综合在线成人 | 久久三级精品 | 亚洲av无码一区二区三区人 | 国产综合在线观看视频 | 美女黄视频大全 | 久操久热| 极品少妇网站 | 肉嫁高柳在线 | 国产黄色网页 | 香蕉成人在线视频 | av综合久久 | 一边顶弄一边接吻 | 亚洲专区视频 | 中文精品无码中文字幕无码专区 | 日本高清不卡码 | 日本欧美久久久久免费播放网 | 免费在线不卡视频 | 免费禁漫天堂a3d | 无码av免费毛片一区二区 | 人人草人人爱 | 成人在线观看亚洲 | 中国字幕一色哟哟 | 成人先锋av | 69网站在线观看 | 国产精品久久二区 | 国产亚洲网站 | aa一级片 | 一二三区精品视频 | 欧美成人高清 | 快射视频在线观看 | 亚洲一区二区三区四区五区午夜 | 成年人天堂 | 超色视频| 欧美人与禽猛交乱配视频 | av手机免费看 | 深夜国产福利 | 精品中文字幕在线播放 | 亚洲视频456 | 日韩在线观看视频一区二区 | 久久先锋| 免费大片av |