জাভাস্ক্রিপ্টে হ্যাশের পরে ইউআরএল পরিবর্তন হয়েছে কিনা তা কীভাবে সনাক্ত করবেন


160

কোনও URL জাভাস্ক্রিপ্টে পরিবর্তিত হয়েছে কিনা তা আমি কীভাবে পরীক্ষা করতে পারি? উদাহরণস্বরূপ, গিটহাবের মতো ওয়েবসাইটগুলি, যা এজেএক্স ব্যবহার করে, পৃষ্ঠাটি পুনরায় লোড না করে একটি অনন্য ইউআরএল তৈরি করতে # চিহ্নের পরে পৃষ্ঠা তথ্য যুক্ত করবে। এই ইউআরএল পরিবর্তন হলে সনাক্ত করার সর্বোত্তম উপায় কী?

  • হয় onloadঘটনা আবার বলা হয়?
  • URL এর জন্য কোনও ইভেন্ট হ্যান্ডলার রয়েছে?
  • অথবা পরিবর্তনটি সনাক্ত করতে URL গুলি প্রতি সেকেন্ডে চেক করা উচিত?

1
: ভবিষ্যতের দর্শকদের জন্য 2018 থেকে @aljgom করে একটি নতুন উত্তর সবচেয়ে ভালো সমাধান হয় stackoverflow.com/a/52809105/151503
Redzarf

উত্তর:


106

আধুনিক ব্রাউজারগুলিতে (আই 8 +, এফএফ 3.6 +, ক্রোম), আপনি কেবল hashchangeইভেন্টটি শুনতে পারবেন window

কিছু পুরানো ব্রাউজারগুলিতে আপনার এমন একটি টাইমার প্রয়োজন যা নিয়মিত চেক করে location.hash। আপনি যদি jQuery ব্যবহার করেন তবে একটি প্লাগইন রয়েছে যা হুবহু এটি করে।


132
এটি, যেমনটি আমি বুঝতে পেরেছি, কেবল # চিহ্ন (সুতরাং ইভেন্টের নাম) পরে অংশ পরিবর্তন করার জন্য কাজ করে? এবং পুরো ইউআরএল পরিবর্তনের জন্য নয়, যেমনটি মনে হয় প্রশ্নের শিরোনাম দ্বারা বোঝানো হয়েছে।
এনপিসি

13
@ এনপিসি সম্পূর্ণ ইউআরএল পরিবর্তনের জন্য কোনও হ্যান্ডলার (অ্যাঙ্কর ট্যাগ ছাড়াই)?
নেহা চৌধুরী চৌদ্দ

আপনার খুব কমই টাইমআউট ইভেন্টগুলি প্রয়োজন: চেক করার জন্য মাউস- এবং কীবোর্ডস ব্যবহার করুন।
সিজেটি

পথ বদলে গেলে কি হ্যাশ হয় না?
সুপারউবারডুপার

@ সুপারউবারডুপার যদি পথটি পরিবর্তিত হয় কারণ ব্যবহারকারী কোনও নেভিগেশন শুরু করেছেন / কোনও লিঙ্ক ইত্যাদি ক্লিক করেছেন, তবে আপনি কেবল একটি beforeunloadইভেন্ট দেখতে পাবেন । যদি আপনার কোডটি ইউআরএল পরিবর্তনের সূচনা করে তবে এটি সবচেয়ে ভাল জানেন।
ফিহাগ

92

আমি locationchangeইভেন্ট শ্রোতা যুক্ত করতে সক্ষম হতে চেয়েছিলেন । নীচের সংশোধন করার পরে, আমরা এটির মতো এটি করতে সক্ষম হব

window.addEventListener('locationchange', function(){
    console.log('location changed!');
})

বিপরীতে, window.addEventListener('hashchange',()=>{})কেবল তখনই গুলি চালিত হবে যদি কোনও ইউআরএল হ্যাশট্যাগের পরে অংশটি পরিবর্তন হয় এবং window.addEventListener('popstate',()=>{})সর্বদা কাজ করে না।

