Tarayıcı Geri Düğmesi olayı nasıl algılanır - Çapraz Tarayıcı


219

Kullanıcının tarayıcıdaki geri düğmesine basıp basmadığını kesin olarak nasıl tespit edersiniz?

#URLSistemi kullanarak tek sayfalık bir web uygulamasında sayfa içi geri düğmesinin kullanımını nasıl zorlarsınız ?

Neden dünyadaki tarayıcı geri düğmeleri kendi olaylarını ateşlemiyor !?


2
Navigasyon etkinliklerinin (geri / ileri) bir ara zamanda eklenmesini dilerim. Şimdiye kadar bu işlerde olan bir şey developer.mozilla.org/tr-TR/docs/Web/API/…
llaaalu

Yanıtlar:


184

(Not: Sharky'nin geri bildirimlerine göre, arka alanları algılamak için kod ekledim)

Yani, bu soruları SO'da sık sık gördüm ve son zamanlarda geri düğmesi işlevselliğini kendim kontrol etme sorunuyla karşılaştım. Uygulamam için en iyi çözümü (Hash Navigation ile Tek Sayfa) aradıktan birkaç gün sonra, geri düğmesini algılamak için basit, çapraz tarayıcı, kitaplıksız bir sistem buldum.

Çoğu kişi şunları kullanmanızı önerir:

window.onhashchange = function() {
 //blah blah blah
}

Ancak, bu işlev, kullanıcı konum karmasını değiştiren sayfa içi öğeyi kullandığında da çağrılır. Kullanıcınız tıkladığında ve sayfa ileri veya geri gittiğinde en iyi kullanıcı deneyimi olmaz.

Size sistemimin genel bir taslağını vermek için, kullanıcı arayüzde ilerledikçe önceki karmaları içeren bir dizi dolduruyorum. Şuna benziyor:

function updateHistory(curr) {
    window.location.lasthash.push(window.location.hash);
    window.location.hash = curr;
}

Oldukça düz ileri. Bunu çapraz tarayıcı desteğinin yanı sıra eski tarayıcılar için de destek sağlamak amacıyla yapıyorum. Yeni karmayı işleve iletmeniz yeterlidir ve sizin için saklar ve ardından karmayı değiştirir (bu daha sonra tarayıcının geçmişine konur).

Ayrıca lasthashdiziyi kullanarak kullanıcıyı sayfalar arasında hareket ettiren bir sayfa içi geri düğmesi de kullanıyorum . Şöyle görünüyor:

function goBack() {
    window.location.hash = window.location.lasthash[window.location.lasthash.length-1];
    //blah blah blah
    window.location.lasthash.pop();
}

Yani bu kullanıcıyı son karmaya geri taşıyacak ve son karmayı diziden kaldıracağım (şu anda ileri düğmesi yok).

Yani. Bir kullanıcının sayfa içi geri düğmemi mi yoksa tarayıcı düğmesini mi kullandığını nasıl anlarım?

İlk başta baktım window.onbeforeunload, ama boşuna - bu sadece kullanıcı sayfaları değiştirecekse çağrılır. Bu, karma gezinme kullanan tek sayfalık bir uygulamada gerçekleşmez.

Böylece, biraz daha kazdıktan sonra, bir bayrak değişkeni ayarlamaya çalışmak için öneriler gördüm. Benim durumumda bu, onu ayarlamaya çalışacağım, ama her şey asenkron olduğundan, her zaman karma değişikliği if deyimi için zamanında ayarlanmazdı. .onMouseDownher zaman tıklamada çağrılmadı ve bir onclick'e eklemek hiçbir zaman yeterince hızlı tetiklemeyecekti.

Bu document, ve arasındaki farka bakmaya başladığım zamandı window. Son çözümüm bayrağı kullanarak ayarlamak document.onmouseoverve devre dışı bırakmaktı document.onmouseleave.

Kullanıcının faresi belge alanının içindeyken (okuyun: işlenen sayfa, ancak tarayıcı çerçevesi hariç), boolean'ım olarak ayarlandı true. Fare belge alanından ayrılır ayrılmaz boole çevrilir false.

Bu şekilde, benim window.onhashchange:

window.onhashchange = function() {
    if (window.innerDocClick) {
        window.innerDocClick = false;
    } else {
        if (window.location.hash != '#undefined') {
            goBack();
        } else {
            history.pushState("", document.title, window.location.pathname);
            location.reload();
        }
    }
}

Çeki not edeceksiniz #undefined. Bunun nedeni, dizimde hiçbir geçmişin olmaması durumunda geri dönmesidir undefined. Bunu kullanıcıya bir window.onbeforeunloadolay kullanarak ayrılmak isteyip istemediklerini sormak için kullanıyorum .

Kısacası, geçmişi depolamak için bir sayfa içi geri düğmesi veya bir dizi kullanması gerekmeyen insanlar için:

document.onmouseover = function() {
    //User's mouse is inside the page.
    window.innerDocClick = true;
}

document.onmouseleave = function() {
    //User's mouse has left the page.
    window.innerDocClick = false;
}

window.onhashchange = function() {
    if (window.innerDocClick) {
        //Your own in-page mechanism triggered the hash change
    } else {
        //Browser back button was clicked
    }
}

İşte buyur. karma gezinme ile ilgili sayfa içi öğelere karşı geri düğmesi kullanımını algılamanın basit, üç bölümlü bir yolu.

DÜZENLE:

Kullanıcının back olayını tetiklemek için backspace kullanmadığından emin olmak için aşağıdakileri de ekleyebilirsiniz ( Bu Soru'daki @thetoolman sayesinde ):

$(function(){
    /*
     * this swallows backspace keys on any non-input element.
     * stops backspace -> back
     */
    var rx = /INPUT|SELECT|TEXTAREA/i;

    $(document).bind("keydown keypress", function(e){
        if( e.which == 8 ){ // 8 == backspace
            if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                e.preventDefault();
            }
        }
    });
});

5
+ 1 güzel fikir, ama fare tarayıcı penceresinin içindeyken kullanıcı "geri" (firefox üzerinde geri tuşu) için ne olursa olsun klavye kısayolu kullanırsa bu başarısız olacağını düşünüyorum
Sharky

3
Yapacağım - Ben şu anda zaten ofisteyim :) (DÜZENLE: Şimdi bitti)
Xarus

