<div id="infinite-scroll">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
#infinite-scroll { width: 400px; height:400px; padding:5px; overflow-y: scroll;}
.item { margin:5px; height:150px; background-color: #ccc; }
const $scrollView = document.getElementById("infinite-scroll");
$scrollView.addEventListener("scroll", function (e) {
const scrollTop = e.target.scrollTop;
const contentHeight = e.target.scrollHeight - e.target.offsetHeight;
if (contentHeight <= scrollTop) {
alert("son!")
}
})
web.dev sitesinden bulduğum aşağıdaki başlıklara göz atabilirsiniz.
Bazı Animasyonlar Neden Yavaş Çalışır?
Modern tarayıcılar iki CSS özelliğini ucuza canlandırabilir: transform ve opacity.
Başka bir animasyon yaparsanız, saniyede 60 kare (FPS) ipeksi pürüzsüzlükte bir hız elde edemezsiniz. Bu yazı, bunun neden böyle olduğunu açıklıyor.
Animasyon Performansı ve Kare Hızı
Web'de herhangi bir animasyon kullanılırken hedefin 60 FPS'lik bir kare hızı olduğu yaygın olarak kabul edilmektedir. Bu kare hızı, animasyonlarınızın düzgün görünmesini sağlayacaktır. Web'de bir frame, ekranı güncellemek ve yeniden render etmek için gereken tüm işleri yapmak için gereken süredir. Her frame 16.7ms (1000ms / 60 ≈ 16.7) içinde tamamlanmazsa, kullanıcılar gecikmeyi algılayacaktır.
Render İşlem Sırası
Bir web sayfasında bir şey görüntülemek için tarayıcının aşağıdaki sıralı adımlardan geçmesi gerekir:
- Style: Elemente uygulanan stiller hesaplanır.
- Layout: Her elemanın geometrik şekli ve konumu bulunur.
- Paint: Her elementin pikselleri katmanlara doldurulur.
- Composite: Katmanlar ekrana çizilir.
Bu 4 atım tarayıcıların rendering pipeline'ı olarak bilinir.
Zaten yüklenmiş bir sayfada bir şeyi anime ettiğinizde, bu adımların tekrar ele alınması gerekir. Bu süreç, animasyonun gerçekleşmesi için değiştirilmesi gereken adımdan başlar.
Daha önce yazdığım gibi, bu adımlar sıralıdır. Örneğin, layout'u değiştiren bir animasyon uygularsanız, paint ve birleştirme adımlarının da yeniden çalışması gerekir. Bu nedenle, düzeni değiştiren bir şeyi canlandırmak, yalnızca kompozisyonu değiştiren bir şeyi canlandırmaktan daha pahalıdır.Daha önce yazdığım gibi, bu adımlar sıralıdır. Örneğin, layout'u değiştiren bir animasyon uygularsanız, paint ve composite adımlarının da yeniden çalışması gerekir. Bu nedenle, layout'u değiştiren bir animasyon, yalnızca composite adımını değiştiren bir animasyondan daha maliyetlidir.
Layout Animasyon Özellikleri
Layout değişiklikleri, değişiklikten etkilenen tüm öğelerin geometrisinin (konum ve boyut) hesaplanmasını içerir. Bir elementi değiştirirseniz, diğer elemanların geometrisinin de yeniden hesaplanması gerekebilir. Örneğin, <html> öğesinin genişliğini değiştirirseniz, alt öğelerinden herhangi biri etkilenebilir. Öğelerin taşma ve birbirini etkileme şekli nedeniyle, ağacın daha aşağısındaki değişiklikler bazen en üste kadar yerleşim hesaplamalarına neden olabilir.
Görünür öğelerin ağacı ne kadar büyükse, layout hesaplamalarının yapılması o kadar uzun sürer.
Paint Animasyon Özellikleri
Paint, elementlerin ekranda hangi sırayla boyanacağını belirleme işlemidir. Genellikle pipeline'daki tüm görevlerin en uzun sürenidir.
Uygulamanızdaki öğelerin katmanlar halinde nasıl gruplandığına bağlı olarak, değişenlerin yanı sıra diğer öğelerin de boyanması gerekebilir.
Composite Animasyon Özellikleri
Composite (birleştirme), sayfayı katmanlara ayırma, sayfanın nasıl görünmesi gerektiğiyle ilgili bilgileri piksellere dönüştürme ve sayfayı oluşturmak için katmanları bir araya getirme (birleştirme) işlemidir.
opacity animasyonunun maliyeti düşükler listesine dahil edilmesinin nedeni budur. Bu özellik kendi katmanında olduğu sürece, bu özellikteki değişiklikler composite (birleştirme) adımı sırasında GPU tarafından işlenebilir. Chromium tabanlı tarayıcılar ve WebKit, opacity ve transform animasyonu olan herhangi bir öğe için yeni bir katman oluşturur.
Katman nedir?
Tarayıcının, canlandırılacak veya geçişi yapılacak şeyleri yeni bir katmana yerleştirerek, diğer her şeyi değil, yalnızca bu öğeleri yeniden boyaması gerekir. Photoshop'un, birlikte hareket ettirilebilen bir grup öğe içeren katman kavramına aşina olabilirsiniz. Tarayıcı oluşturma katmanları bu fikre benzer.
Tarayıcı, yeni bir katmanda hangi öğelerin olması gerektiğine karar vermekte iyiyse de, birini kaçırırsa, katman oluşturmaya zorlamanın yolları vardır. Bunu, yüksek performanslı animasyonlar nasıl oluşturulur bölümünde bulabilirsiniz.
Ancak, her katman RAM'de (geçici bellekte) yer tutacağından, yeni katman oluştururken iyi düşünmek gerekir.
Sınırlı belleğe sahip cihazlarda yeni katmanlar oluşturmak, çözmeye çalıştığınızdan daha fazla performans sorununa neden olabilir. Ek olarak, her katmanın dokularının GPU'ya yüklenmesi gerekir. Bu nedenle, CPU ve GPU arasındaki bant genişliğininin de kısıtlamasına takılarak performans kaybı yaşayabilirsiniz.
Yüksek Performanslı CSS Animasyonları Nasıl Yapılır?
Bu kılavuz size yüksek performanslı CSS animasyonlarının nasıl oluşturulacağınızı anlatır.
Bu kılavuzun önerdiği tüm CSS özellikleri çok iyi tarayıcı uyumluluğuna sahiptir:
... Bu sayfanın içeriği çok uzun olduğu için şu an çevirecek zamanım yok ama basit bir dil kullanıldığı için kolayca anlayabilirsiniz.
Sorumun cevabını Next.js dokümantasyonunda buldum.
Custom Server
Varsayılan olarak next.js, next start ile kendi sunucusunu başlatır.
Eğer sizin kendi backend'iniz varsa bunu Next.js ile kullanmaya devam edebilirsiniz.
Özel bir Next.js sunucusu, özel sunucu kalıplarını kullanabileceğiniz bir server başlatmanıza olanak verir.
Çoğunlukla buna ihtiyacınız omaz ama bu tam bir özelleştirme yapmanıza olanak verir.
Lütfen yalnızca Next.js'in routing yapısı sizin ihtiyaçlarınızı karşılayamıyorsa bir custom server kullanmanız gerektiğini unutmayın.
Bir custom server önemli performans optimizasyonlarını kaldıracaktır. Mesela serverless fonksiyonlar ve Automatic Static Optimization.
Aşağıdaki custom server örneğine bir göz atın:
// server.js
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 3000
// middleware kullanırken `hostname` ve `port` aşapıdaki şekilde sağlanmalıdır.
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer(async (req, res) => {
try {
// `url.parse` için ikinci parametre olarak true vermeyi unutmayın.
// Bu, URL'nin query bölümünü ayrıştırmasını söyler.
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/a') await app.render(req, res, '/a', query)
else if (pathname === '/b') await app.render(req, res, '/b', query)
else await handle(req, res, parsedUrl)
}
catch (err) {
console.error('İşlem sırasında hata oluştu', req.url, err)
res.statusCode = 500
res.end('internal server error')
}
}).listen(port, (err) => {
if (err) throw err
console.log(`> Sunucu Hazır: http://${hostname}:${port}`)
})
})
server.js, babel veya webpack'ten geçmez.
Bu dosyanın gerektirdiği syntax ve import'ların, çalıştırdığınız geçerli node sürümüyle uyumlu olduğundan emin olun.
Custom server'ı çalıştırmak için package.json içindeki script komutlarını şu şekilde güncellemeniz gerekir:
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
}
Custom server, sunucuyu Next.js uygulamasına bağlamak için aşağıdaki içe aktarmayı kullanır:
const next = require('next')
const app = next({})
İlk satırdaki next, aşağıdaki parametreleri alabilen bir objeyi parametre olarak alan bir fonksiyon döndürür:
- dev: [Boolean] - Next.js'in geliştirici modunda başlayıp başlamayacağı. Varsayılan:
false - dir: [String] - Next.js projesinin konumu. Varsayılan: "."
- quiet: [Boolean] - Sunucu bilgilerini içeren hata mesajlarını gizlemek istiyor musun? Varsayılan:
false - conf: [object] - next.config.js dosyası için kullanacağınız object'in aynısı. Varsayılan:
{}
İkinci satırdakinextfonksiyonunun sonucu atanmış olanapp, Next.js'in istekleri gerektiği gibi kullanmasını sağlamak için kullanılabilir.
Dosya Sistemine Göre Yapılan Routing'i Kaldırmak
Varsayılan olaran Next.js, pages klasörü altına yerleştirilen dosya-klasör yapısına göre bir routing kullanır.
Eğer Custom Server kullanarak aynı sayfayı iki farklı link'in render etmesi sağlanıyorsa bu durum SEO ve UX açısından sorunlara yol açabilir.
Bu davranışı devre dışı bırakmak ve sayfalardaki dosyalara dayalı yönlendirmeyi önlemek için next.config.js dosyasını açın ve useFileSystemPublicRoutes yapılandırmasını devre dışı bırakın:
module.exports = {
useFileSystemPublicRoutes: false,
}
useFileSystemPublicRoutes öğesinin SSR'den dosya adı yollarını devre dışı bıraktığını unutmayın.
İstemci tarafı yönlendirme hala bu yollara erişebilir.
Bu seçeneği kullanırken, programatik olarak istemediğiniz rotalara navigasyona karşı önlem almalısınız.
İstemci tarafı yönlendiricisini, dosya adı yollarına istemci tarafı yönlendirmelerine izin vermeyecek şekilde de yapılandırmak isteyebilirsiniz. Bunun için router.beforePopState'e bakın.
https://jquery.com/upgrade-guide/3.0/
Bu saufada tam olarak geçiş için neler yapılması gerektiğini anlatıyor.
Ayrıca bu kaynakta JQuery Migrate Plugin başlığı altında şöyle yazıyor:
jQuery 1.9/2.0'da yapılan büyük değişikliklerde olduğu gibi, eski kodun 3.0 sürümüne geçişini basitleştirmek için jQuery Migrate Plugin'in yeni bir sürümünü oluşturduk. Bu eklentiyi bir yükseltme aracı olarak kullanmanızı şiddetle tavsiye ederiz, kodunuzu etkileyebilecek büyük değişikliklerin çoğu hakkında özel tavsiyeler verecektir.
Sonra da aynı başlık altında adım adım ne yapmanız gerektiği anlatılmış.
1. Önce sayfada kullandığınız jquery sürümünü 1.x veya 2.x'in en son sürümüne yükseltin. Yani mesela 1.12.0 sürümünü kullanıyorsanız artık 1.12.4 sürümünü kullanın.
2. Sıkıştırılmamış jQuery Migrate 1.x Eklentisini sayfaya ekleyin.
3. Mecbur değil ama önerilir: sonraki sürümler genellikle jQuery'nin en son sürümleriyle en uyumlu olduğundan, kullanımda olan tüm eklentileri güncelleyin.
4. Bir kılavuz olarak JQMIGRATE 1.x uyarı dokümantasyonunu kullanarak sayfayı test edin ve konsolda görünen tüm uyarıları çözün.
5. JQuery Migrate 1.x eklentisini kaldırın ve sayfadaki güncellenmiş jQuery kodunun yalnızca en son jQuery 1.x/2.x kullanımdayken düzgün şekilde çalışmaya devam etmesini sağlayın. Yani sayfanız migrate olmadan JQuery 1.12.4 ile düzgün şekilde çalışabiliyor durumda olsun.
-- Eğer sizin sayfanızda zaten JQuery 1.12.4 yüklüyse ve hiç hata almıyorsanız direkt 6.adımdan da başlayabilirsiniz.
6. Sayfadaki jQuery sürümünü en son 3.x sürümüne (3.6.1) yükseltin ve sıkıştırılmamış jQuery Migrate 3.x eklentisini sayfaya ekleyin.
7. JQMIGRATE 3.x uyarı dokümantasyonunu kılavuz olarak kullanarak sayfayı test edin ve konsolda görünen tüm uyarıları çözün. Üçüncü taraf eklentilerdeki hataları eklenti yazarına bildirin çünkü bu eklenti yeni jquery sürümüyle uyumlu çalışamıyor olabilir.
8. jQuery Migrate 3.x eklentisini kaldırın ve sayfanın düzgün şekilde çalışmaya devam etmesini sağlayın.
Sadece hızlıca bir göz atmanız da yetebilir belki.
Ben çok kullanılan bazı fonksiyonlardaki değişimleri yazdım:
1. Kodunuzda $(window).load() kullanımı varsa bunu $(window).on('load') şeklinde değiştirmelisiniz.
$(window).load(function() {
// ...kodlar
}
yerine şu olmalı:
$(window).on('load', function() {
// ...kodlar
}
).load(function geçen ifadeleri ).on('load', function şeklinde bul-değiştir mantığıyla değiştirebilirsiniz.
2. Kullanılan tarayıcıyı algılamak için artık $.browser kullanamazsınız. Kullanılan tarayıcıyı tespit etmenin başka yollarını kullanmalısınız.
if ($.browser == 'MSIE') {
// Ben internet explorer'ım diyen kodlar...
}
// yerine şöyle bir kod kullanılabilir:
const regex = RegExp('MSIE*');
if (regex.test(navigator.userAgent)) {
// Ben internet explorer'ım diyen kodlar...
}
3. addSelf() yerine addBack() kullanın. Basitçe bul-değiştir mantığıyla halledebilirsiniz.
1,2,3 için Kaynak: https://www.computerminds.co.uk/articles/upgrading-jquery-1x-version-3x
4. size() yerine length kullanın. Kaç eleman seçtiğinizi length ile öğrenebilirsiniz.
5. $.unique() fonksiyonunun adı değişti: $.uniqueSort(). İşlevi aynı, sadece fonksiyon adı değişti.
6. $.ready ifadesi destekleniyor. $.when ile veya Promise yapılarıyla kullanılabilir. Örn:
$.when( $.ready, $.getScript("optional.js") ).then(function() {
// document hazır olduğunda optional.js yüklenip çalıştırlacak...
}).catch( function() {
// işlem sırasında bir hata oluşmuşsa burası çalışacak...
});
7. .width(), .height(), .css("width"), and .css("height") eskiden hep tam sayı olarak dönerdi. Artık daha hassas veri döndüğü için tam sayı yerine küsüratlı sayı da dönebilir.
8. .on("ready", fonksiyon) kaldırıldı. Bunun yerine $(fonksiyon) kullanın.
9. .bind() ve .delegate() kaldırıldı. Bunlar yerine .on() var. Aynı şekilde .unbind() ve .undelegate() yerine de .off() kullanılmalı.
4-9 Kaynak: https://jquery.com/upgrade-guide/3.0/
const newStatus = !$(this).prop('checked');
$(this).prop('checked', newStatus);
şeklinde prop() fonksiyonunu kullanmayı deneyebilirsiniz.
O zaman ekran genişliğini kontrol edip öyle çalıştırın.
<script id="willRemove">
(function () {
var options = {
call: "0 000 000 00 00", // Call phone number
whatsapp: "0 000 000 00 00", // WhatsApp number
call_to_action: "Nasıl yardımcı olabilirim?", // Call to action
button_color: "#FF6550", // Color of button
position: "left", // Position may be 'right' or 'left'
order: "call,whatsapp", // Order of buttons
};
var proto = 'https:', host = "getbutton.io", url = proto + '//static.' + host;
var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = url + '/widget-send-button/js/init.js';
s.onload = function () { WhWidgetSendButton.init(host, proto, options); };
var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(s, x);
})();
// Ekran genişliği 600px veya altındaysa silinsin...
if(window.innerWidth <= 600) {
setTimeout(function(){
// Bu #willRemove id'li script tag'ı kendini 10 milisaniye sonra imha edecek...
document.getElementById('willRemove').remove();
},10);
}
</script>
Kodun çalıştıktan sonra kendini remove etmesini sağlayabilirsiniz.
Bunun için bu kodları bir script tag'ına alın ve bu tag'a bir id verin.
Sonra setTimeout() fonksiyonuyla kodun çalışmasına yetecek kadar kısa bir an izin verin ve bu tag'ı komple silin.
<script id="willRemove">
(function () {
var options = {
call: "0 000 000 00 00", // Call phone number
whatsapp: "0 000 000 00 00", // WhatsApp number
call_to_action: "Nasıl yardımcı olabilirim?", // Call to action
button_color: "#FF6550", // Color of button
position: "left", // Position may be 'right' or 'left'
order: "call,whatsapp", // Order of buttons
};
var proto = 'https:', host = "getbutton.io", url = proto + '//static.' + host;
var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = url + '/widget-send-button/js/init.js';
s.onload = function () { WhWidgetSendButton.init(host, proto, options); };
var x = document.getElementsByTagName('script')[0]; x.parentNode.insertBefore(s, x);
})();
setTimeout(function(){
// Bu #willRemove id'li script tag'ı kendini 10 milisaniye sonra imha edecek...
document.getElementById('willRemove').remove();
},10);
</script>
stackoverflow'da sizinkine benzer bir soru sorulmuş. Kendimce biraz yorum ekleyerek paylaşıyorum:
Array.forEach döngüsünü break çağırır gibi nasıl sonlandırabilirim?
[1,2,3].forEach(function(el) {
if(el === 1) break;
});
Bunu forEach fonksiyonunda nasıl yapabilirim? Ben return;, return:false; ve break denedim... Ama break patlıyor ve return de döngüyü sonlandırmıyor.
Doğru Cevap:
forEach içinde break ile döngüyü sonlandırma özelliği yok. Eğer for kullanamıyorsanız, ille de forEach kullanacaksanız try-catch içinde bir exception fırlatabilirsiniz.
var breakData = {};
try {
[1, 2, 3].forEach(function(el) {
if (el === 2) {
breakData.data = el; // bulduğumuz veriyi breakData objesine aktaralım.
throw breakData; // Objeyi exception (istisna) olarak fırlatalım.
}
});
}
catch (e) {
// Buraya gelindiyse ya throw breakData komutu çalışmıştır ya da başka bir hata oluşmuştur.
// Eğer oluşan exception'da data değeri yoksa bizim oluşturduğumuz hata dışında bir hata oluşmuşsa bunu da görelim.
if(!e.data) console.error(e);
}
// Döngü sonucu oluşan verimiz breakData objesindeki data key'inde.
console.log(breakData.data);
NOT: Kodlarda yaptığım değişikliği test etmedim. Sorun yaşarsanız direkt stackoverflow'daki örneği inceleyebilirsiniz.
Kaynak: https://stackoverflow.com/questions/2641347/short-circuit-array-foreach-like-calling-break
Sizin sorunuza gelecek olursak kodunuzu şu şekilde düzenleyebilirsiniz:
async function getData(data) {
try {
data.forEach(async proxy => {
const content = await arrow(proxy);
if(content.includes("Your file is ready")) {
throw { success: content };
}
});
}
catch(e) {
if(!e.success) {
console.error("Hata oluştu", e);
return false;
}
return e.success;
}
return undefined;
}
Ama bence forEach yerine doğrudan for kullanın.
Böylece throw veya break kullanmak zorunda kalmazsınız.
async function getData(data) {
for(let i = 0; i < data.length; i++) {
const proxy = data[i];
const content = await arrow(proxy);
if(content.includes("Your file is ready")) return content;
}
return null;
}
Veya döngü yerine Array.find kullanın. find, bulduğu ilk elemanı döndürür. Bulamazsa undefined döner.
find içinde hiç async fonksiyon kullanmamıştım ama denemek lazım...
async function getData(data) {
return data.find(
async (proxy) => (await arrow(proxy)).includes("Your file is ready")
);
}
JQuery ile <link> elementinin href attribute'sini değiştirebileceğiniz bir örnek yapalım.
href değerini değiştirmek isteyeceğiniz elemente "data-style-mode" diye bir attribute verelim ki seçebilelim.
<link rel="stylesheet" href="assets/styles/light.css" data-style-mode="light" />
// Elementi jquery ile seçelim.
const $styleElement = $('[data-style-mode]');
// Mod değiştiren fonksiyon
function setStyleMode(type='light') {
if(type=='dark') $styleElement.attr('href', 'assets/styles/dark.css').attr('data-style-mode', 'dark');
else if(type=='light') $styleElement.attr('href', 'assets/styles/light.css').attr('data-style-mode', 'light');
}
// Modu toggle eden fonksiyon
function toggleStyleMode() {
const currentMode = $styleElement.attr('data-style-mode');
setStyleMode(currentMode=='light' ? 'dark' : 'light');
}
Sayfanın modunu anlık olarak güncelleyecektir. Ama sayfa yenilendiğinde veya başka bir sayfaya geçildiğinde bu ayar iptal olmuş olacak.
Kalıcılığı sağlamak için mevcut modu cookie'lere yazabilir ve sunucu taraflı bir kontrolle ilk yüklenen stil dosyasını cookie'deki stil dosyasıyla değiştirebilirsiniz.
JQuery kullanıyorsanız kolay cookie yönetimi için https://github.com/js-cookie/js-cookie projesinden faydalanabilirsiniz.
CDN için: https://cdnjs.com/libraries/js-cookie
Yok ben sunucu tarafına bu işi taşımak istemiyorum, front-end'de halledelim derseniz de localStorage'dan yardım alabilirsiniz.
<head>
<!-- head tag'ı içerikleri -->
<link rel="stylesheet" href="assets/styles/light.css" data-style-mode="light" />
<script>
const $styleElement = $('[data-style-mode]');
if(localStorage.getItem('style-mode')) {
const mode = localStorage.getItem('style-mode');
if(mode=='dark') {
$styleElement.attr('data-style-mode', 'dark').attr('href', 'assets/styles/dark.css');
}
}
</script>
</head>
<body>
<!-- body tag'ı içerikleri -->
<script>
// Mod değiştiren fonksiyon
function setStyleMode(type='light') {
if(type=='dark') $styleElement.attr('href', 'assets/styles/dark.css').attr('data-style-mode', 'dark');
else if(type=='light') $styleElement.attr('href', 'assets/styles/light.css').attr('data-style-mode', 'light');
localStorage.setItem('style-mode', type);
}
// Modu toggle eden fonksiyon
function toggleStyleMode() {
const currentMode = $styleElement.attr('data-style-mode');
const targetMode = currentMode=='light' ? 'dark' : 'light';
setStyleMode(targetMode);
return targetMode;
}
</script>
</body>
@sarjaleti'nin verdiği cevaba biraz javascript eklemenizde mahzur yoksa alternatif olarak şu da mümkün:
- Tüm sayfayı kapsayıcı içine alın. Sonra bu kapsayıcıyı dil sayısı kadar çoğaltın. Her kapsayıcıya da attribute olarak dili yazın.
- Javascript ile body'ye aktif dili attribute olarak ekletin.
- CSS ile body attribute'sine göre hangi dilin görüneceğini belirtin.
<head>
<style>
body > .page-content { display:none; }
body[data-lang="tr"] > .page-content[data-lang="tr] { display:block; }
body[data-lang="en"] > .page-content[data-lang="en] { display:block; }
body[data-lang="es"] > .page-content[data-lang="es] { display:block; }
</style>
<script>
// Dil değiştiren fonksiyon
function changeLanguage(langCode="tr") {
document.body.setAttribute("data-lang", langCode);
}
// Sayfa açılışında aktif olacak dili belirleyelim.
// body elementi onload olduğunda bu veri kullanılarak changeLanguage() fonksiyonu çağırılacak.
const startLanguage = "tr";
</script>
</head>
<body onload="changeLanguage(startLanguage);">
<div class="language-selector">
<button onclick="changeLanguage("tr");">TR</button>
<button onclick="changeLanguage("en");">EN</button>
<button onclick="changeLanguage("es");">ES</button>
</div>
<section class="page-container" data-lang="tr">
Tüm sayfanın Türkçe içerikli HTML kodu burada barınacak.
</section>
<section class="page-container" data-lang="en">
Tüm sayfanın İngilizce içerikli HTML kodu burada barınacak.
</section>
<section class="page-container" data-lang="es">
Tüm sayfanın İspanyolca içerikli HTML kodu burada barınacak.
</section>
</body>
Bu kurguyu sitenizdeki tüm sayfalara uygulamalısınız. Ama bazı sorunlarla karşılaşmış olacaksınız.
- Başka bir sayfaya geçtiğinizde seçtiğiniz dil kaybolacak ve ana dile ("tr") dönmüş olacaksınız.
- Siteyi kapatıp tekrar açtığınızda seçtiğiniz dil kaybolacak ve yeniden dil seçmek zorunda kalacaksınız.
Bu durumda seçilen dili tarayıcıya kaydetmek ve sayfa açıldığında kayıtlı bir dil olup olmadığını kontrol edip direkt o dili aktif etmek gerekir.
Yukarıda head tag'ında bulunan script tag'ını şu şekilde değiştirebiliriz:
// Dil değiştiren fonksiyon
function changeLanguage(langCode="tr") {
document.body.setAttribute("data-lang", langCode);
// seçilen dili local storage'a kaydedelim:
localStorage.setItem("selected-language", langCode);
}
// Daha önce local storage'a yazılmış dil verisini alalım.
const storagedLanguage = localStorage.getItem("selected-languge");
// Local storage'dan dil verisi alabildiysek bunu kullanalım. Bulamadıysak varsayılan dilimizi kullanalım.
const startLanguage = storagedLanguage ? storagedLanguage : "tr";