0

我想向使用 Zend 框架构建的现有网站添加一个功能。该网站的问题之一是它经常在网页的不同位置刷新页面。我想做的是使用内置的 Zend 框架功能在网页刷新后保持相同的位置。

一个例子是:用户点击页面底部,相同的页面被重新加载,但它没有在页面顶部重新加载,它停留在用户上次点击的位置。

有这样的事吗?

谢谢

4

3 回答 3

1

您必须结合使用 Javascript(在前端)和 Zend Framework(在后端)来实现这一点。

这是假设您正在使用用户 cookie/会话。

  1. 创建一个事件处理程序,以在页面上的任何位置使用 Javascript 检测鼠标点击。在事件处理程序中,使用event对象获取鼠标位置的 x 和 y 坐标。(鼠标点击事件坐标
  2. 在 Zend 框架中设置一个端点,它将接受用户的鼠标坐标。例如:http://localhost/user/updateCoordinates?x=12&y=100
  3. 在鼠标单击时,让您的事件处理程序执行 AJAX 查询,将坐标发送到您在 #2 中设置的端点。
  4. 在 Zend Framework 中,将这些坐标存储在用户会话/cookie 中(以便您以后可以跟踪它)
  5. 在页面加载时,从会话中获取值并输出 Javascript 代码以自动滚动到该坐标。此外,从 cookie 中删除 x 和 y 坐标,因为它已经被使用过。
于 2012-10-16T15:40:14.637 回答
0

您可以使用一些 javascript 在刷新之前记录窗口的滚动位置,并将其保存到 cookie 中。

然后,当下一页加载时,检查 cookie,滚动到它的位置,然后删除它。如果网页具有动态大小的元素(例如:展开的手风琴菜单),这将无法正常工作。

不过就个人而言,我会尽量避免这种情况。我时不时地访问一些喜欢用我的滚动条做事的网站,并试图帮助我。他们经常弄错了,网页变得无法使用。也许您可以动态更新页面(ajax?)而不是进行真正的重新加载。

于 2012-10-16T15:38:32.880 回答
0

您可以使用 ZF 的现有组件并将它们组合到一些新插件中:

1)在我的例子中,新的 ZF 插件保存在 ZF 结构中:/library/My/Controller/Plugin/ActionHistory.php

final class My_Controller_Plugin_ActionHistory extends Zend_Controller_Plugin_Abstract
{

/** @var bool flag indicating whether current action has been already logged */
private $dispatched = false;

/**
 * @param Zend_Controller_Request_Abstract $request
 * @return void
 */
public function pushStack(Zend_Controller_Request_Abstract $request) {
    $storage = $this->getStorage();
    $storage->stack[] = $request;
    // limit the depth of the stack
    if (count($storage->stack) > $this->getMaxDepth()) {
        array_shift($storage->stack);
    }
    // mark current action as dispatched (influences getBacklink())
    $this->dispatched = true;
}

public function popStack() {
    $storage = $this->getStorage();
    return array_pop($storage->stack);
}

/**
 * Returns request to previous action (not current).
 *
 * @return Zend_Controller_Request_Abstract|null
 */
public function getBacklink() {
    $storage = $this->getStorage();
    $depth = count($storage->stack);
    // points to top of the stack
    $backlinkIndex = $depth - 1;
    if ($this->dispatched) {
        // current action has been already logged, "backlink" is second from the top
        --$backlinkIndex;
    }

    return ($backlinkIndex >= 0 ? $storage->stack[$backlinkIndex] : null);
}

/**
 * Returns stack with performed actions
 * @return array
 */
public function getStack() {
    return $this->getStorage()->stack;
}

/**
 * @return Zend_Session_Namespace
 */
private function getStorage() {
    static $storage = null;
    if ($storage === null) {
        $storage = new Zend_Session_Namespace(get_class($this), true);
        if (!is_array($storage->stack)) {
            // initialize stack if needed
            $storage->stack = array();
        }
    }
    return $storage;
}

/**
 * Returns maximal depth of the action history
 * @return int
 */
private function getMaxDepth() {
    return 3;
}
}

2)将此代码放在某个地方以将历史推送到堆栈中。您只能使用历史记录,例如与登录到应用程序的合作,或者您可以保存所有历史记录。这取决于你:

// this code is example of usage in another ZF controller plugin class
$actionHistory = Zend_Controller_Action_HelperBroker::getStaticHelper("ActionHistory");
if ($actionHistory) {
    // $this => instance of Zend_Controller_Plugin_Abstract
    $actionHistory->pushStack($this->getRequest());
}

3)然后你可以在一些你想要处理动作历史的控制器中使用这个插件:

// check if there is an backlink stored in actionStack, if yes than use it
if (($actionHistory = $this->getHelper('actionHistory'))) {
$request = $actionHistory->getBacklink();
if ($request) {
    $actionHistory->popStack();
    // use any of your redirect classes or simle redirector helper
    // right path to previous site is accesible by $request->getUserParams()
    $this->redirect($request->getUserParams());
}
}

就是这样:) 希望你可以修改你想要的,但是这个解决方案的理论和好处是很清楚的......

于 2012-11-06T12:27:03.560 回答