javascript - 原生 JS如何实现类似Jquery的siblings功能?
巴扎黑
巴扎黑 2017-04-11 12:51:34
[JavaScript讨论组]

如题:
比如我body里面有这么几个链接:

    连接一
    连接二
    连接三
    连接四
    连接五
    连接六
    连接七
    连接八
    连接九
var link = document.getElementsByTagName("a");
for (var i = 0; i < link.length; i++) {
    link[i].addEventListener("click", function() {
        this.style.backgroundColor = "#000";
    })
}

现在能实现单击其中一个链接改变它的背景色,但是如何能实现JQ中很容易实现的功能,点击其中一个,其它的样式也同时变了(切换)。

巴扎黑
巴扎黑

全部回复(5)
PHP中文网

受 @小明 大神的启发,写了最优雅,最高效的方式(我自认为)。

<style>
body{
  background:#CCC;
}
a{
  display:inline-block;
  width:100px;
  padding:5px 10px;
  background:#666;
  text-align:center;
  color:#FFF;
  border:solid 3px #333;
  margin:1px;
}
a.active{
  background-color:#FF0;
  border-color:#C00;
  color:#C00;
}
</style>
<p id="parent">
  <a href="javascript:;">连接一</a>
  <a href="javascript:;">连接二</a>
  <a href="javascript:;">连接三</a>
  <a href="javascript:;">连接四</a>
  <a href="javascript:;">连接五</a>
  <a href="javascript:;">连接六</a>
  <a href="javascript:;">连接七</a>
  <a href="javascript:;">连接八</a>
  <a href="javascript:;">连接九</a>
</p>
<script>
document.getElementById("parent").addEventListener("click", function(event){
    if( event.srcElement.tagName.toLowerCase() == "a" ){
        if( this.lastClick != event.target){
            event.target.className = "active";
            if( !!this.lastClick){
                this.lastClick.className = "";
            }
            this.lastClick = event.target;
        } else {
            console.log("重复点击不触发");
        }
    }
});
</script>

以下是老答案:

好像没有原生的方法,试着扩展了一下:

Element.prototype.siblings = function(callback){
    var siblingElement = [];
    var parentAllElement = [];
    if( ! this.parentNode ){
        return siblingElement;
    };
    parentAllElement = this.parentNode.getElementsByTagName(this.tagName);
    for( var i = 0; i < parentAllElement.length ; i++ ){
        if( parentAllElement[i] != this ){
            siblingElement.push(parentAllElement[i]);
            typeof callback == "function" && callback.call(parentAllElement[i]);
        }
    }
    return siblingElement;
};

然后就可以向 jQuery 一样使用 siblings() 了。

var link = document.getElementsByTagName("a");
for (var i = 0; i < link.length; i++) {
    link[i].addEventListener("click", function() {
        this.style.backgroundColor = "#000";
        var siblings = this.siblings(function(){
            this.style.backgroundColor = "#FFF";
        });
        console.log(siblings[0].siblings());
    })
}

附带 html 代码的例子:

<style>
body{
    background:#CCC;
}
a{
    display:block;
    width:100px;
    padding:5px 10px;
    float:left;
    background:#666;
    text-align:center;
    color : #FFF;
    border : solid 3px #333;
    margin: 1px;
}
</style>
<p>
  <a href="javascript:;">连接一</a>
  <a href="javascript:;">连接二</a>
  <a href="javascript:;">连接三</a>
  <a href="javascript:;">连接四</a>
  <a href="javascript:;">连接五</a>
  <a href="javascript:;">连接六</a>
  <a href="javascript:;">连接七</a>
  <a href="javascript:;">连接八</a>
  <a href="javascript:;">连接九</a>
</p>
<script>
Element.prototype.siblings = function(callback){
    var siblingElement = [];
    var parentAllElement = [];
    if( ! this.parentNode ){
        return siblingElement;
    };
    parentAllElement = this.parentNode.getElementsByTagName(this.tagName);
    for( var i = 0; i < parentAllElement.length ; i++ ){
        if( parentAllElement[i] != this ){
            siblingElement.push(parentAllElement[i]);
            typeof callback == "function" && callback.call(parentAllElement[i]);
        }
    }
    delete parentAllElement;
    return siblingElement;
};

var link = document.getElementsByTagName("a");
for (var i = 0; i < link.length; i++) {
    link[i].addEventListener("click", function() {
        this.style.backgroundColor = "#C00";
        this.style.borderColor = "#FF0";
        
        //用法1:callback方式;改变背景为蓝色
        this.siblings(function(){
            this.style.backgroundColor = "#009";
        });
        
        //用法2:返回列表;改变边框为绿色
        this.siblings().forEach(function(sibling){
            sibling.style.borderColor = "#090";
        });
    })
}
</script>
PHPz

这种情况更多的是吧listener加在父级上,从event的target来判断来源吧。我是Demo

巴扎黑

应该不是加在本级上,应该是从父元素遍历出来的,因为siblings()方法是可以带参数做筛选的。

怪我咯

再加一层循环呗

var link = document.getElementsByTagName("a");
for (var i = 0; i < link.length; i++) {
    link[i].addEventListener("click", function() {
        for (var j = 0; j < link.length; j++){
            link[j].style.backgroundColor = "#fff";
        }
        this.style.backgroundColor = "#000";
    })
}
大家讲道理

@toBeTheLight @mqycn 感谢感谢,确实都能实现同样的效果

@toBeTheLight 的更简洁,只是觉得,a标签如果多了,会不会有性能的影响,或许没有,我也只是这么猜,测试的话也不知道如何能测试性能开销。
@mqycn 的逼格更高,感觉更符合我需要的答案吧,
但具体哪位的更好,我也分辨不出来,总之很是感谢,都能解决实际的问题,至于 性能 暂时就只能不多做考虑了,毕竟我的水平在这。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号