খ্রিস্টানদের উত্তরের অনুরূপ এই পরিবর্তনটি কিছু কার্যকারিতা যুক্ত করতে ইতিহাসের বিষয়টিকে পরিবর্তন করে।

ডিফল্টরূপে, একটি popstateইভেন্ট আছে pushstate, এবং এর জন্য কোনও ইভেন্ট নেই এবং replacestate

এই মডিফাই এই তিনটি ফাংশন যাতে সব আগুন একটি কাস্টম locationchangeআপনার ব্যবহারের জন্য, এবং এছাড়াও ঘটনা pushstateএবং replacestateঘটনা আপনি ঐ ব্যবহার করতে চান:

/* These are the modifications: */
history.pushState = ( f => function pushState(){
    var ret = f.apply(this, arguments);
    window.dispatchEvent(new Event('pushstate'));
    window.dispatchEvent(new Event('locationchange'));
    return ret;
})(history.pushState);

history.replaceState = ( f => function replaceState(){
    var ret = f.apply(this, arguments);
    window.dispatchEvent(new Event('replacestate'));
    window.dispatchEvent(new Event('locationchange'));
    return ret;
})(history.replaceState);

window.addEventListener('popstate',()=>{
    window.dispatchEvent(new Event('locationchange'))
});

2
দুর্দান্ত, আমার কী দরকার ধন্যবাদ
eslamb

ধন্যবাদ, সত্যই সহায়ক!
থমাস ল্যাং

1
আইই-তে এটি করার কোনও উপায় আছে? যেহেতু এটি সমর্থন করে না =>
জোশুয়াসটসন

1
@ জোশুয়াচটন => একটি তীর ফাংশন, আপনি f => ফাংশন নাম () {... replace ফাংশন (চ) {রিটার্ন ফাংশন ফিনম ()} ...}}
আলজগম

1
এটি খুব সহায়ক এবং একটি কবজির মতো কাজ করে। এটি গ্রহণযোগ্য উত্তর হওয়া উচিত।
কুণাল পারেক

77

এই কোড ব্যবহার করুন

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

jQuery সহ

$(window).bind('hashchange', function() {
     //code
});

7
এটি অবশ্যই উত্তর চিহ্নিত করা উচিত। এটি একটি লাইন, ব্রাউজার ইভেন্টের মডেল ব্যবহার করে এবং অফুরন্ত সংস্থান গ্রহণের সময়সীমার উপর নির্ভর করে না
নিক মিচেল

1
এটি আমার মতে এখানে সেরা উত্তর। কোনও প্লাগইন এবং ন্যূনতম কোড নেই
agDev

14
নন-হ্যাশ ইউআরএল পরিবর্তনগুলিতে কাজ করে না যা স্ল্যাক দ্বারা বাস্তবায়িত একটির মতো খুব জনপ্রিয় বলে মনে হয়
এনাইককম্পসি

26
ইউআরএলটিতে একটি হ্যাশ থাকলে কেবল এটিই যদি ট্রিগার করা হয় তবে এটি কীভাবে সেরা উত্তর?
অ্যারন

1
অন্য কিছু যদি শুনতেও চায় সে ক্ষেত্রে আপনার অন্যাশ্চেঞ্জ মানটি সরাসরি প্রতিস্থাপনের পরিবর্তে আপনার অ্যাডএভেন্টলিস্টনার ব্যবহার করা উচিত।
ভাঙা ই

55

কিছুটা গবেষণা করার পরে সম্পাদনা করুন:

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

তবে @ আলফা 123 অনুসারে বানরকে প্যাচ করে এটিকে রোধ করার উপায় রয়েছে :

var pushState = history.pushState;
history.pushState = function () {
    pushState.apply(history, arguments);
    fireEvents('pushState', arguments);  // Some event-handling function
};

আসল উত্তর

এই প্রশ্নের শিরোনামটি হল " ইউআরএল পরিবর্তন কীভাবে সনাক্ত করা যায় " উত্তর, আপনি যখন জানতে চান পুরো পথটি কখন পরিবর্তিত হয় (এবং কেবল হ্যাশ অ্যাঙ্কর নয়), আপনি এই popstateইভেন্টটি শুনতে পারবেন :