7
Cep telefonu (örneğin ipad) hakkında
Basarat

5
MAC'deki izleme dörtgeninden hızlıca kaydırma olaylarına ne dersiniz? Bu da yakalanabilir mi?
Sriganesh Navaneethakrishnan

6
İleri ve geri düğmelerini nasıl ayırt edebilirim?
Mr_Perfect

79

popstateOlay işleyiciyi deneyebilirsiniz , örneğin:

window.addEventListener('popstate', function(event) {
    // The popstate event is fired each time when the current history entry changes.

    var r = confirm("You pressed a Back button! Are you sure?!");

    if (r == true) {
        // Call Back button programmatically as per user confirmation.
        history.back();
        // Uncomment below line to redirect to the previous page instead.
        // window.location = document.referrer // Note: IE11 is not supporting this.
    } else {
        // Stay on the current page.
        history.pushState(null, null, window.location.pathname);
    }

    history.pushState(null, null, window.location.pathname);

}, false);

Not: En iyi sonuçları elde etmek için, bu kodu yalnızca beklenmedik sorunlardan kaçınmak için mantığı uygulamak istediğiniz belirli sayfalara yüklemelisiniz.

Geçerli geçmiş girişi her değiştiğinde (kullanıcı yeni bir duruma geçtiğinde) popstate olayı tetiklenir. Bu tarayıcınızın Geri / İleri düğmeleri veya tıkladığında ne olur history.back(), history.forward(), history.go()yöntemler programlama yoluyla denir.

event.stateOlayın olduğu mülkiyet geçmiş durum nesnesi eşittir.

JQuery sözdizimi için etrafına sarın (belge hazır olduktan sonra bile dinleyici eklemek için):

(function($) {
  // Above code here.
})(jQuery);

Ayrıca bkz: window.onpopstate sayfa yükleme


Ayrıca Tek Sayfalı Uygulamalar ve HTML5 pushState sayfasındaki örneklere bakın:

<script>
// jQuery
$(window).on('popstate', function (e) {
    var state = e.originalEvent.state;
    if (state !== null) {
        //load content with ajax
    }
});

