dd();
function dd() {
var s = document.getElementsByClassName("pingStar")[0],
m = document.getElementsByClassName('dir')[0],
n = s.getElementsByTagName("li"),
input = document.getElementsByClassName('startP')[0]; //保存所选值
clearAll = function () {
for (var i = 0; i < n.length; i++) {
n[i].className = '';
}
}
for (var i = 0; i < n.length; i++) {
n[i].onclick = function () {
var q = this.getAttribute("rel");
clearAll();
input.value = q;
for (var i = 0; i < q; i++) {
n[i].className = 'on';
}
m.innerHTML = this.getAttribute("title");
}
n[i].onmouseover = function () {
var q = this.getAttribute("rel");
clearAll();
for (var i = 0; i < q; i++) {
n[i].className = 'on';
}
}
n[i].onmouseout = function () {
clearAll();
for (var i = 0; i < input.value; i++) {
n[i].className = 'on';
}
}
}
}
在同一个页面内,怎么只用这一遍代码同时实现好几个效果
把Html代码贴下,谢谢
<span class="starts">
<ul class="pingStar">
<li rel="1" title="特别差,给1分"></li>
<li rel="2" title="很差,给2分"></li>
<li rel="3" title="一般般,给3分"></li>
<li rel="4" title="很好,给4分"></li>
<li rel="5" title="非常好,给5分"></li>
<span class="dir"></span>
</ul>
<input type="hidden" value="" class="startP">
</span>
.span{display: inline-block;width: 20px;height:20px;line-height: 20px;text-align: center;background: #333;color:#fff;}
.starts,.starts ul{float:left;}
.starts{padding-left:16px;padding-top:7px;}
.starts ul li{width:32px;height:31px;float:left;background:#ddd;padding-right:3px;}
.starts ul li.on{background:red;}
.starts ul span{display:inline;float:left;padding-left:10px;height:31px;line-height:31px;}
@疯撩汝心:
好久没见到使用原生JS写的代码了。
好吧,来说说你的问题。
CSS代码我就不管了,艺术细胞不好
先说你的HTML 代码
span不要写在ul里面,虽然多数浏览器不会报错,但是这样不符合html的结构规则。当然这个问题不重要
然后说过你关心的JS
你说你即使复制了html代码还是只有第一个生效问题在这
看到这三个箭头了么,这就是原因,你的选择器虽然找到了所有同类名的元素,但是你仅对第一个元素进行了事件绑定,而没有对后续的元素进行绑定,自然也无法触发事件
那知道问题后我们来修改代码,虽然你的代码里有很多问题,或者说至少我不喜欢的写法,但是我尽可能按照你的风格来写
1 dd(); 2 3 function dd() { 4 //从模块域开始 5 var scope = document.getElementsByClassName("starts") 6 7 for (var id = 0; id < scope.length; id++) { 8 let s = scope[id].getElementsByClassName("pingStar")[0], 9 m = scope[id].getElementsByClassName('dir')[0], 10 n = s.getElementsByTagName("li"), 11 input = scope[id].getElementsByClassName('startP')[0]; //保存所选值 12 let clearAll = function() { 13 14 for (var i = 0; i < n.length; i++) { 15 n[i].className = ''; 16 } 17 } 18 for (var i = 0; i < n.length; i++) { 19 n[i].onclick = function() { 20 var q = this.getAttribute("rel"); 21 clearAll(); 22 input.value = q; 23 for (var i = 0; i < q; i++) { 24 n[i].className = 'on'; 25 } 26 m.innerHTML = this.getAttribute("title"); 27 } 28 n[i].onmouseover = function() { 29 var q = this.getAttribute("rel"); 30 clearAll(); 31 for (var i = 0; i < q; i++) { 32 n[i].className = 'on'; 33 } 34 } 35 n[i].onmouseout = function() { 36 clearAll(); 37 for (var i = 0; i < input.value; i++) { 38 n[i].className = 'on'; 39 } 40 } 41 } 42 } 43 }
这样你的事件就可以被绑定多次了
我们再来分析一下代码
我做了4处修改,
第一处,确定你有几组可以用来Star的结构(也就是你贴的html代码),也就是为了复用
第二处,我加了一个For循环,为了保证所有的Star结构都被绑定了事件
第三处,获取元素的域被修改为当前的循环的star结构,而不是上下文(document),
第四处,这个你可能会有些疑惑,JS中定义变量的时候,有3个访问修饰符,或者说是四种情况,分别是 var a , let a , const a ,和 a; 。区别是这个变量的作用范围,简单理解(不完全正确),var是的作用范围是function以内,let的作用范围是for以内,const是一个不可修改的常量,而不用访问修饰符,你的作用范围是window。那么结论也就自然有了,第二部for循环中每次需要绑定事件的li不同,而clearAll事件本身也不同,那么自然用let。如有对修饰符疑惑请自行度娘
@写代码的相声演员:谢谢!很详细
@疯撩汝心:
中午吃完饭无聊,给你用JQuery重写了一下
1 $("body").on("click", ".starts li", function() { 2 $(this).addClass("current").siblings().removeClass("current") 3 var component = $(this).closest(".starts") 4 component.find(".dir:eq(0)").html($(this).attr("title")) 5 component.find(".startP:eq(0)").val($(this).index() + 1) 6 }) 7 8 $("body").on("mouseover", ".starts li", function() { 9 $(this).parent().children().removeClass("on") 10 $(this).addClass("on").prevAll().addClass("on"); 11 }) 12 13 $("body").on("mouseleave", ".starts ul", function() { 14 $(this).children().removeClass("on"); 15 $(this).children(".current:eq(0)").addClass("on").prevAll().addClass("on"); 16 });
把这个也在页面下面,无论你如何修改页面(直接改html刷新,还是直接再控制台改而页面元素),效果都可以稳定执行
@写代码的相声演员: 像类似于这样同一个页面多次调用的有没有什么固定的技巧之类的
@疯撩汝心: 原则上没有...纯代码写多了,自然就会了复用了,前提是基本功得好...
jquery上的要理解冒泡事件,并熟悉Jquery强大的选择器,下所有的方法,也能减少很多代码两
@写代码的相声演员: 上传图片之后,这个左边和右边图片是一样的,这个效果如何实现
@疯撩汝心: 私信吧,要不就再开一个问题...
@写代码的相声演员: qq聊吧,我qq:1454700738
@疯撩汝心: QQ...感觉一下回到了上个世纪...咳...太久没登了...估计都被注销了...
@写代码的相声演员: 微信总有吧??
你不是写成函数了么,这个函数可以随意调用,但要实现不同的效果你这个函数就要加几个参数了,比如点击事件获得参数1,该参数可以放到函数中,根据参数函数中实现不同效果
我复制了html布局代码,在js里面不知道要怎么写?
@疯撩汝心: 没听懂你js打算实现什么效果
@河畔: 其实就是这样一个效果,但是只能第一个能用,下面的不行
@疯撩汝心: 你的触发事件是啥 比如ul 下面的li都是评分的 你要each 循环每一个li 然后使用这个函数
@河畔: 鼠标点击时确定评分,
有没有代码案例参考参考,实在想不出来
@疯撩汝心: http://www.jq22.com/yanshi291