window.onpopstate = function(event) {
  console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
};

মজিলা ডক্সে পপস্টেটের জন্য রেফারেন্স

বর্তমানে (জানুয়ারী 2017) বিশ্বব্যাপী 92% ব্রাউজারের পপস্টেটের জন্য সমর্থন রয়েছে।


11
অবিশ্বাস্য যে আমাদের এখনও 2018 সালে এই জাতীয় হ্যাকগুলি অবলম্বন করতে হবে
ছাগল

1
এটি আমার ব্যবহারের ক্ষেত্রে কাজ করেছে - তবে ঠিক যেমন @ বোট বলেছেন - এটির কোনও আদি সমর্থন নেই তা অবিশ্বাস্য ...
wasddd__

1
কি যুক্তি? আমি কীভাবে ফায়ার এভেস্টস স্থাপন করব?
শানমিসি

2
মনে রাখবেন যে এটি অনেক ক্ষেত্রেই অবিশ্বাস্য। উদাহরণস্বরূপ, আপনি যখন বিভিন্ন অ্যামাজন পণ্যের বৈচিত্রগুলি (দামের নীচে টাইলস) ক্লিক করেন তখন এটি URL পরিবর্তনটি সনাক্ত করতে পারে না।
thdoan

2
এই অবস্থানটি ব্যবহার না করে লোকালহোস্ট / foo থেকে লোকালহোস্ট /
বাএতে

53

Jquery (এবং একটি প্লাগ-ইন) দিয়ে আপনি করতে পারেন

$(window).bind('hashchange', function() {
 /* things */
});

http://benalman.com/projects/jquery-hashchange-plugin/

অন্যথায় হ্যাঁ, আপনাকে সেট ইনটারওয়াল ব্যবহার করতে হবে এবং হ্যাশ ইভেন্টে পরিবর্তন (উইন্ডো.লোকেশন.হ্যাশ) পরীক্ষা করতে হবে

হালনাগাদ! একটি সাধারণ খসড়া

function hashHandler(){
    this.oldHash = window.location.hash;
    this.Check;

    var that = this;
    var detect = function(){
        if(that.oldHash!=window.location.hash){
            alert("HASH CHANGED - new has" + window.location.hash);
            that.oldHash = window.location.hash;
        }
    };
    this.Check = setInterval(function(){ detect() }, 100);
}

var hashDetection = new hashHandler();

আমি কী (উইন্ডো.লোকেশন) পরিবর্তন সনাক্ত করতে এবং এটি পরিচালনা করতে পারি? (jquery ছাড়াই)
বার্গপি

6
আপনি সরল জাভাস্ক্রিপ্ট শ্রোতাদের ব্যবহার করে @ বার্গপি করতে পারেন: window.addEventListener("hashchange", hashChanged);
রন

1
এত স্বল্প সময়ের ব্যবধানটি কি অ্যাপটির জন্য ভাল? অর্থাত, এটি detect()ফাংশন সম্পাদন করতে ব্রাউজারটিকে খুব ব্যস্ত রাখে না ?
হাসিব মাহমুদ

4
@ হাছিবমাহমুদ, এই কোডটি প্রতি 100 মিমিতে 1 টি সমতা পরীক্ষা করে। আমি কেবল আমার ব্রাউজারে বেঞ্চমার্ক করেছি যে আমি 1 এমএসের অধীনে 500 সমতা পরীক্ষা করতে পারি। সুতরাং সেই কোডটি আমার প্রসেসিং পাওয়ারের 1/50000 তম ব্যবহার করছে। আমি খুব বেশি চিন্তা করব না।
z5h

24

একটি হ্যাশ পরিবর্তন ইভেন্ট শ্রোতা যুক্ত করুন!

window.addEventListener('hashchange', function(e){console.log('hash changed')});

বা, সমস্ত ইউআরএল পরিবর্তন শুনতে:

window.addEventListener('popstate', function(e){console.log('url changed')});

নীচের কোডের মতো এটির চেয়ে ভাল এটি কারণ উইন্ডো.হ্যাশচেঞ্জে কেবলমাত্র একটি জিনিস থাকতে পারে এবং আপনি সম্ভবত অন্য কারও কোডটি ওভাররাইট করে যাবেন।

// Bad code example

window.onhashchange = function() { 
     // Code that overwrites whatever was previously in window.onhashchange  
}

1
পপ অবস্থা কেবল তখনই ট্রিগার হয় যখন আপনি কোনও রাজ্যকে পপ করুন, একটিকে ধাক্কা দেবেন না
SeanMC

8

এই সমাধানটি আমার পক্ষে কাজ করেছে:

var oldURL = "";
var currentURL = window.location.href;
function checkURLchange(currentURL){
    if(currentURL != oldURL){
        alert("url changed!");
        oldURL = currentURL;
    }

    oldURL = window.location.href;
    setInterval(function() {
        checkURLchange(window.location.href);
    }, 1000);
}

checkURLchange();

18
এটি একটি বরং প্রাথমিক পদ্ধতি, আমি মনে করি আমরা উচ্চতর লক্ষ্য রাখতে পারি।
কার্লস অ্যালকোলেয়া

8
যদিও আমি @ কার্লস অ্যালকোলেয়ার সাথে একমত যে এটি পুরানো বোধ করে, আমার অভিজ্ঞতায় এটি এখনও সমস্ত ইউআরএল পরিবর্তনের 100% ধরার একমাত্র উপায়।
Trev14

5
@ অহফম্যান পরামর্শ দিয়েছেন (এমন সম্পাদনায় যা একটি মন্তব্য হওয়া উচিত ছিল) এতে পরিবর্তন setIntervalকরে setTimeout: "সেটইন্টারভাল () ব্যবহার করে কিছুক্ষণের পরে ব্রাউজারটি থামবে, কারণ এটি প্রতি সেকেন্ডে চেক URL পরিবর্তন () এ একটি নতুন কল তৈরি করবে। সেটটাইমআউট () সঠিক সমাধান, কারণ এটি কেবল একবার ডাকা হয় called
ডিবিবিসান

সমস্ত ইউআরএল পরিবর্তনগুলি ধরার জন্য এটিই ছিল একমাত্র সমাধান তবে সম্পদ গ্রহণকারী আমাকে অন্য কিছু সমাধান খুঁজতে বাধ্য করছে।
রিটার্নটেবল

3
অথবা setTimeout@ ডিবিবিসান পরামর্শের মতো ব্যবহারের পরিবর্তে setIntervalফাংশনের বাইরে চলে যান move checkURLchange();এছাড়াও becomesচ্ছিক হয়।
aristidesfl

4

যদিও একটি পুরানো প্রশ্ন, লোকেশন-বার প্রকল্পটি খুব দরকারী।

var LocationBar = require("location-bar");
var locationBar = new LocationBar();

// listen to all changes to the location bar
locationBar.onChange(function (path) {
  console.log("the current url is", path);
});

// listen to a specific change to location bar
// e.g. Backbone builds on top of this method to implement
// it's simple parametrized Backbone.Router
locationBar.route(/some\-regex/, function () {
  // only called when the current url matches the regex
});

locationBar.start({
  pushState: true
});

// update the address bar and add a new entry in browsers history
locationBar.update("/some/url?param=123");

// update the address bar but don't add the entry in history
locationBar.update("/some/url", {replace: true});

// update the address bar and call the `change` callback
locationBar.update("/some/url", {trigger: true});

এটি নোডজেসের জন্য, এটি ক্লায়েন্ট-সাইড ব্যবহার করার জন্য আমাদের ব্রাউজারিফাই ব্যবহার করা উচিত। আমরা না?
হ্যাক 4

1
না এটা না। ব্রাউজারে কাজ করে
রে বুয়েন

3

Url পরিবর্তনগুলি শুনতে, নীচে দেখুন:

window.onpopstate = function(event) {
  console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
};

আপনি যদি কিছু নির্দিষ্ট শর্ত পরে শ্রোতাদের থামানোর / অপসারণ করতে চান তবে এই শৈলীটি ব্যবহার করুন।

window.addEventListener('popstate', function(e) {
   console.log('url changed')
});

2

কিছুটা ক্রোম এক্সটেনশন করার সময়, আমি একটি সংযোজনজনিত সমস্যা নিয়ে একই সমস্যার মুখোমুখি হয়েছিলাম: কখনও কখনও পৃষ্ঠাটি পরিবর্তন হয় তবে ইউআরএল নয়।

উদাহরণস্বরূপ, কেবল ফেসবুক হোমপেজে যান এবং 'হোম' বোতামটি ক্লিক করুন। আপনি পৃষ্ঠাটি পুনরায় লোড করবেন তবে URL টি পরিবর্তন হবে না (এক পৃষ্ঠার অ্যাপ স্টাইল)।

সময়ের 99%, আমরা ওয়েবসাইটগুলি বিকাশ করছি যাতে আমরা সেই ঘটনাগুলি ফ্রেমওয়ার্কগুলি থেকে যেমন কৌণিক, প্রতিক্রিয়া, মান ইত্যাদির কাছ থেকে পেতে পারি ..

কিন্তু , আমার ক্রোম এক্সটেনশনের ক্ষেত্রে (ভ্যানিলা জেএসে), আমাকে এমন একটি ইভেন্ট শুনতে হয়েছিল যা প্রতিটি "পৃষ্ঠা পরিবর্তন" এর জন্য ট্রিগার করবে, যা সাধারণত ইউআরএল পরিবর্তিত হয়ে ধরা যেতে পারে, তবে কখনও কখনও তা হয় না।

আমার বাড়ির তৈরি সমাধানটি ছিল:

listen(window.history.length);
var oldLength = -1;
function listen(currentLength) {
  if (currentLength != oldLength) {
    // Do your stuff here
  }

  oldLength = window.history.length;
  setTimeout(function () {
    listen(window.history.length);
  }, 1000);
}

সুতরাং মূলত লিনকোকার্ট সমাধানটি উইন্ডো ইতিহাসে প্রয়োগ করা হয়, যা কোনও একক পৃষ্ঠায় অ্যাপ্লিকেশনটিতে কোনও পৃষ্ঠা পরিবর্তিত হলে পরিবর্তিত হবে।

রকেট বিজ্ঞান নয়, তবে সবচেয়ে পরিষ্কার সমাধান আমি খুঁজে পেয়েছি, বিবেচনা করে আমরা এখানে কেবলমাত্র একটি পূর্ণসংখ্যার সমতা পরীক্ষা করছি, এবং বড় কোনও অবজেক্ট বা পুরো ডিওএম নয়।


আপনার সমাধানটি সহজ এবং ক্রোম এক্সটেনশনের জন্য খুব ভাল কাজ করে। আমি দৈর্ঘ্যের পরিবর্তে ইউটিউব ভিডিও আইডি ব্যবহার করার পরামর্শ দিতে চাই। stackoverflow.com/a/3452617/808901
রড লিমা

2
আপনার সেটআইন্টারভাল ব্যবহার করা উচিত নয় কারণ আপনি যখনই শোনেন (xy) কল করবেন তখনই একটি নতুন ইন্টারভাল তৈরি হবে এবং আপনি হাজার হাজার ব্যবধানে শেষ হবেন।
স্টিফ চیسر

1
আপনি ঠিক বলেছেন আমি লক্ষ্য করেছি যে পরে এবং আমার পোস্ট পরিবর্তন হয়নি, আমি এটি সম্পাদনা করব। র‍্যাম ফাঁস হওয়ার কারণে আমি গুগল ক্রোমের ক্রাশের মুখোমুখি হয়েছি। মন্তব্যের জন্য আপনাকে ধন্যবাদ
Alburkerk

