Cảm nhận tư duy và tổng hợp kiến thức

Thứ Bảy, 6 tháng 2, 2016

SlideShow trình chiếu ảnh tuyệt đẹp cho Blogspot (Blogger) phần 2

SlideShow trình chiếu ảnh tuyệt đẹp cho Blogspot (Blogger) phần 2Cũng đã 10 ngày rồi không vào Blog, hôm nay ghé thăm cảm thấy đơn điệu quá L. Chắc từ nay về sau một tuần mình chỉ viết một bài vào thứ hai thôi (Do thời gian của mình càng ngày càng hạn hẹp, nhưng mình vẫn cố gắng trả lời thắc mắc khi các bạn cần).
Còn riêng hôm nay mình sẽ hướng dẫn các bạn cách chằn một “SlideShow trình chiếu có gắn phần mô tả ngắn cho từng hình ảnh” trông rất chuyên nghiệp, thường gắn vào cột sitebar để giới thiệu một số bài viết nổi bật của họ hay tạo Banner để quảng cáo là hợp lý nhất.
SlideShow trình chiếu này được phát triển bởi Dynamicdrive, sử dụng một đoạn Javarscip và CSS với hiệu ứng mượt từ thư viện JQuery dưới đây là DEMO cho các bạn xem trước.


☼ Giờ bắt đầu thủ thuật cùng Windows2it.

