পুশস্টেট সদৃশ ইতিহাস এন্ট্রিগুলি তৈরি করে এবং পূর্ববর্তীগুলিকে ওভাররাইট করে


15

আমি একটি ওয়েব অ্যাপ তৈরি করেছি যা ইতিহাস আপডেট করার সময় পৃষ্ঠাগুলি নেভিগেট করার জন্য পদ্ধতি history pushStateএবং replaceStateপদ্ধতিগুলি ব্যবহার করে ।

লিপি নিজেই প্রায় নিখুঁতভাবে কাজ করে; এটি পৃষ্ঠাগুলি সঠিকভাবে লোড করবে এবং পৃষ্ঠার ত্রুটিগুলি নিক্ষেপ করার দরকার পড়বে। তবে, আমি একটি অদ্ভুত সমস্যা লক্ষ্য করেছি যেখানে pushStateইতিহাসে একাধিক, সদৃশ এন্ট্রিগুলি (এবং তার আগে এন্ট্রিগুলি প্রতিস্থাপন করবে) ঠেলে দেবে।

উদাহরণস্বরূপ, আসুন আমি বলি যে আমি নিম্নলিখিতগুলি (ক্রমে) করছি:

  1. Index.php লোড আপ (ইতিহাস হবে: সূচক)

  2. প্রোফাইল.php এ নেভিগেট করুন (ইতিহাসটি হবে: প্রোফাইল, সূচি)

  3. Search.php এ নেভিগেট করুন (ইতিহাসটি হবে: অনুসন্ধান, অনুসন্ধান, সূচি)

  4. ড্যাশবোর্ড.এফপি নেভিগেট করুন

তারপরে অবশেষে, এটিই আমার ইতিহাসে আসবে (সর্বাধিক অতি প্রাচীনতম অনুসারে):

ড্যাশবোর্ড
ড্যাশবোর্ড
ড্যাশবোর্ড
অনুসন্ধান
সূচি

এটির সাথে সমস্যাটি হ'ল কোনও ব্যবহারকারী যখন ফরোয়ার্ড বা পিছনের বোতামগুলিতে ক্লিক করেন, তারা হয় ভুল পৃষ্ঠায় পুনর্নির্দেশিত হবে, বা একবার ফিরে যেতে একবারে একাধিকবার ক্লিক করতে হবে। এটি, এবং যদি তারা যায় এবং তাদের ইতিহাসটি পরীক্ষা করে তবে তা কোনও অর্থ দেবে না।

আমার এ পর্যন্ত যা আছে:

var Traveller = function(){
    this._initialised = false;

    this._pageData = null;
    this._pageRequest = null;

    this._history = [];
    this._currentPath = null;
    this.abort = function(){
        if(this._pageRequest){
            this._pageRequest.abort();
        }
    };
    // initialise traveller (call replaceState on load instead of pushState)
    return this.init();
};

/*1*/Traveller.prototype.init = function(){
    // get full pathname and request the relevant page to load up
    this._initialLoadPath = (window.location.pathname + window.location.search);
    this.send(this._initialLoadPath);
};
/*2*/Traveller.prototype.send = function(path){
    this._currentPath = path.replace(/^\/+|\/+$/g, "");

    // abort any running requests to prevent multiple
    // pages from being loaded into the DOM
    this.abort();

    return this._pageRequest = _ajax({
        url: path,
        dataType: "json",
        success: function(response){
            // render the page to the dom using the json data returned
            // (this part has been skipped in the render method as it
            // doesn't involve manipulating the history object at all
            window.Traveller.render(response);
        }
    });
};
/*3*/Traveller.prototype.render = function(data){
    this._pageData = data;
    this.updateHistory();
};
/*4*/Traveller.prototype.updateHistory = function(){
    /* example _pageData would be:
    {
        "page": {
            "title": "This is a title",
            "styles": [ "stylea.css", "styleb.css" ],
            "scripts": [ "scripta.js", "scriptb.js" ]
        }
    }
    */
    var state = this._pageData;
    if(!this._initialised){
        window.history.replaceState(state, state.title, "/" + this._currentPath);
        this._initialised = true;
    } else {
        window.history.pushState(state, state.title, "/" + this._currentPath);  
    }
    document.title = state.title;
};

