使用原生JavaScript实现HTML()函数,希望通过点击t1改变div中的内容,为什么报错?

希望通过点击t1改变div中的内容,为什么这么实现HTML函数无效?

<div>
  <div class="t1">
    测试
  </div>
</div>

<script type="text/javascript" src="../../../../scripts/helper.js"></script>
<script>

  document.getElementsByClassName("t1")[0].onclick = function() {
    Helper.$(".t1")[0].html("90")
  }
</script>

Helper代码

var Helper = {
    $: function(strExpr) {
        var idExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;
        var classExpr = /^(?:\s*(<[\w\W]+>)[^>]*|.([\w-]*))$/;
        if(idExpr.test(strExpr)){
            var idMatch = idExpr.exec(strExpr);
            return document.getElementById(idMatch[2]);
        }else if(classExpr.test(strExpr)){
            var classMatch = classExpr.exec(strExpr);
            var allElement = document.getElementsByTagName("*");
            var ClassMatch = [];
            for(var i=0,l=allElement.length; i<l; i++){
                if(allElement[i].className.match( new RegExp( "(\\s|^)" + classMatch[2] + "(\\s|$)") )){
                    ClassMatch.push(allElement[i]);
                }
            }
            return ClassMatch;
        }
    },

    html: function() {
        if (arguments.length === 0) {
            return this.innerHTML;
        } else if (arguments.length === 1) {
            this.innerHTML = arguments[0];
            return this;
        }
    }
}

这是我写的,但无法实现,请问什么原因

阅读 1.9k
3 个回答

无法实现是因为你.html("90").html是挂在Helper上的。
Helper.$(".t1")[0]返回的元素上没有对应的方法,要按你写法的实现,就需要将对应方法设置在返回的元素上。

 for (var i = 0, l = allElement.length; i < l; i++) {
                if (allElement[i].className.match(new RegExp("(\\s|^)" + classMatch[2] + "(\\s|$)"))) {
// 将html方法挂在返回元素上
                    allElement[i].html = function () {
                        if (arguments.length === 0) {
                            return this.innerHTML;
                        } else if (arguments.length === 1) {
                            this.innerHTML = arguments[0];
                            return this;
                        }
                    }
                    ClassMatch.push(allElement[i]);
                }
            }

因为html函数中的this指向的是Helper对象本身,而$函数返回的是dom元素或dom元素数组而非Helper对象,显然是没有html这个方法的,所以调用时肯定会报错。你可以把Helper对象这样改下,让它有类数组的特性,并且$方法始终返回数组,这样就能确保这些函数的行为保持一致从而正常调用:

var Helper = {
    length: 0,
    push: [].push,
    splice: [].splice,
    $: function(strExpr) {
        var idExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;
        var classExpr = /^(?:\s*(<[\w\W]+>)[^>]*|.([\w-]*))$/;
        if (idExpr.test(strExpr)) {
            var idMatch = idExpr.exec(strExpr);
            this.push(document.getElementById(idMatch[2]));
        } else if (classExpr.test(strExpr)) {
            var classMatch = classExpr.exec(strExpr);
            var allElement = document.getElementsByTagName("*");
            for (var i = 0, l = allElement.length; i < l; i++) {
                if (allElement[i].className.match(new RegExp("(\\s|^)" + classMatch[2] + "(\\s|$)"))) {
                    this.push(allElement[i]);
                }
            }
        }
        return this;
    },
    html: function() {
        if (arguments.length === 0) {
            return this[0] ? this[0].innerHTML : "";
        } else if (arguments.length === 1) {
            // 这里也要修改下,类数组的多个元素需要循环修改
            for (var i = 0; i < this.length; ++i) {
                this[i].innerHTML = arguments[0];
            }
            return this;
        }
    },
    get: function(index) {
        this.splice(0, this.length, this[index]);
        return this;
    }
};
document.getElementsByClassName("t1")[0].onclick = function() {
    Helper.$(".t1").get(0).html("90");
};

当然,上面这样其实还有改造空间,因为Helper上面的方法都是静态的,每次都是调用同一个对象的方法,你可以把Helper改成构造函数,让它每次调用$函数都是创建新的实例,达到重复使用的目的。

你这么用是会报错的~
Helper.$(".t1")[0]执行后,返回的是dom元素,而dom元素上是不存在html方法的
你这是想实现一个JQuery?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题