浏览代码

Improving performance.
Using debounce function
Using vanilla js to do some verification

djhvscf 4 年之前
父节点
当前提交
a452b872b4

+ 22 - 31
src/extensions/filter-control/bootstrap-table-filter-control.js

@@ -56,6 +56,7 @@ $.extend($.fn.bootstrapTable.defaults, {
   // internal variables
   _valuesFilterControl: [],
   _initialized: false,
+  _isRendering: false,
   _usingMultipleSelect: false
 })
 
@@ -122,48 +123,37 @@ $.BootstrapTable = class extends $.BootstrapTable {
       this._valuesFilterControl = []
       this._initialized = false
       this._usingMultipleSelect = false
+      this._isRendering = false
 
       this.$el
-        .on('reset-view.bs.table', () => {
-          setTimeout(() => {
-            UtilsFilterControl.initFilterSelectControls(this)
-            UtilsFilterControl.setValues(this)
-          }, 2)
-        })
-        .on('toggle.bs.table', (_, cardView) => {
+        .on('reset-view.bs.table', Utils.debounce(() => {
+          UtilsFilterControl.initFilterSelectControls(this)
+          UtilsFilterControl.setValues(this)
+        }, 3))
+        .on('toggle.bs.table', Utils.debounce((_, cardView) => {
           this._initialized = false
           if (!cardView) {
             UtilsFilterControl.initFilterSelectControls(this)
             UtilsFilterControl.setValues(this)
             this._initialized = true
           }
-        })
-        .on('post-header.bs.table', () => {
-          setTimeout(() => {
-            UtilsFilterControl.initFilterSelectControls(this)
-            UtilsFilterControl.setValues(this)
-            setTimeout(() => {
-              const container = UtilsFilterControl.getControlContainer(this)
-              const multipleSelects = container.find('.fc-multipleselect')
-
-              if (multipleSelects.length > 0 && $.fn.multipleSelect) {
-                multipleSelects.multipleSelect('destroy').multipleSelect(this.options.filterControlMultipleSelectOptions)
-              }
-            }, 2)
-          }, 2)
-        })
-        .on('column-switch.bs.table', () => {
+        }, 1))
+        .on('post-header.bs.table', Utils.debounce(() => {
+          UtilsFilterControl.initFilterSelectControls(this)
+          UtilsFilterControl.setValues(this)
+        }, 3))
+        .on('column-switch.bs.table', Utils.debounce(() => {
           UtilsFilterControl.setValues(this)
           if (this.options.height) {
             this.fitHeader()
           }
-        })
-        .on('post-body.bs.table', () => {
+        }, 1))
+        .on('post-body.bs.table', Utils.debounce(() => {
           if (this.options.height && !this.options.filterControlContainer && this.options.filterControlVisible) {
             UtilsFilterControl.fixHeaderCSS(this)
           }
           this.$tableLoading.css('top', this.$header.outerHeight() + 1)
-        })
+        }, 1))
         .on('all.bs.table', () => {
           UtilsFilterControl.syncHeaders(this)
         })
@@ -175,12 +165,13 @@ $.BootstrapTable = class extends $.BootstrapTable {
 
   initBody () {
     super.initBody()
-    if (this.options.filterControl) {
-      setTimeout(() => {
-        UtilsFilterControl.initFilterSelectControls(this)
-        UtilsFilterControl.setValues(this)
-      }, 3)
+    if (!this.options.filterControl) {
+      return
     }
+    setTimeout(() => {
+      UtilsFilterControl.initFilterSelectControls(this)
+      UtilsFilterControl.setValues(this)
+    }, 3)
   }
 
   load (data) {

+ 30 - 22
src/extensions/filter-control/utils.js

@@ -7,7 +7,7 @@ export function getFormControlClass (options) {
 }
 
 export function getOptionsFromSelectControl (selectControl) {
-  return selectControl.get(selectControl.length - 1).options
+  return selectControl[0].options
 }
 
 export function getControlContainer (that) {
@@ -63,34 +63,42 @@ export function addOptionToSelectControl (selectControl, _value, text, selected)
 
   value = value.replace(/(<([^>]+)>)/ig, '').replace(/&[#A-Za-z0-9]+;/gi, '').trim()
 
-  // Double check if the select control is a jquery object.
-  if (!(selectControl instanceof jQuery)) {
-    throw new Error ('SelectControl is not a jQuery instance.')
+  if (existOptionInSelectControl(selectControl, value)) {
+    return
   }
 
-  if (!existOptionInSelectControl(selectControl, value)) {
-    const option = $(`<option value="${value}">${text}</option>`)
-
-    if (value === selected) {
-      option.attr('selected', true)
-    }
+  const option = new Option(text, value, false, value === selected)
 
-    selectControl.append(option)
-  }
+  selectControl.get(0).add(option)
 }
 
 export function sortSelectControl (selectControl, orderBy) {
-  const $selectControl = $(selectControl.get(selectControl.length - 1))
-  const $opts = $selectControl.find('option:gt(0)')
+  const $selectControl = selectControl.get(0)
 
-  if (orderBy !== 'server') {
-    $opts.sort((a, b) => {
-      return Utils.sort(a.textContent, b.textContent, orderBy === 'desc' ? -1 : 1)
-    })
+  if (orderBy === 'server') {
+    return
+  }
+
+  const tmpAry = new Array()
+
+  for (let i = 0; i < $selectControl.options.length; i++) {
+    tmpAry[i] = new Array()
+    tmpAry[i][0] = $selectControl.options[i].text
+    tmpAry[i][1] = $selectControl.options[i].value
   }
 
-  $selectControl.find('option:gt(0)').remove()
-  $selectControl.append($opts)
+  tmpAry.sort((a, b) => {
+    return Utils.sort(a[0], b[0], orderBy === 'desc' ? -1 : 1)
+  })
+  while ($selectControl.options.length > 0) {
+    $selectControl.options[0] = null
+  }
+
+  for (let i = 0; i < tmpAry.length; i++) {
+    const op = new Option(tmpAry[i][0], tmpAry[i][1])
+
+    $selectControl.add(op)
+  }
 }
 
 export function fixHeaderCSS ({ $tableHeader }, pixels = '89px') {
@@ -280,7 +288,7 @@ export function initFilterSelectControls (that) {
     if (isColumnSearchableViaSelect(column) && isFilterDataNotGiven(column) && hasSelectControlElement(selectControl)) {
       if (!selectControl[0].multiple && selectControl.get(selectControl.length - 1).options.length === 0) {
         // Added the default option, must use a non-breaking space(&nbsp;) to pass the W3C validator
-        addOptionToSelectControl(selectControl, '', column.filterControlPlaceholder || '&nbsp;', column.filterDefault)
+        addOptionToSelectControl(selectControl, '', column.filterControlPlaceholder || ' ', column.filterDefault)
       }
 
       const uniqueValues = {}
@@ -313,7 +321,7 @@ export function initFilterSelectControls (that) {
         }
       }
 
-      sortSelectControl(selectControl, column.filterOrderBy)
+      // sortSelectControl(selectControl, column.filterOrderBy)
       if (that.options.hideUnusedSelectOptions) {
         hideUnusedSelectOptions(selectControl, uniqueValues)
       }

+ 22 - 0
src/utils/index.js

@@ -394,5 +394,27 @@ export default {
       return arg
     }
     return $.extend(true, Array.isArray(arg) ? [] : {}, arg)
+  },
+
+  debounce (func, wait, immediate) {
+    let timeout
+
+    return function executedFunction () {
+      const context = this
+      const args = arguments
+
+      const later = function () {
+        timeout = null
+        if (!immediate) func.apply(context, args)
+      }
+
+      const callNow = immediate && !timeout
+
+      clearTimeout(timeout)
+
+      timeout = setTimeout(later, wait)
+
+      if (callNow) func.apply(context, args)
+    }
   }
 }