Đầu tiên bạn vào Blog => Bố cục => Thêm tiện ích => HTML/JavaScript và dán đoạn mã code dưới đây vào và Lưu lại.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<style type="text/css"> /*Make sure your page contains a valid doctype at the top*/
visibility: hidden; /*keep this intact*/
#simplegallery1{ //CSS for Simple Gallery Example 1 position: relative; /*keep this intact*/
border: 1px solid #666;
}
#simplegallery1 .gallerydesctext{ //CSS for description DIV of Example 1 (if defined)
text-align: left;
padding: 2px 5px;
font: 10px normal verdana, arial;
} </style>
<script type="text/javascript" >
var simpleGallery_navpanel={
loadinggif: 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkZuz7TOFdd4v9Fck5ntd3Qx3laMfAV2PkcWHuGDT9Yq281hzlHLFeguPwEPX6iNHVDRS5HG_0HT2lcjWudDFseIkxstUJjVshYxrG1Do9BY4vTO2LopOIKnik1Znu5xQ85nU37zuzL00/s1600/ajaxload-namkna-blogspot-com.png', //full path or URL to loading gif image
panel: {height:'45px', opacity:0.5, paddingTop:'5px', fontStyle:'bold 11px Verdana'}, //customize nav panel container
images: [ 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ7od6ow3hzUBqkT9BhtaU4skNtH7b8yzcOtgHRhyphenhyphenOYOOwRoHlHpTK3q8BlBdut4YaCri-Ko-WrIVL158om3UESlCLyY8ilU_G4xClDONQaxWFiFqPWlwX2TK0732TIuUIqZdPLA18OIc/s1600/left-namkna-blogspot-com.png', 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIv1jPqXnL19lqKcXxnbhdJfFFckqv2GNNIPTVfElz9CDcqbM1Jb1IH9Ok9KWw_Qemdb6Zn7NrTbprnqiZJ1QTbqib_C8tMRBWRYpv7gdJcafRGi7gJb60OJCLnxkB5Yh-Y1RvdcODh6E/s1600/play-namkna-blogspot-com.png', 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmCoOBk0vGBFOwb_2tmjrGlgD5PsqQcP_YHmSDLYwlzrlDROad3EYGuGEZOT2B-5Oyf2BsDbWfjlSTG2rc2760vwrVjlGdlslGAl8HgZ9ldHpTw4eyvf3CMEmuwDdzJOxBbsN8OnPuZNI/s1600/right-namkna-blogspot-com.png', 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvK3ej3GU-GBEH8m7k2uP8ks-WBo_351HdMCw-VL7JfdEylhwUnPbDJSDmNGif-kQXlot3S-XAZmE7jBE6ifk03mOiM3Y5P3kQexrvUcnFyWDi29TFj7HOTpm8QVhEt5Y19fnlLDALOUI/s1600/pause-namklna-blogspot-com.png'], //nav panel images (in that order)
imageSpacing: {offsetTop:[-4, 0, -4], spacing:10}, //top offset of left, play, and right images, PLUS spacing between the 3 images
slideduration: 500 //duration of slide up animation to reveal panel
} function simpleGallery(settingarg){
settingarg=null
this.setting=settingarg var setting=this.setting
setting.panelheight=(parseInt(setting.navpanelheight)>5)? parseInt(setting.navpanelheight) : parseInt(simpleGallery_navpanel.panel.height)
setting.fadeduration=parseInt(setting.fadeduration)
setting.curimage=(setting.persist)? simpleGallery.routines.getCookie("gallery-"+setting.wrapperid) : 0
setting.curimage=setting.curimage || 0 //account for curimage being null if cookie is empty
setting.preloadfirst=(!jQuery.Deferred)? false : (typeof setting.preloadfirst!="undefined")? setting.preloadfirst : true //Boolean on whether to preload all images before showing gallery
setting.ispaused=!setting.autoplay[0] //ispaused reflects current state of gallery, autoplay[0] indicates whether gallery is set to auto play
setting.currentstep=0 //keep track of # of slides slideshow has gone through
setting.totalsteps=setting.imagearray.length*setting.autoplay[2] //Total steps limit: # of images x # of user specified cycles
setting.fglayer=0, setting.bglayer=1 //index of active and background layer (switches after each change of slide)
setting.oninit=setting.oninit || function(){}
var preloadimages=[], longestdesc=null, loadedimages=0
setting.onslide=setting.onslide || function(){}
var dfd = (setting.preloadfirst)? jQuery.Deferred() : {resolve:function(){}, done:function(f){f()}} //create real deferred object unless preloadfirst setting is false or browser doesn't support it
setting.longestdesc="" //get longest description of all slides. If no desciptions defined, variable contains ""
setting.$loadinggif=(function(){ //preload and ref ajax loading gif
var loadgif=new Image()
loadgif.src=simpleGallery_navpanel.loadinggif
return jQuery(loadgif).css({verticalAlign:'middle'}).wrap('<div style="position:absolute;text-align:center;width:100%;height:100%" />').parent()
})()
for (var i=0; i<setting.imagearray.length; i++){ //preload slideshow images
preloadimages[i]=new Image()
preloadimages[i].src=setting.imagearray[i][0]
if (setting.imagearray[i][3] && setting.imagearray[i][3].length>setting.longestdesc.length)
setting.longestdesc=setting.imagearray[i][3]
jQuery(preloadimages[i]).bind('load error', function(){
loadedimages++
if (loadedimages==setting.imagearray.length){
dfd.resolve() //indicate all images have been loaded
} }) }
jQuery(document).ready(function($){
var slideshow=this var setting=slideshow.setting
setting.$wrapperdiv=$('#'+setting.wrapperid).css({position:'relative', visibility:'visible', background:'black', overflow:'hidden', width:setting.dimensions[0], height:setting.dimensions[1]}).empty() //main gallery DIV
if (setting.$wrapperdiv.length==0){ //if no wrapper DIV found
alert("Error: DIV with ID \""+setting.wrapperid+"\" not found on page.")
return
}
setting.$gallerylayers=$('<div class="gallerylayer"></div><div class="gallerylayer"></div>') //two stacked DIVs to display the actual slide
.css({position:'absolute', left:0, top:0})
.appendTo(setting.$wrapperdiv)
setting.$loadinggif.css({top:setting.dimensions[1]/2-30}).appendTo(setting.$wrapperdiv) //30 is assumed height of ajax loading gif
setting.gallerylayers=setting.$gallerylayers.get() //cache stacked DIVs as DOM objects
setting.navbuttons=simpleGallery.routines.addnavpanel(setting) //get 4 nav buttons DIVs as DOM objects
if (setting.longestdesc!="") //if at least one slide contains a description (feature is enabled)
setting.descdiv=simpleGallery.routines.adddescpanel(setting)
$(setting.navbuttons).filter('img.navimages').css({opacity:0.8})
.bind('mouseover mouseout', function(e){
$(this).css({opacity:(e.type=="mouseover")? 1 : 0.8})
})
.bind('click', function(e){
var keyword=e.target.title.toLowerCase()
slideshow.navigate(keyword) //assign behavior to nav images
})
setting.$loadinggif.remove()
dfd.done(function(){ //execute when all images have loaded
setting.$wrapperdiv.bind('mouseenter', function(){slideshow.showhidenavpanel('show')})
setting.$wrapperdiv.bind('mouseleave', function(){slideshow.showhidenavpanel('hide')})
$(window).bind('unload', function(){ //clean up and persist
slideshow.showslide(setting.curimage) //show initial slide setting.oninit.call(slideshow) //trigger oninit() event
$(slideshow.setting.navbuttons).unbind()
if (slideshow.setting.persist) //remember last shown image's index
simpleGallery.routines.setCookie("gallery-"+setting.wrapperid, setting.curimage)
jQuery.each(slideshow.setting, function(k){
if (slideshow.setting[k] instanceof Array){
for (var i=0; i<slideshow.setting[k].length; i++){
if (slideshow.setting[k][i].tagName=="DIV") //catches 2 gallerylayer divs, gallerystatus div
slideshow.setting[k][i].innerHTML=null
slideshow.setting[k][i]=null
if (slideshow.setting[k].innerHTML) //catch gallerydesctext div
} }
slideshow.setting[k].innerHTML=null
})
slideshow.setting[k]=null slideshow=slideshow.setting=null
simpleGallery.prototype={
}) }) //end deferred code }) //end jQuery domload }
this.setting.totalsteps=100000 //if any of the nav buttons are clicked on, set totalsteps limit to an "unreachable" number
navigate:function(keyword){ clearTimeout(this.setting.playtimer)
if (!isNaN(parseInt(keyword))){
this.showslide(parseInt(keyword))
}
else if (/(prev)|(next)/i.test(keyword)){
this.showslide(keyword.toLowerCase())
}
else{ //if play|pause button
var slideshow=this
var $playbutton=$(this.setting.navbuttons).eq(1)
if (!this.setting.ispaused){ //if pause Gallery
this.setting.autoplay[0]=false
$playbutton.attr({title:'Play', src:simpleGallery_navpanel.images[1]})
}
else if (this.setting.ispaused){ //if play Gallery
this.setting.autoplay[0]=true
this.setting.playtimer=setTimeout(function(){slideshow.showslide('next')}, this.setting.autoplay[1])
$playbutton.attr({title:'Pause', src:simpleGallery_navpanel.images[3]})
}
slideshow.setting.ispaused=!slideshow.setting.ispaused
} }, showslide:function(keyword){
var setting=slideshow.setting
var slideshow=this var totalimages=setting.imagearray.length
var imgindex=(keyword=="next")? (setting.curimage<totalimages-1? setting.curimage+1 : 0)
: (keyword=="prev")? (setting.curimage>0? setting.curimage-1 : totalimages-1)
: Math.min(keyword, totalimages-1)
setting.gallerylayers[setting.bglayer].innerHTML=simpleGallery.routines.getSlideHTML(setting.imagearray[imgindex])
setting.$gallerylayers.eq(setting.bglayer).css({zIndex:1000, opacity:0}) //background layer becomes foreground
.stop().css({opacity:0}).animate({opacity:1}, setting.fadeduration, function(){ //Callback function after fade animation is complete:
clearTimeout(setting.playtimer)
setting.gallerylayers[setting.bglayer].innerHTML=null //empty bglayer (previously fglayer before setting.fglayer=setting.bglayer was set below)
try{
setting.onslide.call(slideshow, setting.gallerylayers[setting.fglayer], setting.curimage)
}catch(e){
alert("Simple Controls Gallery: An error has occured somwhere in your code attached to the \"onslide\" event: "+e)
}
setting.currentstep+=1
if (setting.autoplay[0]){
if (setting.currentstep<=setting.totalsteps)
setting.playtimer=setTimeout(function(){slideshow.showslide('next')}, setting.autoplay[1])
else
slideshow.navigate("play/pause")
}
setting.gallerylayers[setting.fglayer].style.zIndex=999 //foreground layer becomes background
}) //end callback function
setting.fglayer=setting.bglayer
setting.bglayer=(setting.bglayer==0)? 1 : 0
setting.curimage=imgindex
setting.navbuttons[3].innerHTML=(setting.curimage+1) + '/' + setting.imagearray.length
if (setting.imagearray[imgindex][3]){ //if this slide contains a description
setting.$descpanel.css({visibility:'visible'})
setting.descdiv.innerHTML=setting.imagearray[imgindex][3]
}
else if (setting.longestdesc!=""){ //if at least one slide contains a description (feature is enabled)
setting.descdiv.innerHTML=null
setting.$descpanel.css({visibility:'hidden'})
} },
var setting=this.setting
showhidenavpanel:function(state){
var endpoint=(state=="show")? setting.dimensions[1]-setting.panelheight : this.setting.dimensions[1]
setting.$navpanel.stop().animate({top:endpoint}, simpleGallery_navpanel.slideduration)
if (setting.longestdesc!="") //if at least one slide contains a description (feature is enabled)
this.showhidedescpanel(state)
},
var setting=this.setting
showhidedescpanel:function(state){
var endpoint=(state=="show")? 0 : -setting.descpanelheight
setting.$descpanel.stop().animate({top:endpoint}, simpleGallery_navpanel.slideduration)
} } simpleGallery.routines={ getSlideHTML:function(imgelement){
var layerHTML=(imgelement[1])? '<a href="'+imgelement[1]+'" target="'+imgelement[2]+'">\n' : '' //hyperlink slide?
layerHTML+='<img src="'+imgelement[0]+'" style="border-width:0" />'
layerHTML+=(imgelement[1])? '</a>' : ''
return layerHTML //return HTML for this layer
},
addnavpanel:function(setting){
var interfaceHTML=''
for (var i=0; i<3; i++){
var imgstyle='position:relative; border:0; cursor:hand; cursor:pointer; top:'+simpleGallery_navpanel.imageSpacing.offsetTop[i]+'px; margin-right:'+(i!=2? simpleGallery_navpanel.imageSpacing.spacing+'px' : 0)
var title=(i==0? 'Prev' : (i==1)? (setting.ispaused? 'Play' : 'Pause') : 'Next')
var imagesrc=(i==1)? simpleGallery_navpanel.images[(setting.ispaused)? 1 : 3] : simpleGallery_navpanel.images[i]
interfaceHTML+='<img class="navimages" title="' + title + '" src="'+ imagesrc +'" style="'+imgstyle+'" /> '
}
interfaceHTML+='<div class="gallerystatus" style="margin-top:1px">' + (setting.curimage+1) + '/' + setting.imagearray.length + '</div>'
setting.$navpanel=$('<div class="navpanellayer"></div>')
.css({position:'absolute', width:'100%', height:setting.panelheight, left:0, top:setting.dimensions[1], font:simpleGallery_navpanel.panel.fontStyle, zIndex:'1001'})
.appendTo(setting.$wrapperdiv)
$('<div class="navpanelbg"></div><div class="navpanelfg"></div>') //create inner nav panel DIVs
.css({position:'absolute', left:0, top:0, width:'100%', height:'100%'})
.eq(0).css({background:'black', opacity:simpleGallery_navpanel.panel.opacity}).end() //"navpanelbg" div
.eq(1).css({paddingTop:simpleGallery_navpanel.panel.paddingTop, textAlign:'center', color:'white'}).html(interfaceHTML).end() //"navpanelfg" div
.appendTo(setting.$navpanel)
return setting.$navpanel.find('img.navimages, div.gallerystatus').get() //return 4 nav related images and DIVs as DOM objects
},
adddescpanel:function(setting){
setting.$descpanel=$('<div class="gallerydesc"><div class="gallerydescbg"></div><div class="gallerydescfg"><div class="gallerydesctext"></div></div></div>')
.css({position:'absolute', width:'100%', left:0, top:-1000, zIndex:'1001'})
.find('div').css({position:'absolute', left:0, top:0, width:'100%'})
.eq(0).css({background:'black', opacity:simpleGallery_navpanel.panel.opacity}).end() //"gallerydescbg" div
.eq(1).css({color:'white'}).end() //"gallerydescfg" div
.eq(2).html(setting.longestdesc).end().end()
.appendTo(setting.$wrapperdiv)
var $gallerydesctext=setting.$descpanel.find('div.gallerydesctext')
setting.descpanelheight=$gallerydesctext.outerHeight()
setting.$descpanel.css({top:-setting.descpanelheight, height:setting.descpanelheight}).find('div').css({height:'100%'})
return setting.$descpanel.find('div.gallerydesctext').get(0) //return gallery description DIV as a DOM object
},
getCookie:function(Name){
var re=new RegExp(Name+"=[^;]+", "i"); //construct RE to search for target name/value pair
if (document.cookie.match(re)) //if cookie found
return document.cookie.match(re)[0].split("=")[1] //return its value
return null
},
setCookie:function(name, value){
document.cookie = name+"=" + value + ";path=/"
} } </script> <script type="text/javascript">
wrapperid: "simplegallery1", //ID of main gallery container,
var mygallery=new simpleGallery({
dimensions: [300, 200], //width/height of gallery in pixels. Should reflect dimensions of the images exactly
imagearray: [
["IMAGE LINK 1", "#", "_new", "DESCRIPTION"],
["IMAGE LINK 2", "#", "_new", "DESCRIPTION"],
["IMAGE LINK 3", "#", "_new", "DESCRIPTION"],
["IMAGE LINK 4", "#", "_new", "DESCRIPTION"],
["IMAGE LINK 5", "#", "_new", "DESCRIPTION"] ],
autoplay: [true, 2000, 20], //[auto_play_boolean, delay_btw_slide_millisec, cycles_before_stopping_int]
persist: false, //remember last viewed slide and recall within same session?
fadeduration: 500, //transition duration (milliseconds)
oninit:function(){ //event that fires when gallery has initialized/ ready to run
//Keyword "this": references current gallery instance (ie: try this.navigate("play/pause"))
},
onslide:function(curslide, i){ //event that fires after each slide is shown
//Keyword "this": references current gallery instance
//curslide: returns DOM reference to current slide's DIV (ie: try alert(curslide.innerHTML)
//i: integer reflecting current image within collection being shown (0=1st image, 1=2nd etc)
}
<div id="simplegallery1"></div>  
})
</script>
·        Thay IMAGE LINK 1, 2, 3, 4, 5 thành link ảnh của bạn.
·        Thay dấu # màu đỏ là liên kết tới bài viết hoặc trang Blog/Website bạn mong muốn.
·        Thay DESCRIPTION là mô tả cho hình ảnh
·        Để tăng hoặc giảm thời gian luân chuyển giữa 2 ảnh kế tiếp nhau bạn thay đổi giá trị 2000 tương đương với 2 giây.
·        Để tắt chức năng tự động di chuyển qua các ảnh bạn sửa true thành false.
·        Để thay đổi chiều rộng và chiều cao của khung slider bạn hãy thay đổi giá trị chiều rộng 300 và chiều cao 200.
·       font: 10px là cỡ chữ của phần mô tả.
·        persist: false tắt chức năng nhớ bức ảnh cuối cùng bạn xem trước khi thoát khỏi hoặc chuyển đến bài khác để tiếp tục chạy. Để bật thì thay persist: false thành persist: true .
·        fadeduration: 500 Thời gian chuyển đổi thời gian tính bằng mili giây.

Đó là tất cả những gì bạn cần phải làm.

Nếu bạn thích bài viết này, hãy subscribe blog của tôi để thường xuyên cập nhật những bài viết hay nhất, mới nhất qua email nhé. Cảm ơn rất nhiều. JJJ

Quá trình cài đặt gặp vấn đề gì cứ để lại Comment !
Nguồn Windows2it.com


Share:

SlideShow trình chiếu ảnh tuyệt đẹp cho blogspot (blogger) phần 1

SlideShow trình chiếu ảnh tuyệt đẹp cho blogspot Kiểu trình chiếu SlideShow bạn thường thấy nhiều nhất là ở các Blog/website tài liệu (123tailieufree.com,123doc.orgidoc.vnkilobooks.com đây là các site tài liệu lớn nhất Việt Nam hiện nay)… Nó làm nổi bật nội dung của một Blog/Website thường đặt ở ngoài trang chủ. Ngoài ra một số Blog thường dùng các SlideShow để trao quảng ở các cột sitebar. Hoàn toàn dùng Javascript không dùng Jquery và Flash.

Hôm nay windows2it sẽ hướng dẫn các bạn cách chằn một SlideShow vào cột Sitebar và trực tiếp vào trong template (nơi mà bạn muốn chằn vào). Bắt đầu thủ thuật !

Chằn vào cột sitebar (vô cùng đơn giản) thường dùng cho quảng cáo



Đầu tiên bạn vào Blog => Bố cục => Thêm tiện ích => HTML/JavaScript và dán đoạn mã code dưới đây vào và Lưu lại.

<script type="text/javascript">
// Banner Rotation Script by Bloggerism
var ban = new Array();
var link = new Array();
var index = 0;
ban[0] = new Image();
ban[0].src = "URL_banner_0";
link[0] = "URL_link_0";
ban[1] = new Image();
ban[1].src = "URL_banner_1";
link[1] = "URL_link_1";
ban[2] = new Image();
ban[2].src = "URL_banner_2";
link[2] = "URL_link_2";
index = Math.random() * (ban.length);
index = Math.floor(index);
function rotator()
{if (index == ban.length) index = 0;
if (document.images) {
document.images.rotation.src = ban[index].src;
}
else {
document.getElementById('rotation').src=ban[index].src;
}
index++;
setTimeout('rotator()',3000);
}
function go() {window.open(link[index-1]);}
</script>
<img id="rotation" style="cursor:pointer;" src="" onclick="go();"/>
<script type="text/javascript">rotator();</script>

Chằn trực tiếp vào trong template làm nổi bật giao diện Blog/Website

Thay đoạn code SlideShow trong Blog/Website của bạn bằng đoạn Code dưới đây: (đoạn code SlideShow thường nằm giữa thẻ mở <body> và thẻ đóng </body>)


<b:if cond='data:blog.pageType != &quot;item&quot;'>
<script type="text/javascript">
// Banner Rotation Script by Bloggerism
var ban = new Array();
var link = new Array();
var index = 0;
ban[0] = new Image();
ban[0].src = "URL_banner_0";
link[0] = "URL_link_0";
ban[1] = new Image();
ban[1].src = "URL_banner_1";
link[1] = "URL_link_1";
ban[2] = new Image();
ban[2].src = "URL_banner_2";
link[2] = "URL_link_2";
index = Math.random() * (ban.length);
index = Math.floor(index);
function rotator()
{if (index == ban.length) index = 0;
if (document.images) {
document.images.rotation.src = ban[index].src;
}
else {
document.getElementById('rotation').src=ban[index].src;
}
index++;
setTimeout('rotator()',3000);
}
function go() {window.open(link[index-1]);}
</script>
<img id="rotation" style="cursor:pointer;" src="" onclick="go();"/>
<script type="text/javascript">rotator();</script></b:if>

 Tùy chỉnh

  • Thay URL_banner_0URL_banner_1URL_banner_2 thành URL của hình ảnh bạn muốn hiển thị trên banner

  • Thay URL_link_0URL_link_1URL_link_2 thành linh liên kết tới trang cần quảng cáo tương ướng với mỗi bức ảnh ở bên trên.

  •  Chú ý số 3000 ám chỉ 3000 mili giây, tương đương 3 giây chỉ khoảng cách giữa các lần chuyển banner. Bạn có thể điều chỉnh con số này tùy ý.

  • Bạn muốn thêm báo nhiêu Ảnh cũng được nhé ! với cú pháp
ban[n] = new Image();
ban[n].src = "URL_banner_n";
link[n] = "URL_link_n";
☼ Kết luận

  • Dễ dàng tùy biến, Code gọn đơn giản dể sửa và đặc biệt hoạt động tốt trên mọi trình duyệt.

  • Đặc biệt không dùng Flash thuận lợi cho việc đăng ký Google Asen 

Bạn nào không rõ thì cứ để lại Comment nhé !

Share:


Thống kê Blogspot

Bài có thể xem

Mời tham gia CLB

 
Câu Lạc Bộ Kết bạn & Chia sẻ thông tin
Nhóm Công khai · 1.614 thành viên
Tham gia nhóm
Mục đích phát triển của Câu lạc bộ: - Cảm nhận tư duy và tổng hợp kiến thức.Cùng nhau Kết bạn và chia sẽ những gì tốt đẹp . - Giúp nhau chia sẽ thươn...
 
 
BACK TO TOP