window.historyসর্বোচ্চ দৈর্ঘ্য 50 (কমপক্ষে ক্রোম 80 হিসাবে) has এই বিন্দুর পরে, window.history.lengthসর্বদা 50 প্রদান করে that
কলিন ক্রাওল

1

JQuery আনলোড ফাংশনটি দেখুন। এটি সমস্ত জিনিস পরিচালনা করে।

https://api.jquery.com/unload/

ব্যবহারকারী পৃষ্ঠা থেকে দূরে নেভিগেট করলে আনলোড ইভেন্টটি উইন্ডো উপাদানটিতে পাঠানো হয়। এর অর্থ অনেকগুলি জিনিসের একটি হতে পারে। পৃষ্ঠাটি ছেড়ে যাওয়ার জন্য ব্যবহারকারী কোনও লিঙ্কে ক্লিক করতে পারে বা ঠিকানা বারে একটি নতুন URL টাইপ করতে পারে। ফরোয়ার্ড এবং ব্যাক বোতামগুলি ইভেন্টটি ট্রিগার করবে। ব্রাউজার উইন্ডোটি বন্ধ করার ফলে ইভেন্টটি ট্রিগার হওয়ার কারণ হবে। এমনকি একটি পৃষ্ঠা পুনরায় লোডও প্রথমে একটি আনলোড ইভেন্ট তৈরি করবে।

$(window).unload(
    function(event) {
        alert("navigating");
    }
);

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

@ ক্রমবুক প্রশ্নের মতোই, এটি কেবলমাত্র সেই পৃষ্ঠাগুলির জন্য নির্দিষ্ট যা কোনও একক পৃষ্ঠার অ্যাপ্লিকেশন নয় এবং এই ইভেন্টটি কেবল আনলোড উইন্ডো ইভেন্টটি দেখছে, url পরিবর্তন নয়।
ncubica


0

নীচের উত্তরটি এখান থেকে এসেছে (পুরানো জাভাস্ক্রিপ্ট সিনট্যাক্স সহ (কোনও তীর ফাংশন নয়, IE 10+ সমর্থন করবেন না)): https://stackoverflow.com/a/52809105/9168962

(function() {
  if (typeof window.CustomEvent === "function") return false; // If not IE
  function CustomEvent(event, params) {
    params = params || {bubbles: false, cancelable: false, detail: null};
    var evt = document.createEvent("CustomEvent");
    evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
    return evt;
  }
  window.CustomEvent = CustomEvent;
})();

(function() {
  history.pushState = function (f) {
    return function pushState() {
      var ret = f.apply(this, arguments);
      window.dispatchEvent(new CustomEvent("pushState"));
      window.dispatchEvent(new CustomEvent("locationchange"));
      return ret;
    };
  }(history.pushState);
  history.replaceState = function (f) {
    return function replaceState() {
      var ret = f.apply(this, arguments);
      window.dispatchEvent(new CustomEvent("replaceState"));
      window.dispatchEvent(new CustomEvent("locationchange"));
      return ret;
    };
  }(history.replaceState);
  window.addEventListener("popstate", function() {
    window.dispatchEvent(new CustomEvent("locationchange"));
  });
})();

0

আপনি এটির আর একটি সহজ উপায় হ'ল একটি ক্লিক ইভেন্ট যুক্ত করে পৃষ্ঠার অ্যাঙ্কার ট্যাগগুলিতে শ্রেণীর নামের মাধ্যমে ক্লিক করা হয় তা সনাক্ত করতে, তবে আপনি এখন url ডেটা পেতে উইন্ডো.লোকেশন.href ব্যবহার করতে পারেন যা আপনি সার্ভারে আপনার এজ্যাক্স অনুরোধ চালানোর জন্য ব্যবহার করতে পারেন। সহজ এবং সহজ।


-1

setIntervalপূর্ববর্তীটি বাতিল না করে আপনি প্রতিটি কলটিতে একটি নতুন শুরু করছেন - সম্ভবত আপনি কেবল একটিটি বোঝাতে চেয়েছিলেনsetTimeout

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