// Vanilla javascript
window.addEventListener('popstate', function (e) {
    var state = e.state;
    if (state !== null) {
        //load content with ajax
    }
});
</script>

Bunun Chrome 5+, Firefox 4+, IE 10+, Safari 6+, Opera 11.5+ ve benzeri ile uyumlu olması gerekir.


2
Kenorb, popstate'in değişikliği yakalamak için çalıştığını doğru söylüyorsunuz, ancak programlı olarak olayı çağırmakla kullanıcı tarayıcının düğmelerini tıklattığında ayrım yapmıyor.
Xarus

1
Tek Sayfalı Uygulamalar ve HTML5 pushState için harika yayın . Modern "bir sayfa düzenleri" veya "tek sayfa uygulamaları" için mükemmeldir. Bağlantı ve cevabınız için teşekkür ederiz!
lowtechsun

1
e.state, modern tarayıcılarda her zaman tanımsız görünüyor
FAjir

Doğrudan burada çalıştırabilmeniz için kodunuzu bir pasaja koymanızı öneririm.
FourCinnamon0

16

Bir süredir bu gereksinimle mücadele ediyordum ve uygulamak için yukarıdaki çözümlerden bazılarını aldım. Ancak, bir gözlemle karşılaştım ve Chrome, Firefox ve Safari tarayıcıları + Android ve iPhone'da çalışıyor gibi görünüyor

Sayfa yüklenirken:

window.history.pushState({page: 1}, "", "");

window.onpopstate = function(event) {

  // "event" object seems to contain value only when the back button is clicked
  // and if the pop state event fires due to clicks on a button
  // or a link it comes up as "undefined" 

  if(event){
    // Code to handle back button or prevent from navigation
  }
  else{
    // Continue user action through link or button
  }
}

Bunun yardımcı olup olmadığını bana bildirin. Bir şey eksikse, anlamaktan mutluluk duyacağım.


1
Doğru değil. eventileri düğmesi için bile değeri var
Daniel Birowsky Popeski

14

Javascript'te gezinme türü 2, tarayıcının geri veya ileri düğmesi tıklatıldığı ve tarayıcının aslında önbellekten içerik aldığı anlamına gelir.

if(performance.navigation.type == 2)
{
    //Do your code here
}

1
Bu, tek sayfalık bir uygulamada çalışmaz, sonuç her zaman 1'dir (yani yeniden yükleme anlamına gelir). Dahası, çok talihsiz olan geri ve ileri düğmesi arasındaki farkı yapmaz.
papillon

"Üstelik bu, talihsiz bir şekilde geri ve ileri düğmesi arasındaki farkı oluşturmaz." Evet, çünkü veriler önbellekten her zaman alındığında performans.navigation.type 2
Hasan Badshah

Tüm tarayıcılarda çalışacağı garanti edilmez! bu nedenle şöyle bir şey yazmalısınız: if (window.performance) {// performansla ilgili kodunuz} da daha fazla okunabilirlik için 2 yerine TYPE_BACK_FORWARD kullanmak daha iyidir.
blank94

7

Bu kesinlikle işe yarar (Geri düğmesini tıklamak için tıklayın)

$(window).on('popstate', function(event) {
 alert("pop");
});

6

Bunu gör:

history.pushState(null, null, location.href);
    window.onpopstate = function () {
        history.go(1);
    };

iyi çalışıyor...


Chrome 78.0.3904.70'de (Resmi Derleme) (64 bit)
çalışmıyor

Brave v1.3.118 >> Chromium: 80.0.3987.116 (Resmi Derleme) (64 bit) üzerinde çalışma
doğrulandı

Sayfaya harici bir siteden geldiyseniz çalışmaz.
Milan Vlach

5
if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
  alert('hello world');
}

Bu benim için çalışan tek çözüm (bir web sitesi değil). Chrome, Firefox ve Safari ile çalışıyor.


1
window.performance.navigation kullanımdan kaldırıldı. İşte docs developer.mozilla.org/tr-TR/docs/Web/API/Performance/navigation
llaaalu

Bu benim için .cshtml sayfamda çalıştı. Chrome ve IE'de başarıyla çalıştı. Teşekkürler
Justjyde

5

