Replace the dangling text prompt for the title attribute with native JS

background

When you want a DOM element to appear as a floating text alert, you add the title attribute to the element

<div title="Surprise is me. Surprise or no surprise?">Mouse over my body has a surprise</div>
Copy the code

The suspended text prompt of the title attribute varies with browsers. The suspended waiting time and the style of the suspended text may be different. For example, on Chrome, the suspended text may be gray on a white background, while on Firefox, it may be black on a yellow background, and the duration may be 3s or 1s.

To ensure a consistent user experience across browsers, we need to disable the default title property and use JS to manually implement the dangling text prompt.

The most important thing is that the suspension time is too long to display, to 3 seconds is very uncomfortable

Implementation principle steps

  1. First we need to know that the DOM load is complete on the page
  2. Also be aware that dynamically rendered DOM loads are complete (using the MutationObserver interface provides the ability to monitor changes made to the DOM tree)
  3. Gets all elements with the title attribute
  4. Listen for the mouseEnter event for the corresponding element
  5. Write style replaces the native title hover effect

The specific implementation code is as follows:

// Use custom dangling text prompt instead of native title attribute, use addEventListner for event binding, incompatible with IE 6, 7, 8
let titleTools = {
  init(time) {
    time = parseInt(time)
    if (!isNaN(time) && time >= 0) {
      this.timeout = time
    } else {
      console.warn(`param ${time} is not a number or out of range! using default timeout setting`)}// Select all nodes with the title attribute
    let eles = document.querySelectorAll('*[title]')
    for (let i = 0; i < eles.length; i++) {
      // Hide the original title attribute and use js control
      if (eles[i].title) {
        eles[i].dataset.title = eles[i].title
        eles[i].title = ' '
      }
      // Bind the function
      eles[i].timeoutms = this.timeout
      eles[i].addEventListener('mousemove'.this.title)
      eles[i].addEventListener('mouseleave'.this.clear)
      eles[i].leaveAction = this.clear
    }
  },
  // Delay text display
  timeout: 500.// The function that displays the prompt text is bound to mousemove
  title(e) {
    clearTimeout(this.timer)
    const that = this
    that.removeEventListener('mousemove'.this.leaveAction)
    this.timer = setTimeout(() = > {
      let div = document.createElement('div')
      div.innerHTML = that.dataset.title
      div.style.cssText = `display:inline-block; border-radius: 2px; padding: 0 5px; The line - height: 1.3; color:#000; background:#fff; font-size:13px; box-shadow: 0 0 6px #ccc; position:fixed; left:${e.clientX}px;
                            top:${e.clientY}px;
                            z-index:999`
      document.body.appendChild(div)
      that.titleElement = div
      that.addEventListener('mousemove', that.leaveAction)
    }, this.timeoutms)
  },
  // Clear text prompt box function, bound to mousemove and mouseleave
  clear(e) {
    clearTimeout(this.timer)
    let div = this.titleElement
    if (div && div.parentNode) {
      div.parentNode.removeChild(div)
    }
  }
}

// Select the nodes that need to be observed to change
const targetNode = document.getElementById('root')

// Observer configuration (what changes need to be observed)
const config = {
  childList: true.// Observe the change of the target child node, whether it is added or deleted
  attributes: true.// Observe property changes
  subtree: true     // Observe descendant nodes, default is false
}

// The callback function that is executed when changes are observed
const callback = function(mutationsList, observer) {
  // Use traditional 'for loops' for IE 11
  titleTools.init(500)}// Create an observer instance and pass in the callback function
const observer = new MutationObserver(callback)

// Observe the target node from the above configuration
observer.observe(targetNode, config)
Copy the code

The actual effect is shown below:

See article: Use native JS to replace title property with floating text prompt – customizable style and occurrence time – simple implementation