原生JS实现的DOM操作笔记(草稿整理)

Posted 风雨后见彩虹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原生JS实现的DOM操作笔记(草稿整理)相关的知识,希望对你有一定的参考价值。

原生JS实现的DOM一系列操作参考:

代码如下:

var dom = {
    
    /** 功能说明:匹配元素是否含有指定class
     * @param el 指定的DOM元素
     * @param className 匹配的class名
     * */
    hasClass:function(el,className){
          return el.className.match(new RegExp(\'(\\\\s|^)\' + className + \'(\\\\s|$)\')); 
    },
    
    /** 功能说明:给指定DOM元素添加class
     * @param el 指定的DOM元素
     * @param className 添加的class名
     * */
    addClass:function(el,className){
        if(!this.hasClass(el,className)){
            el.className += " " + className;
        }
        return el;
    },
    
    /** 功能说明:给指定DOM元素移除class
     * @param el 指定的DOM元素
     * @param className 移除的class名
     * */
    removeClass:function(el,className){
        if(this.hasClass(el,className)){
            var reg = new RegExp(\'(\\\\s|^)\' + className +\'(\\\\s|$)\');
            el.className = el.className.replace(reg,\' \')
        }
        return el;
    },
    
    /** 功能说明:给指定的DOM元素添加或者删除class
     * @param el 指定的DOM元素
     * @parm className 添加或删除的class名
     * */
    toggleClass:function(el,className){
        if(this.hasClass(el,className)){
            this.removeClass(el,className);
        }else{
            this.addClass(el,className);
        }
        return el;
    },
    
    /** 功能说明:获取当前元素的兄弟节点
     * @param el 当前DOM元素
     * */
    siblings:function(el){
        var matched = []; //存放兄弟节点
        var n = (el.parentNode || {}).firstChild;
        for(; n; n = n.nextSibling){
            if(n.nodeType === 1 && n !== el){
                matched.push(n);
            }
        }
        return matched;
    }
};

 获得class:

function getByClass(oParent,sClass){
    if(oParent.getElementsByClassName){
        return oParent.getElementsByClassName(sClass);
    }else{
        var allEle = oParent.getElementsByTagName("*"),
            len = allEle.length,
            reg = new RegExp(\'(\\\\b)\' + sClass + \'(\\\\b)\',\'i\'),
            allReuslt = [],
            i;
        for( i=0; i < len; i ++){
            if(allEle[i].className.search(reg) != -1){
                allReuslt.push(allEle[i]);
            }
        }
        return allReuslt;
    }
}

获取样式:

function getStyle(ele,attr){
    var result = \'\';
    if(document.defaultView.getComputedStyle){
        result = document.defaultView.getComputedStyle(ele,false)[attr];
    }else{
        result = ele.currentStyle[attr];
    }
    if(attr == \'opacity\'){
        return Math.round(parseFloat(result)*100);
    }else{
        return parseInt(result);
    }
}

 element组件的DOM操作代码如下,更灵活:

const ieVersion = document.documentMode && Number(document.documentMode);


const trim = function(string) {
  return (string || \'\').replace(/^[\\s\\uFEFF]+|[\\s\\uFEFF]+$/g, \'\');
};

const camelCase = function(name) {
    const SPECIAL_CHARS_REGEXP = /([\\:\\-\\_]+(.))/g;
    const MOZ_HACK_REGEXP = /^moz([A-Z])/;
  return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
    return offset ? letter.toUpperCase() : letter;
  }).replace(MOZ_HACK_REGEXP, \'Moz$1\');
};

const on = (function() {
  if (document.addEventListener) {
    return function(element, event, handler) {
      if (element && event && handler) {
        element.addEventListener(event, handler, false);
      }
    };
  } else {
    return function(element, event, handler) {
      if (element && event && handler) {
        element.attachEvent(\'on\' + event, handler);
      }
    };
  }
})();


const off = (function() {
  if (document.removeEventListener) {
    return function(element, event, handler) {
      if (element && event) {
        element.removeEventListener(event, handler, false);
      }
    };
  } else {
    return function(element, event, handler) {
      if (element && event) {
        element.detachEvent(\'on\' + event, handler);
      }
    };
  }
})();


const once = function(el, event, fn) {
  var listener = function() {
    if (fn) {
      fn.apply(this, arguments);
    }
    off(el, event, listener);
  };
  on(el, event, listener);
};


function hasClass(el, cls) {
  if (!el || !cls) return false;
  if (cls.indexOf(\' \') !== -1) throw new Error(\'className should not contain space.\');
  if (el.classList) {
    return el.classList.contains(cls);
  } else {
    return (\' \' + el.className + \' \').indexOf(\' \' + cls + \' \') > -1;
  }
};


function addClass(el, cls) {
  if (!el) return;
  var curClass = el.className;
  var classes = (cls || \'\').split(\' \');

  for (var i = 0, j = classes.length; i < j; i++) {
    var clsName = classes[i];
    if (!clsName) continue;

    if (el.classList) {
      el.classList.add(clsName);
    } else if (!hasClass(el, clsName)) {
      curClass += \' \' + clsName;
    }
  }
  if (!el.classList) {
    el.className = curClass;
  }
};


function removeClass(el, cls) {
  if (!el || !cls) return;
  var classes = cls.split(\' \');
  var curClass = \' \' + el.className + \' \';

  for (var i = 0, j = classes.length; i < j; i++) {
    var clsName = classes[i];
    if (!clsName) continue;

    if (el.classList) {
      el.classList.remove(clsName);
    } else if (hasClass(el, clsName)) {
      curClass = curClass.replace(\' \' + clsName + \' \', \' \');
    }
  }
  if (!el.classList) {
    el.className = trim(curClass);
  }
};


const getStyle = ieVersion < 9 ? function(element, styleName) {
  if (!element || !styleName) return null;
  styleName = camelCase(styleName);
  if (styleName === \'float\') {
    styleName = \'styleFloat\';
  }
  try {
    switch (styleName) {
      case \'opacity\':
        try {
          return element.filters.item(\'alpha\').opacity / 100;
        } catch (e) {
          return 1.0;
        }
      default:
        return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null);
    }
  } catch (e) {
    return element.style[styleName];
  }
} : function(element, styleName) {
  if (!element || !styleName) return null;
  styleName = camelCase(styleName);
  if (styleName === \'float\') {
    styleName = \'cssFloat\';
  }
  try {
    var computed = document.defaultView.getComputedStyle(element, \'\');
    return element.style[styleName] || computed ? computed[styleName] : null;
  } catch (e) {
    return element.style[styleName];
  }
};


function setStyle(element, styleName, value) {
  if (!element || !styleName) return;

  if (typeof styleName === \'object\') {
    for (var prop in styleName) {
      if (styleName.hasOwnProperty(prop)) {
        setStyle(element, prop, styleName[prop]);
      }
    }
  } else {
    styleName = camelCase(styleName);
    if (styleName === \'opacity\' && ieVersion < 9) {
      element.style.filter = isNaN(value) ? \'\' : \'alpha(opacity=\' + value * 100 + \')\';
    } else {
      element.style[styleName] = value;
    }
  }
};

const isScroll = (el, vertical) => {
  const determinedDirection = vertical !== null || vertical !== undefined;
  const overflow = determinedDirection
    ? vertical
      ? getStyle(el, \'overflow-y\')
      : getStyle(el, \'overflow-x\')
    : getStyle(el, \'overflow\');

  return overflow.match(/(scroll|auto)/);
};

const getScrollContainer = (el, vertical) => {

  let parent = el;
  while (parent) {
    if ([window, document, document.documentElement].includes(parent)) {
      return window;
    }
    if (isScroll(parent, vertical)) {
      return parent;
    }
    parent = parent.parentNode;
  }

  return parent;
};

const isInContainer = (el, container) => {
  if (!el || !container) return false;

  const elRect = el.getBoundingClientRect();
  let containerRect;

  if ([window, document, document.documentElement, null, undefined].includes(container)) {
    containerRect = {
      top: 0,
      right: window.innerWidth,
      bottom: window.innerHeight,
      left: 0
    };
  } else {
    containerRect = container.getBoundingClientRect();
  }

  return elRect.top < containerRect.bottom &&
    elRect.bottom > containerRect.top &&
    elRect.right > containerRect.left &&
    elRect.left < containerRect.right;
};

 

以上是关于原生JS实现的DOM操作笔记(草稿整理)的主要内容,如果未能解决你的问题,请参考以下文章

将原生JS和jquery里面的DOM操作进行了一下整理

原生js操作DOM基础-笔记

原生js 的一些DOM/样式操作

Javascript操作DOM常用API总结

原生js的开发笔记

repostJavascript操作DOM常用API总结