Soruyu cevaplamak için doğru cevap zaten var. Yeni JavaScript API PerformanceNavigationTiming'den bahsetmek istiyorum , kullanımdan kaldırılmış performance.navigation'ın yerini alıyor .

Kullanıcı geri veya ileri düğmesini kullanarak sayfanıza geldiyse, aşağıdaki kod "back_forward" konsolunda oturum açar. Projenizde kullanmadan önce uyumluluk tablosuna bir göz atın.

var perfEntries = performance.getEntriesByType("navigation");
for (var i = 0; i < perfEntries.length; i++) {
    console.log(perfEntries[i].type);
}

Bu, bu sayfada bir geri düğmesinin tıklanıp tıklanmadığını anlamanın bir yolu değildir . O eğer söyler son sayfada tıklandığı .
Seph Reed

Ama bu aradığım asıl cevap oldu çünkü ben geri sorunu vurduktan sonra aldım ve daha önce değil yinelenen istekleri sorunları durduran bazı yanıt kodu inşa edebilirsiniz anlamına gelir. Teşekkürler.
Andrew

1
Bu soruya cevap olmayabilir, ama tam olarak ihtiyacım olan şey! Güzel bir - Bunu bilmiyordum ...
Hogsmill

4

Tarayıcı: https://jsfiddle.net/Limitlessisa/axt1Lqoz/

Mobil kontrol için: https://jsfiddle.net/Limitlessisa/axt1Lqoz/show/

$(document).ready(function() {
  $('body').on('click touch', '#share', function(e) {
    $('.share').fadeIn();
  });
});

// geri butonunu yakalama
window.onhashchange = function(e) {
  var oldURL = e.oldURL.split('#')[1];
  var newURL = e.newURL.split('#')[1];

  if (oldURL == 'share') {
    $('.share').fadeOut();
    e.preventDefault();
    return false;
  }
  //console.log('old:'+oldURL+' new:'+newURL);
}
.share{position:fixed; display:none; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,.8); color:white; padding:20px;
<!DOCTYPE html>
<html>

<head>
    <title>Back Button Example</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

</head>

<body style="text-align:center; padding:0;">
    <a href="#share" id="share">Share</a>
    <div class="share" style="">
        <h1>Test Page</h1>
        <p> Back button press please for control.</p>
    </div>
</body>

</html>


Bu, sorulan soruya cevap vermiyor. Soru, bir sayfa içi geri düğmesinin, tarayıcının yerel geri düğmesine karşı kullanımını algılamakla ilgilidir.
Xarus

2
Soru jquery değil, javascript olarak etiketlenir.
skwny

3

İşte benim almam. Varsayım, URL değiştiğinde, ancak documenttespit edilen içinde hiçbir tıklama olmadığında , bu bir tarayıcı geri (evet veya ileri). Bir kullanıcının tıklaması, Ajax aracılığıyla içerik yükleyen sayfalarda çalışmasını sağlamak için 2 saniye sonra sıfırlanır:

(function(window, $) {
  var anyClick, consoleLog, debug, delay;
  delay = function(sec, func) {
    return setTimeout(func, sec * 1000);
  };
  debug = true;
  anyClick = false;
  consoleLog = function(type, message) {
    if (debug) {
      return console[type](message);
    }
  };
  $(window.document).click(function() {
    anyClick = true;
    consoleLog("info", "clicked");
    return delay(2, function() {
      consoleLog("info", "reset click state");
      return anyClick = false;
    });
  });
  return window.addEventListener("popstate", function(e) {
    if (anyClick !== true) {
      consoleLog("info", "Back clicked");
      return window.dataLayer.push({
        event: 'analyticsEvent',
        eventCategory: 'test',
        eventAction: 'test'
      });
    }
  });
})(window, jQuery);

2

IE ve Chrome / Edge'de çalışmasını sağlamak için bu konudaki bazı cevapları ve diğerlerini kullanabildim. history.pushState benim için IE11'de desteklenmedi.

if (history.pushState) {
    //Chrome and modern browsers
    history.pushState(null, document.title, location.href);
    window.addEventListener('popstate', function (event) {
        history.pushState(null, document.title, location.href);
    });
}
else {
    //IE
    history.forward();
}

Bunu Chrome 78.0.3904.70 (Resmi Derleme) (64 bit) üzerinde denedim ve işe yaramadı.
Jeffz

