Frontend Development 8 min read

Implementing Download Interception, Search, Tab Management, and Drag‑Drop Features in an Electron‑Based Browser

This article details how to build a lightweight Electron browser by assembling webview components, covering download interception, in‑page search, custom tab handling, address‑bar logic, and draggable desktop icons, with full code examples and implementation notes.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Implementing Download Interception, Search, Tab Management, and Drag‑Drop Features in an Electron‑Based Browser

Using Electron combined with a webview allows rapid assembly of a custom browser where the primary goal is to produce a functional product for personal use.

Download Interception Feature

The download logic replaces the typical web popup with a native‑like downloader by listening to the will-download event on the BrowserWindow's session and forwarding progress updates to the renderer process.

global.WIN.webContents.session.on('will-download', (evt, item) => {
  // other logic
  item.on('updated', (evt, state) => {
    // send real‑time progress to renderer
  })
})

Page Search Feature

Electron's webview provides built‑in find‑in‑page capabilities; the UI simply triggers the search box and leverages findInPage and stopFindInPage for keyword highlighting and navigation.

function toSearch() {
  let timer
  return () => {
    if (timer) { clearTimeout(timer) }
    timer = setTimeout(() => {
      if (keyword.value) {
        webviewRef.value.findInPage(keyword.value, { findNext: true })
      } else {
        webviewRef.value.stopFindInPage('clearSelection')
      }
    }, 200)
  }
}
function closeSearch() { showSearch.value = false; webviewRef.value.stopFindInPage('clearSelection') }
function installFindPage(webview) { /* attach found‑in‑page listener */ }

Current Tab Opening Feature

To prevent new windows from opening, the app intercepts the new-window disposition, sends the URL to the existing webview, and denies the default action.

app.on('web-contents-created', (event, contents) => {
  contents.setWindowOpenHandler(info => {
    global.WIN?.webContents.send('webview-url-is-change')
    if (info.disposition === 'new-window') {
      return { action: 'allow' }
    } else {
      global.WIN?.webContents.send('webview-open-url', info.url)
      return { action: 'deny' }
    }
  })
})
ipcRenderer.on('webview-open-url', (event, url) => {
  try {
    const reg = /http|https/g
    if (webviewRef.value && reg.test(url)) { webviewRef.value.src = url }
  } catch (err) { console.log(err) }
})

Tab Switching Feature

Tab switching is achieved by toggling CSS visibility and leveraging Vue Router to manage the displayed component.

Address Bar Functionality

The address bar supports direct URL navigation, quick access to bookmarked sites, and keyword search, prioritizing bookmarks, then URLs, then search queries.

function toSearch(keyword) {
  if (`${keyword}`.length === 0) return false
  // app search
  if (`${keyword}`.length < 20) {
    // lookup in bookmark lists
  }
  // URL navigation
  if (isUrl(keyword)) {
    let url = /^https?:\/\//i.test(keyword) ? keyword : 'http://' + keyword
    goAppNewTab(url)
    return false
  }
  // keyword search
  let searchEngine = localStorage.getItem('searchEngine') || CONFIG.searchEngine
  url = searchEngine + keyword
  if (!router.hasRoute('search')) {
    router.addRoute({ name: 'search', path: '/search', meta: { title: '搜索', icon: 'search.svg' }, component: WebView })
    keepAliveInclude.value.push('search')
  }
  router.push({ path: '/search', query: { url } })
  setTimeout(() => Bus.$emit('toSearch', url), 20)
}

Desktop Icon Drag‑and‑Drop

Because the browser window can be resized, a fixed‑size central area is used for desktop icons; drag‑enter, drag‑over, drag‑leave, and drop events update icon coordinates.

// background grid
// drag logic (Vue composition API)
import { ref, computed } from 'vue'
export default function useDrag() {
  const dragging = ref(null)
  const currentTarget = ref()
  const desk = useDesk()
  const { deskList } = storeToRefs(desk)
  const { setDeskList, updateDeskData } = desk
  function start(e, item) { e.target.classList.add('dragging'); e.dataTransfer.effectAllowed = 'move'; dragging.value = item; currentTarget.value = e }
  function end(e) { dragging.value = null; e.target.classList.remove('dragging'); setDeskList(deskList.value); clearTimeout(timer2); timer2 = setTimeout(() => updateDeskData(), 2000) }
  // ...enter, leave, over, drop implementations
  return { start, end, over, enter, leave, drop }
}

Installation Package

The source code is available at https://github.com/jddk/aweb-browser.git ; binaries can be downloaded from the official site or Microsoft Store, with the macOS build pending due to size constraints.

JavaScriptElectronWebViewVuesearchdownloadTab Management
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.