Traveller.prototype.redirect = function(href){
    this.send(href);
};

// initialise traveller
window.Traveller = new Traveller();

document.addEventListener("click", function(event){
    if(event.target.tagName === "a"){
        var link = event.target;
        if(link.target !== "_blank" && link.href !== "#"){
            event.preventDefault();
            // example link would be /profile.php
            window.Traveller.redirect(link.href);
        }
    }
});

সমস্ত সাহায্য প্রশংসা করা হয়,
চিয়ার্স।


সুতরাং আপনি কেবলমাত্র ইতিহাসের পরিবর্তনের প্রচার করতে চান যদি লক্ষ্যটি শেষ এন্ট্রি থেকে আলাদা হয়?
আলুয়ান হাদ্দাদ

এটা কি দৃশ্যত এলোমেলোভাবে ঘটছে? বা সুনির্দিষ্ট পৃষ্ঠাগুলি হ'ল সদৃশ ইতিহাসের এন্ট্রিগুলির কারণ।
SamVK

@ অ্যালুয়ানহাদদাদ না আমি কেবল ইতিহাসের পরিবর্তনের প্রচার করতে চাই যদি কোনও ইতিহাসের পরিবর্তন হয় (যেমন, যখন কোনও ব্যবহারকারী সাইটের মাধ্যমে চলাচল করছে)। সাধারণ পরিস্থিতিতে যা ঘটবে তার অনুরূপ ... (স্ট্যাকওভারফ্লোতে অনুসন্ধানে সূচী থেকে প্রোফাইলে যাওয়া আমার ইতিহাসে হুবহু ফিরে আসবে)
GROVER।

@ সামভিকে প্রাথমিক পৃষ্ঠা লোড পৃষ্ঠা (যেমন সূচক। পিএফপি) থেকে চারপাশে নেভিগেট করার পরে কোনও পৃষ্ঠা গুরুত্বপূর্ণ নয়, এন্ট্রিগুলি সেগুলি নকল করবে।
গ্রোয়ার

1
ঠিক আছে, আমি মন্তব্য সম্পর্কে এতটা লেখার বিষয়ে যথেষ্ট নিশ্চিত নই। আমি দেখতে পাচ্ছি আপনি নিজের updateHistoryফাংশনে ব্রাউজারের ইতিহাসের জিনিসগুলি যুক্ত করছেন । updateHistoryআপনি যখন ট্র্যাভেলারটিকে ( window.Traveller = new Traveller();, constructor-> init-> send-> render-> -> updateHistory) আরম্ভ করছেন তখন এখন, দু'বার কল করা যেতে পারে , তারপরেও ইভেন্টলিস্টনার redirectথেকে click। আমি এটি পরীক্ষা করেছি না, কেবল বুনো অনুমান করা, সুতরাং এটি একটি মন্তব্য হিসাবে যুক্ত করা এবং উত্তর নয়।
অক্ষিত অরোরা

উত্তর:


3

আপনার কি অনপপস্টেট হ্যান্ডলার আছে?

যদি হ্যাঁ, তবে আপনি ইতিহাসের দিকে এগিয়ে যাচ্ছেন না তাও সেখানে পরীক্ষা করে দেখুন। ইতিহাসের তালিকায় কিছু এন্ট্রি সরানো / প্রতিস্থাপন করা বড় চিহ্ন হতে পারে। সত্যই, এই এই উত্তরটি দেখুন :

মনে রাখবেন যে ইতিহাস.পুশ স্টেট () নতুন ইতিহাসের স্থিতি হিসাবে একটি নতুন রাষ্ট্রকে সেট করে। এবং উইন্ডোঅনপপস্টেটকে বলা হয়েছে যে আপনি যে রাজ্যগুলি সেট করেছেন সেগুলির মধ্যে নেভিগেট করার সময় (পিছনে / ফরোয়ার্ড)।

