【问题标题】:onhashchange not working within in-app browsers (Facebook, Twiiter)onhashchange 在应用内浏览器(Facebook、Twitter)中不起作用
【发布时间】:2015-05-08 04:34:11
【问题描述】:

我正在使用onhashchange window event 来检测my single page webapp 的url 哈希变化。这使我能够触发 AJAX,同时保留浏览器历史记录。

  1. 用户点击带有 href="#hashlink" 的锚点。
  2. onhashchange 检测到 URL 更新。
  3. #hashlink 被提取并作为 AJAX url (/partials/hashlink.php) 传入。

我发现了一个问题。您可能已经意识到,Facebook 和 Twitter 已经开始在应用内浏览器中启动外部链接。它似乎阻止了页面锚点 href 的默认操作,这已经杀死了我的哈希更改检测。因此我的 webapp 几乎没用 :-(

Facebook 和 Twitter 的应用内浏览器是最近才发布的,因此要找到解决方案非常困难。

提前致谢!

【问题讨论】:

  • 没有升级到现代 HTML5 History api 的原因?
  • 这是一个很好的观点,但问题不在于历史。这是我检测哈希更改以触发我的 AJAX 的方式。我想我只是想知道它在这些应用内浏览器中不起作用的原因。

标签: javascript ajax facebook twitter


【解决方案1】:

我知道这是一个老问题,但我昨天遇到了同样的问题。无法找到允许我继续使用哈希链接和 onhashchange 事件的解决方案。我重写了我的代码以使用History API,即widely supported(caniuse 说它适用于除 Opera Mini 之外的所有浏览器,但是当我测试时,它也适用于我)。

一步一步:

  1. 将所有哈希链接转换为按钮,或其他一些可访问的格式(具有 role="link" 属性的 div 等)。 (如果按钮不包含清楚说明其功能的文本,请不要忘记包含 aria-label 属性)。

    <button class="nav__list-item" data-id="${p.websafeHandle}" aria-label="Read our Q & A with ${p.name}">
        <div class="nav__list-item__img" style="background-image: url(${p.thumbnail})"></div>
        <span class="nav__list-item__handle">${p.handle}</span>
    </button>
    
  2. 添加点击事件监听

    const qaLinks = document.querySelectorAll('.nav__list-item')
    qaLinks.forEach(link => {
        link.addEventListener('click', (e) => this.loadQA(e.currentTarget.dataset.id, true))
    })
    
  3. 单击事件处理程序以更新页面内容和浏览器历史记录

    loadQA(person, updateHistory) {
        // I'm condensing/summarizing the parts of my code that deal with fetching data and
        // outputting it on the page, because it's not particularly relevant to this question. 
        const data = this.data[person]
        this.container.innerHTML = template(Templates.qaPage, data.qa)
    
        // the loadQA function will also be called if somebody comes to this page 
        // with a hash link like the one below. in that case (on an initial visit, 
        // instead of navigation within my single-page app), I wouldn't want to add 
        // the page to the history again, thereby creating a double entry, 
        // which is why I have the updateHistory param
        if (updateHistory) {
            // update our page title and our URL and add it to the browser history
            const title = `MTI - ${data.info.name}`
            const hash = `#/qa/${data.info.websafeHandle}`
            history.pushState(null, title, hash)
        }
    }
    
  4. 当有人使用浏览器的前进/后退按钮时触发的事件处理程序

    window.addEventListener('popstate', () => this.loadPage())
    
  5. 在 popstate 事件处理程序(也在初始页面加载时运行)中,获取 URL 哈希并相应地加载页面

    loadPage() {
        if (!window.location.hash) {
            // the param here is for updateHistory
            this.showLanding(false)
        } else {
            const person = this.getHashParam()
            person ? this.loadQA(person, false) : this.showLanding(true)
        }
    }
    

旁注:我发现this app 对在 Facebook 的 IAB 中测试我的本地代码非常有帮助。你给它一个链接(例如到你的开发站点),它会生成一个链接(你必须使用 xip.io 才能在 FB 中打开它),给你一个二维码来用你的手机扫描,它连接您的手机访问其开发工具并在浏览器中打开该链接。然后您可以复制链接,将其发布到只有您可以看到的私人 FB 帖子中,瞧!您可以在 Facebook 浏览器中访问本地服务器,Ghostlab 让您可以访问通常在 Chrome 中拥有的所有开发工具。

【讨论】:

    猜你喜欢
    • 2021-09-07
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 2012-06-05
    • 1970-01-01
    相关资源
    最近更新 更多