首页 >社区问答列表 >javascript - 又是this指向问题

javascript - 又是this指向问题

这是一个星星评分插件,用原生js写的。将for(var k = 0)...这一段抽出来时,然后执行到that.getStarPoint.call(this,point,active)这部分就不行了,这个this是指向star[i],如何将star[i]和star[k]有相同的作用呢?

html: (星星暂时用颜色块代替)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>星星评分插件</title>
    <meta name="renderer" content="ie-webkit">
    <style>
        .star{
            margin-top: 10px;
        }
        .star span, .star em{
            display: inline-block;
            vertical-align: top;
        }
        .star span{
            cursor: pointer;
            width: 16px;
            height: 16px;
            background: #eee;
        }
        .star span.active{
            background: #333;
        }
    </style>
</head>
<body>
    <!-- 建议放评分的盒子也放在同一个盒子里面并且与星星的标签不一样,这样方面dom查找 -->
    <!-- 星星可以是图片,也可以放在css里面 -->
    <p class="star">
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <em class="star-point"></em>
    </p>
</body>
    <script type="text/javascript" src="common.js"></script>
    <script type="text/javascript">
        new Star('.star');
    </script>
</html>

js:

;(function(global,undefined){
    'use strict'
    var _global;

    function Star(options){
        this.defaultOptions = {
            starBox: '.star',  //装星星的obj
            starActive: 'active',  //鼠标移上去的样式
            starPoint: '.star-point'  //星星评分
        };
        this.opt = this.extend(this.defaultOptions, options || {} || '');
        this.star = this.getElem(this.opt.starBox).getElementsByTagName('span');
        this.len = this.star.length;

        this.init(options);

    }
    Star.prototype = {
        constructor: this,

        init: function(options){
            var that = this;

            var starBox = that.getElem(that.opt.starBox),
                starPoint = that.getElem(that.opt.starPoint),
                active = that.opt.starActive,
                star = starBox.getElementsByTagName('span'),
                point = 0;

            for(var i = 0; i<this.len; i++){
                star[i].index = i;
                star[i].onmouseover = function(){
                    that.clearAllStar.call(this);
                    /*for(var k = 0; k<this.len; k++){
                        star[k].className = '';
                    }*/
                    for(var j = 0; j<this.index + 1; j++){
                        star[j].className = active;  //经过的就添加active类
                    }
                }
                star[i].onmouseout = function(){
                    for(var j = 0; j<this.index + 1; j++){
                        star[j].className = '';  //离开的就去掉active类
                    }
                    //公用部分
                    /*for(var k = 0; k<point; k++){
                        star[k].className = active;
                    }*/
                    that.getStarPoint.call(this,point,active);
                }
                star[i].onclick = function(){  //点击后的星星个数以及分数
                    point = this.index + 1;
                    starPoint.innerHTML = point + '分';
                    //公用部分
                    /*for(var k = 0; k<point; k++){
                        star[k].className = active;
                    }*/
                    
                    that.getStarPoint.call(this,point,active);
                }
            }
        },
        clearAllStar: function(){  //清理所有hover过的星星
            for(var k = 0; k<this.len; k++){
                this.className = '';
            }
        },
        getStarPoint: function(point,active){  //获取评分
            for(var k = 0; k<point; k++){
                this.className = active;
            }
        },
        getElem: function(obj){  //获取dom元素
            return document.querySelector(obj);
        },
        extend: function(source,value){  //拓展参数的函数
            for(var i in value){
                if(value.hasOwnProperty(i)){
                    source[i] = value[i];
                }
            }
            return source;
        }
    }
}())

  • 女神的闺蜜爱上我
  • 女神的闺蜜爱上我    2017-06-30 10:00:074楼

    感觉把 this 绑到 getStarPoint() 意义不大,因为除了当前元素,还有前面的元素都要置为 active,不如就 循环然后 star[k].className = active;

    +0添加回复

  • 回复
  • 为情所困
  • 为情所困    2017-06-30 10:00:073楼

    我觉得,你应该将that作为getStarPoint的上下文,写作that.getStarPoint.call(that, point, active);,此处that才是Star实例。

    +0添加回复

  • 回复
  • 阿神
  • 阿神    2017-06-30 10:00:072楼

    把str数组传过去呗,getStarPoint 这个对纯粹的循环操作 ,对this是啥并无要求。

    +0添加回复

  • 回复
  • 欧阳克
  • 欧阳克    2017-06-30 10:00:071楼

    不太理解你说的 “star[i]和star[k]有相同的作用”, 是什么意思。如果onmouseover 知道自己是哪一个star,可以用闭包把i传过去:

    for(var i = 0; i<this.len; i++) {

    star[i].index = i;
    star[i].onmouseover = (function(i) {
        return function(){
            that.clearAllStar.call(this);
            /*for(var k = 0; k<this.len; k++){
                star[k].className = '';
            }*/
            for(var j = 0; j<this.index + 1; j++){
                star[j].className = active;  //经过的就添加active类
            }
        }
    })(i)
    
    .....
    

    }

    +0添加回复

  • 回复