সুতরাং উইন্ডো.অনপপস্টেট ডাকা হলে পুশস্টেটটি করবেন না, কারণ এটি নতুন রাষ্ট্রকে শেষ রাজ্য হিসাবে সেট করবে এবং তারপরে এগিয়ে যাওয়ার মতো কিছুই নেই।

আপনার বর্ণনা অনুসারে আমার একবারে একই সমস্যা হয়েছিল, তবে এটি আসলে আমার পিছনে পিছনে গিয়ে বাগটি বোঝার চেষ্টা করার কারণে ঘটেছিল যা শেষ পর্যন্ত পপস্টেট হ্যান্ডলারটিকে ট্রিগার করবে। এই হ্যান্ডলারটি থেকে, এটি তখন ইতিহাস বলে। সুতরাং শেষে, আমার কাছে কোনও যৌক্তিক ব্যাখ্যা ছাড়াই কিছু অনুলিপি প্রবেশও ছিল এবং কিছু অনুপস্থিত।

আমি কলটিটি হিস্ট্রি.পুশ-এ সরিয়েছি, কিছু শর্তাদি যাচাই করার পরে এবং ইতিহাসের মোড়ের মতো কাজ করার পরে এটি ইতিহাসের পরিবর্তে প্রতিস্থাপন করেছি :)

সম্পাদনা করুন -> টিপ

আপনি যদি সনাক্ত করতে না পারেন যে কোডটি ইতিহাস কল করছে pপুস্ট স্টেট:

ইতিহাসটি ওভাররাইট করে চেষ্টা করুন .পুস্ট স্টেট এবং নিম্নলিখিত কোডের সাথে স্টেট ফাংশনগুলি প্রতিস্থাপন করুন:

window.pushStateOriginal = window.history.pushState.bind(window.history);
window.history.pushState = function () {
    var args = Array.prototype.slice.call(arguments, 0);
    let allowPush  = true;
    debugger;
    if (allowPush ) {
        window.pushStateOriginal(...args);
    }
}
//the same for replaceState
window.replaceStateOriginal = window.history.replaceState.bind(window.history);
window.history.replaceState = function () {
    var args = Array.prototype.slice.call(arguments, 0);
    let allowReplace  = true;
    debugger;
    if (allowReplace) {
        window.replaceStateOriginal(...args);
    }
}

তারপরে প্রতিটি বার ব্রেকপয়েন্টগুলি ট্রিগার হয়ে গেলে কল স্ট্যাকটি একবার দেখুন।

কনসোলে, আপনি যদি কোনও পুসস্টেট প্রতিরোধ করতে চান তবে সুনির্দিষ্টভাবে প্রবেশ করুন allowPush = false;বা allowReplace = false;পুনরায় শুরু করার আগে। এইভাবে, আপনি কোনও হিস্টোস.পুশ স্টেট মিস করবেন না, এবং গিয়ে কোডটি খুঁজে পেতে পারেন :)


আমি করি, তবে এটি ইতিহাসকে মোটেও ঠেলা বা প্রতিস্থাপন করে না: / কেবল পৃষ্ঠাটি রেন্ডার করে
GROVER V

সত্যিই অদ্ভুত. নীচের কোডের সাথে ইতিহাসের উপর চাপুন overw এইচপি (লোকেশন)} এবং ইতিহাস.রেপসস্টেটের জন্য একই করুন। তারপরে প্রতিবার ব্রেকপয়েন্টগুলি ট্রিগার হওয়ার সাথে সাথে কল স্ট্যাকটি একবার দেখুন
Bonjour123

আমি কল স্ট্যাকটি পরীক্ষা করে দেখেছি এবং সমস্ত কিছু সঠিকভাবে করা হয়েছে বলে মনে হচ্ছে - তবুও ইতিহাস কাজ করতে চায় না। মোজিলা কেন সবকিছু এত কঠিন করে তুলবে :(
গ্রেভ।

ধন্যবাদ :) এবং আপনি যদি Chrome এ চেষ্টা করেন তবে আপনার কী ফলাফল হবে?
Bonjour123
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.