2

Tam teşekküllü bir bileşen, yalnızca API'yi yeniden tanımladığınızda ('tarih' nesnesinin yöntemlerini değiştirirseniz) uygulanabilir. Chrome ve Mozilla Desteği'nde yalnızca HTML5 ve ECMAScript5-6'da test edildi

class HistoryNavigation {
    static init()
    {
        if(HistoryNavigation.is_init===true){
            return;
        }
        HistoryNavigation.is_init=true;

        let history_stack=[];
        let n=0;
        let  current_state={timestamp:Date.now()+n};
        n++;
        let init_HNState;
        if(history.state!==null){
            current_state=history.state.HNState;
            history_stack=history.state.HNState.history_stack;
            init_HNState=history.state.HNState;
        } else {
            init_HNState={timestamp:current_state.timestamp,history_stack};
        }
        let listenerPushState=function(params){
            params=Object.assign({state:null},params);
            params.state=params.state!==null?Object.assign({},params.state):{};
            let h_state={ timestamp:Date.now()+n};
            n++;
            let key = history_stack.indexOf(current_state.timestamp);
            key=key+1;
            history_stack.splice(key);
            history_stack.push(h_state.timestamp);
            h_state.history_stack=history_stack;
            params.state.HNState=h_state;
            current_state=h_state;
            return params;
        };
        let listenerReplaceState=function(params){
            params=Object.assign({state:null},params);
            params.state=params.state!==null?Object.assign({},params.state):null;
            let h_state=Object.assign({},current_state);
            h_state.history_stack=history_stack;
            params.state.HNState=h_state;
            return params;
        };
        let desc=Object.getOwnPropertyDescriptors(History.prototype);
        delete desc.constructor;
        Object.defineProperties(History.prototype,{

            replaceState:Object.assign({},desc.replaceState,{
                value:function(state,title,url){
                    let params={state,title,url};
                    HistoryNavigation.dispatchEvent('history.state.replace',params);
                    params=Object.assign({state,title,url},params);
                    params=listenerReplaceState(params);
                    desc.replaceState.value.call(this,params.state,params.title,params.url);
                }
            }),
            pushState:Object.assign({},desc.pushState,{
                value:function(state,title,url){
                    let params={state,title,url};
                    HistoryNavigation.dispatchEvent('history.state.push',params);
                    params=Object.assign({state,title,url},params);
                    params=listenerPushState(params);
                    return desc.pushState.value.call(this, params.state, params.title, params.url);
                }
            })
        });
        HistoryNavigation.addEventListener('popstate',function(event){
            let HNState;
            if(event.state==null){
                HNState=init_HNState;
            } else {
                HNState=event.state.HNState;
            }
            let key_prev=history_stack.indexOf(current_state.timestamp);
            let key_state=history_stack.indexOf(HNState.timestamp);
            let delta=key_state-key_prev;
            let params={delta,event,state:Object.assign({},event.state)};
            delete params.state.HNState;
            HNState.history_stack=history_stack;
            if(event.state!==null){
                event.state.HNState=HNState;
            }
            current_state=HNState;
            HistoryNavigation.dispatchEvent('history.go',params);
        });

    }
    static addEventListener(...arg)
    {
        window.addEventListener(...arg);
    }
    static removeEventListener(...arg)
    {
        window.removeEventListener(...arg);
    }
    static dispatchEvent(event,params)
    {
        if(!(event instanceof Event)){
            event=new Event(event,{cancelable:true});
        }
        event.params=params;
        window.dispatchEvent(event);
    };
}
HistoryNavigation.init();

// exemple

