قم بتغيير عنوان URL في المتصفح دون تحميل الصفحة الجديدة باستخدام JavaScript

StackOverflow https://stackoverflow.com/questions/136458

سؤال

كيف سيكون لدي جافا سكريبت الإجراء الذي قد يكون له بعض التأثيرات على الصفحة الحالية ولكنه سيؤدي أيضًا إلى تغيير عنوان URL في المتصفح، لذا إذا قام المستخدم بالضغط على إعادة التحميل أو وضع إشارة مرجعية، فسيتم استخدام عنوان URL الجديد؟

سيكون من الجيد أيضًا أن يقوم زر الرجوع بإعادة تحميل عنوان URL الأصلي.

أحاول تسجيل حالة JavaScript في عنوان URL.

هل كانت مفيدة؟

المحلول

مع HTML 5، استخدم history.pushState وظيفة.كمثال:

<script type="text/javascript">
var stateObj = { foo: "bar" };
function change_my_url()
{
   history.pushState(stateObj, "page 2", "bar.html");
}
var link = document.getElementById('click');
link.addEventListener('click', change_my_url, false);
</script>

و href:

<a href="#" id='click'>Click to change url to bar.html</a>

إذا كنت تريد تغيير عنوان URL دون إضافة إدخال إلى قائمة زر الرجوع، فاستخدمه history.replaceState بدلاً من.

نصائح أخرى

إذا كنت تريد أن يعمل في المتصفحات التي لا تدعم ذلك history.pushState و history.popState ومع ذلك، فإن الطريقة "القديمة" هي تعيين معرف الجزء، والذي لن يتسبب في إعادة تحميل الصفحة.

الفكرة الأساسية هي تعيين window.location.hash الخاصية إلى قيمة تحتوي على معلومات الحالة التي تحتاجها، ثم استخدم إما حدث window.onhashchange, ، أو للمتصفحات القديمة التي لا تدعمها onhashchange (IE <8، Firefox <3.6)، تحقق بشكل دوري لمعرفة ما إذا كانت التجزئة قد تغيرت (باستخدام setInterval على سبيل المثال) وتحديث الصفحة.ستحتاج أيضًا إلى التحقق من قيمة التجزئة عند تحميل الصفحة لإعداد المحتوى الأولي.

إذا كنت تستخدم jQuery فهناك البرنامج المساعد لتغيير التجزئة التي ستستخدم أي طريقة يدعمها المتصفح.أنا متأكد من أن هناك مكونات إضافية للمكتبات الأخرى أيضًا.

الشيء الوحيد الذي يجب الحذر منه هو الاصطدام بالمعرفات الموجودة على الصفحة، لأن المتصفح سيقوم بالتمرير إلى أي عنصر بمعرف مطابق.

يحتوي window.location.href على عنوان URL الحالي.يمكنك القراءة منه، ويمكنك الإلحاق به، ويمكنك استبداله، مما قد يتسبب في إعادة تحميل الصفحة.

إذا كنت تريد، كما يبدو، تسجيل حالة جافا سكريبت في عنوان URL حتى يمكن وضع إشارة مرجعية عليها، دون إعادة تحميل الصفحة، فقم بإلحاقها بعنوان URL الحالي بعد # واحصل على جزء من جافا سكريبت يتم تشغيله بواسطة حدث onload لتحليل الحالي URL لمعرفة ما إذا كان يحتوي على الحالة المحفوظة.

إذا كنت تستخدم ؟بدلاً من #، ستفرض إعادة تحميل للصفحة، ولكن بما أنك ستقوم بتحليل الحالة المحفوظة عند التحميل، فقد لا يكون هذا مشكلة في الواقع؛وهذا سيجعل الأزرار الأمامية والخلفية تعمل بشكل صحيح أيضًا.

وأظن بقوة أن هذا غير ممكن، لأنه سيكون مشكلة أمنية لا تصدق إذا كان الأمر كذلك.على سبيل المثال، يمكنني إنشاء صفحة تشبه صفحة تسجيل الدخول إلى البنك، وإظهار عنوان URL في شريط العناوين تماما مثل البنك الحقيقي!

ربما إذا شرحت سبب رغبتك في القيام بذلك، فقد يتمكن الأشخاص من اقتراح طرق بديلة...

