[JavaScript练习]造个简单的DOM库

2017-04-22  本文已影响0人  这名字真不对

成品:点我
源码:点这个我
需求如下:

let items = $('li')
// 使用$方法传入选择器,可以返回一个内容为元素节点的数组
items.on('click', function(){
  console.log('click')
})
// 返回的items 对象有一个on方法可以传入事件和监听事件回调的方法
items.addClass('hi').removeClass('error')
// 新增一个addClass 和 removeClass方法,并且可以链式调用
items.text('你好')
// 为数组里面每个item 写入text 
items.text() 
// 返回内容
item = $(items.get(0))

// 1. item 没有 siblings 方法
// 2. 需求要有 xxx.siblings 方法
// 3. $item = $(item)   $item.siblings() 返回 item 的兄弟

// 1. $item.siblings() 没有 addClass 方法
// 2. 需求要有  $item.siblings().addClass
// 3. $item.siblings() 的结果是 $('li') 类似的东西

$item.siblings().removeClass('active').end()
  .addClass('active')
window.$ = function (selectorOrNode) {
    let array = []
    let items = document.querySelectorAll(selectorOrNode)
    for (var i = 0; i < items.length; i++) {
        array.push(items[i])
    }
    return array
}
array.on = function(eventType, fnc){
  for(var i = 0; i < items.length; i++){
    array[i].addEventListener(eventType, fnc)
  }
}
array.addClass = function (value) {
  for (var i = 0; i < array.length; i++) {
    array[i].classList.add(value)
  }
  return array
}
array.removeClass = function (value) {
  for (var i = 0; i < array.length; i++) {
    array[i].classList.remove(value)
  }
  return array
}

这里还有两个问题,如果传值为空,会传入一个undefined 作为参数,此时不应该给原数组做任何操作,我们修改一下:

array.addClass = function (className) {
  if (className !== undefined) {
    for (var i = 0; i < array.length; i++) {
      array[i].classList.add(className)
    }
  }
  return array
}
array.removeClass = function (className) {
  if (className !== undefined) {
    for (var i = 0; i < array.length; i++) {
      array[i].classList.remove(className)
    }
  }
  return array
}
array.text = function (text) {
  if (text !== undefined) {
    for (var i = 0; i < array.length; i++) {
      array[i].textContent = text  //这个方法有局限
    }
    return array
  }else{
    let result = []
    for(var i =0; i< array.length;i++){
      result.push(array[i].textContent)
    }
    return result
  }
}
window.$ = function (selectorOrNode) {
    let array = []
    if (typeof selectorOrNode === 'string') {
        let items = document.querySelectorAll(selectorOrNode)
        for (var i = 0; i < items.length; i++) {
            array.push(items[i])
        }
    } else if (selectorOrNode instanceof Element) {
        array.push(selectorOrNode)
    } else if (selectorOrNode instanceof Array) {
        for (var i = 0; i < selectorOrNode.length; i++) {
            if (selectorOrNode[i] instanceof Element) {
                array.push(selectorOrNode[i])
            }
        }
    }

    array.on = function (eventType, fnc) {
        for (var i = 0; i < array.length; i++) {
            array[i].addEventListener(eventType, fnc)
        }
        return array
    }
    array.addClass = function (className) {
        if (className !== undefined) {
            for (var i = 0; i < array.length; i++) {
                array[i].classList.add(className)
            }
        }
        return array
    }
    array.removeClass = function (className) {
        if (className !== undefined) {
            for (var i = 0; i < array.length; i++) {
                array[i].classList.remove(className)
            }
        }
        return array
    }
    array.text = function (text) {
        if (text !== undefined) {
            for (var i = 0; i < array.length; i++) {
                array[i].textContent = text
            }
            return array
        } else {
            let result = []
            for (var i = 0; i < array.length; i++) {
                result.push(array[i].textContent)
            }
            return result
        }
    }
    return array
}
array.get = function(index){
  return array[index]
}
array.siblings = function(){
  let sibling = array[0].parentNode.children
  // 该方法只用作判断元素的兄弟姐妹,所以传入的是一个数组,该数组里面只有一个元素,即需要判断兄弟姐妹的那个元素
  let result = []
  for(var i = 0 ;i<sibling.length;i++){
    if(sibling[i] !== array[0]){
      result.push(sibling[i])
    }
  }
  let items = $(result)
  // 递归保证结果依然能使用$里面的数组方法
  items.previousSelection = array
  // 附加一个属性为执行该方法前的数组,用于后面的end()方法返回原数组
  return items 
}
array.end = function (){
  return array.previousSelection
}

学习过程中遇到的问题:

上一篇 下一篇

猜你喜欢

热点阅读