HistoryNavigation.addEventListener('popstate',function(event){
    console.log('Will not start because they blocked the work');
});
HistoryNavigation.addEventListener('history.go',function(event){
    event.params.event.stopImmediatePropagation();// blocked popstate listeners
    console.log(event.params);
    // back or forward - see event.params.delta

});
HistoryNavigation.addEventListener('history.state.push',function(event){
    console.log(event);
});
HistoryNavigation.addEventListener('history.state.replace',function(event){
    console.log(event);
});
history.pushState({h:'hello'},'','');
history.pushState({h:'hello2'},'','');
history.pushState({h:'hello3'},'','');
history.back();

    ```

Güzel yaklaşım! Buna eklediğiniz için teşekkürler (Hala uzun yıllar sonra bu konu üzerinde konuşma olduğunu şaşırtıcı buluyorum)
Xarus

Bu akıllıca bir geçmiş izleme mekanizması gibi görünüyor. Ancak, kod önerilmemektedir, bu nedenle takip edilmesi oldukça zordur. Birisi geçerli sayfadan ayrılırsa, bu düğmeye basıldığını algılamaz ve bu da "Kullanıcının tarayıcıdaki geri düğmesine basıp basmadığını kesin olarak nasıl tespit edersiniz?" Düğmeler ve geçmiş izleme, biri diğerini tetiklese bile iki farklı şeydir. Hala konuşma olması, web tarayıcısı tasarımında büyük bir kusur olduğunu gösteriyor.
CubicleSoft

1

Document.mouseover, IE ve FireFox için çalışmaz. Ancak bunu denedim:

$(document).ready(function () {
  setInterval(function () {
    var $sample = $("body");
    if ($sample.is(":hover")) {
      window.innerDocClick = true;
    } else {
      window.innerDocClick = false;
    }
  });

});

window.onhashchange = function () {
  if (window.innerDocClick) {
    //Your own in-page mechanism triggered the hash change
  } else {
    //Browser back or forward button was pressed
  }
};

Bu, FireFox için değil Chrome ve IE için çalışır. Hala FireFox'u düzeltmek için çalışıyor. Tarayıcı geri / ileri düğmesine tıklamayı tespit etmenin herhangi bir kolay yolu, özellikle JQuery'de değil, aynı zamanda AngularJS veya düz Javascript'te de kabul edilir.


1
 <input style="display:none" id="__pageLoaded" value=""/>


 $(document).ready(function () {
        if ($("#__pageLoaded").val() != 1) {

            $("#__pageLoaded").val(1);


        } else {
            shared.isBackLoad = true;
            $("#__pageLoaded").val(1);  

            // Call any function that handles your back event

        }
    });

Yukarıdaki kod benim için çalıştı. Mobil tarayıcılarda, kullanıcı geri düğmesini tıkladığında, önceki ziyaretine göre sayfa durumunu geri yüklemek istedik.


Yukarıdaki kod benim için çalıştı, mobil tarayıcılarda, kullanıcılar geri düğmesini tıkladığında, önceki ziyaretine göre sayfa durumunu geri yüklemek istedik
Ashwin

0

Bir tetikleme hashchange, bir tıklama veya bir tekerlek olsun) tetikleyen orijinal etkinliği takip ederek çözdüm , böylece etkinlik sayfaya basit bir açılışla karıştırılmayacak ve her etkinlik bağlantım. Tarayıcı false, geri düğmesine basıldığında bayrağı tekrar olarak ayarlamaz :

var evt = null,
canGoBackToThePast = true;

$('#next-slide').on('click touch', function(e) {
    evt = e;
    canGobackToThePast = false;
    // your logic (remember to set the 'canGoBackToThePast' flag back to 'true' at the end of it)
}

-21

Yukarıdaki seçenekleri denedim ama hiçbiri benim için çalışmıyor. İşte çözüm

if(window.event)
   {
        if(window.event.clientX < 40 && window.event.clientY < 0)
        {
            alert("Browser back button is clicked...");
        }
        else
        {
            alert("Browser refresh button is clicked...");
        }
    }

Daha fazla bilgi için bu bağlantıya http://www.codeproject.com/Articles/696526/Solution-to-Browser-Back-Button-Click-Event-Handli bakın


8
@MunamYousuf Bu kod parçasının neden işe yaramadığı çok açık. Tarayıcının geri düğmesini izler, ancak düğme görünüm penceresinin dışındadır, bu nedenle clientX ve clientY koordinatları alınamaz. Çalıştığını varsayarsak, iOS'a ne dersiniz? Geri düğmesi altta ... Yazılma şekli de süper verimsiz, tetiklenen her olay için bir şarttır ... Tanrı o kadar kötü ki, aşağı oy vereceğim.
James Wong - Monica'yı eski

Bu çok korkunç! neden böyle bir şey yapasın? : ve James'in dediği gibi çalışmayacak.
msqar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.