[تحرير في عام 2011:منذ أن كتبت هذه الإجابة في عام 2008، ظهرت المزيد من المعلومات بخصوص تقنية HTML5 يسمح بتعديل عنوان URL طالما أنه من نفس المصدر]

تمنع إعدادات أمان المتصفح الأشخاص من تعديل عنوان URL المعروض مباشرة.يمكنك أن تتخيل ثغرات التصيد الاحتيالي التي من شأنها أن تسبب ذلك.

الطريقة الوحيدة الموثوقة لتغيير عنوان URL دون تغيير الصفحات هي استخدام رابط داخلي أو تجزئة.على سبيل المثال: http://site.com/page.html يصبح http://site.com/page.html#item1 .تُستخدم هذه التقنية غالبًا في hijax (AJAX + الحفاظ على التاريخ).

عند القيام بذلك، غالبًا ما سأستخدم فقط روابط الإجراءات التي تحتوي على التجزئة مثل href، ثم أضف أحداث النقر باستخدام jquery التي تستخدم التجزئة المطلوبة لتحديد الإجراء وتفويضه.

آمل أن يضعك هذا على الطريق الصحيح.

مسج يحتوي على مكون إضافي رائع لتغيير عنوان URL للمتصفحات، يُسمى مسج انتهازي.

جافا سكريبت pushState ويمكن استخدام jQuery معًا، مثل:

history.pushState(null, null, $(this).attr('href'));

مثال:

$('a').click(function (event) {

  // Prevent default click action
  event.preventDefault();     

  // Detect if pushState is available
  if(history.pushState) {
    history.pushState(null, null, $(this).attr('href'));
  }
  return false;
});


باستخدام فقط جافا سكريبت history.pushState(), ، الذي يغير المرجع، الذي يتم استخدامه في رأس HTTP لكائنات XMLHttpRequest التي تم إنشاؤها بعد تغيير الحالة.

مثال:

window.history.pushState("object", "Your New Title", "/new-url");

طريقة PushState ():

pushState() يأخذ ثلاث معلمات:كائن حالة، وعنوان (يتم تجاهله حاليًا)، و(اختياريًا) عنوان URL.دعونا نفحص كل من هذه المعلمات الثلاثة بمزيد من التفصيل:

  1. كائن الدولة - كائن الحالة هو كائن JavaScript مرتبط بإدخال السجل الجديد الذي تم إنشاؤه بواسطة pushState().عندما ينتقل المستخدم إلى الحالة الجديدة، يتم إطلاق حدث popstate، وتحتوي خاصية الحالة الخاصة بالحدث على نسخة من كائن الحالة الخاص بإدخال السجل.

    يمكن أن يكون كائن الحالة أي شيء يمكن إجراء تسلسل له.نظرًا لأن Firefox يحفظ كائنات الحالة على قرص المستخدم بحيث يمكن استعادتها بعد إعادة تشغيل المستخدم لمتصفحه، فإننا نفرض حدًا للحجم يبلغ 640 ألف حرف على التمثيل المتسلسل لكائن الحالة.إذا قمت بتمرير كائن حالة يكون تمثيله المتسلسل أكبر من هذا إلى pushState(), ، ستطرح الطريقة استثناءً.إذا كنت بحاجة إلى مساحة أكبر من هذه، فننصحك باستخدام sessionStorage و/أو localStorage.

  2. عنوان — يتجاهل Firefox هذه المعلمة حاليًا، على الرغم من أنه قد يستخدمها في المستقبل.يجب أن يكون تمرير السلسلة الفارغة هنا آمنًا ضد التغييرات المستقبلية في الطريقة.وبدلاً من ذلك، يمكنك تمرير عنوان قصير للولاية التي ستنتقل إليها.

  3. عنوان URL — يتم توفير عنوان URL لإدخال السجل الجديد بواسطة هذه المعلمة.لاحظ أن المتصفح لن يحاول تحميل عنوان URL هذا بعد الاتصال به pushState(), ، ولكن قد يحاول تحميل عنوان URL لاحقًا، على سبيل المثال بعد قيام المستخدم بإعادة تشغيل المتصفح.لا يلزم أن يكون عنوان URL الجديد مطلقًا؛إذا كان الأمر نسبيًا، فسيتم حله بالنسبة إلى عنوان URL الحالي.يجب أن يكون عنوان URL الجديد من نفس أصل عنوان URL الحالي؛خلاف ذلك، pushState() سوف يرمي استثناء.هذه المعلمة اختيارية؛إذا لم يتم تحديده، فسيتم تعيينه على عنوان URL الحالي للمستند.

يوجد مكون Yahoo YUI (مدير محفوظات المتصفح) يمكنه التعامل مع هذا: http://developer.yahoo.com/yui/history/

يقوم معرض صور Facebook بذلك باستخدام #hash في عنوان URL.فيما يلي بعض أمثلة عناوين URL:

قبل النقر على "التالي":

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507

بعد النقر على "التالي":

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507#!/photo.php?fbid=496435457507&set=a.218088072507.133423.681812507&pid=5887085&id=681812507

لاحظ علامة التجزئة (#!) متبوعة مباشرةً بعنوان URL الجديد.

هناك البرنامج المساعد مسج http://www.asual.com/jquery/address/

أعتقد أن هذا هو ما تحتاجه.

ما يعمل بالنسبة لي هو - history.replaceState() الدالة وهي كما يلي -

history.replaceState(data,"Title of page"[,'url-of-the-page']);

لن يؤدي هذا إلى إعادة تحميل الصفحة، يمكنك الاستفادة منها مع حدث جافا سكريبت

كنت أتساءل عما إذا كان ذلك ممكنًا طالما أن المسار الأصلي في الصفحة هو نفسه، فسيتم إلحاق شيء جديد به فقط.

لنفترض أن المستخدم موجود في الصفحة: http://domain.com/site/page.htmlثم يمكن للمتصفح أن يسمح لي بذلك location.append = new.htmlوتصبح الصفحة: http://domain.com/site/page.htmlnew.html والمتصفح لا يغيره.

أو فقط اسمح للشخص بتغيير معلمة get، فلنفعل ذلك location.get = me=1&page=1.

لذلك تصبح الصفحة الأصلية http://domain.com/site/page.html?me=1&page=1 ولا يتم تحديثه.

مشكلة # هي أن البيانات لا يتم تخزينها مؤقتًا (على الأقل لا أعتقد ذلك) عند تغيير التجزئة.لذلك يبدو الأمر كما هو الحال في كل مرة يتم فيها تحميل صفحة جديدة، في حين أن أزرار الرجوع إلى الخلف والأمام في وضع غيراياكس الصفحة قادرة على تخزين البيانات مؤقتًا ولا تقضي وقتًا في إعادة تحميل البيانات.

مما رأيته، يقوم سجل Yahoo بتحميل جميع البيانات مرة واحدة بالفعل.لا يبدو أنه يقوم بأي طلبات من Ajax.لذلك عندما أ div يتم استخدامه للتعامل مع العمل الإضافي بطريقة مختلفة، ولا يتم تخزين هذه البيانات لكل حالة محفوظات.

الكود الخاص بي هو:

//change address bar
function setLocation(curLoc){
    try {
        history.pushState(null, null, curLoc);
        return false;
    } catch(e) {}
        location.hash = '#' + curLoc;
}

والعمل:

setLocation('http://example.com/your-url-here');

والمثال

$(document).ready(function(){
    $('nav li a').on('click', function(){
        if($(this).hasClass('active')) {

        } else {
            setLocation($(this).attr('href'));
        }
            return false;
    });
});

هذا كل شئ :)

لقد حققت النجاح مع:

location.hash="myValue";

ويضيف فقط #myValue إلى عنوان URL الحالي.إذا كنت بحاجة إلى تشغيل حدث عند تحميل الصفحة، فيمكنك استخدام نفس الشيء location.hash للتحقق من القيمة ذات الصلة.فقط تذكر إزالة # من القيمة التي تم إرجاعها بواسطة location.hash على سبيل المثال

var articleId = window.location.hash.replace("#","");

إجابة أكثر بساطة أقدمها ،

window.history.pushState(null, null, "/abc")

هذا سيضيف /abc بعد اسم المجال في عنوان URL للمتصفح.ما عليك سوى نسخ هذا الرمز ولصقه في وحدة تحكم المتصفح ورؤية عنوان URL يتغير إلى "https://stackoverflow.com/abc"

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top