将屏幕宽度用Javascript获取并存入PHP变量

6
我有一个响应式网站,当网站处于“桌面”视图(屏幕可用宽度> 768)时,有一个 简单的下拉式登录菜单,位于其他导航链接旁边。当屏幕宽度低于768时,导航链接会出现在选择选项中。问题是,从选择选项中无法使用下拉式登录菜单。

我想使用PHP在屏幕宽度小于768时将下拉式登录菜单更改为简单的<a href>链接。

现在我在我的页面 <head> 中有:

<?
$screenWidth = '<script type="text/javascript">document.write(screen.availWidth);</script>';
?>

<body> 中:
<?
if($screenWidth <= "768") {
echo '<li><a href="login.php">Log in</a></li>';
} else {
?>
<div id="fancy">
<li id="login">
<a id="login-trigger" href="#">Log in <span>&#x25BC;</span></a>
<div id="login-content">
    <form>
        <fieldset id="inputs">
            <input id="username" type="email" name="Email" placeholder="Your email address" required>   
            <input id="password" type="password" name="Password" placeholder="Password" required>
        </fieldset>
        <fieldset id="actions">
            <input type="submit" id="submit" value="Log in">
            <label><input type="checkbox" checked="checked"> Keep me signed in</label>
        </fieldset>
    </form>
</div>                     
</li>
<? } ?>

在我的桌面上,我已经回显了$screenWidth,它显示为1920。因此,我期望“fancy”下拉式登录菜单被显示出来。(确实如此)。
在我的移动设备上,$screenWidth回显给出320。然后,我期望<a href>链接被显示出来。(但它没有-相反,它显示了“fancy”菜单)。
奇怪的是,当变量在body中回显时会给出不同的数字,但在if语句中比较时却不会改变输出。
有没有更好的方法来改变输出?
编辑:jquery响应式菜单代码

jquery.responsivemenu.js:

(function($) {
$.fn.responsiveMenu = function(options) {
    var defaults = {autoArrows: false}
    var options = $.extend(defaults, options);
    return this.each(function() {
        var $this = $(this);
        var $window = $(window);
        var setClass = function() {
            if ($window.width() > 768) {$this.addClass('dropdown').removeClass('accordion').find('li:has(ul)').removeClass('accorChild');}
            else {$this.addClass('accordion').find('li:has(ul)').addClass('accorChild').parent().removeClass('dropdown');}
        }
        $window.resize(function() {
            setClass();
            $this.find('ul').css('display', 'none');
        });
        setClass();
        $this
            .addClass('responsive-menu')
            .find('li.current a')
            .live('click', function(e) {
                var $a = $(this);
                var container = $a.next('ul,div');
                if ($this.hasClass('accordion') && container.length > 0) {
                    container.slideToggle();
                    return false;
                }
            })
            .stop()
            .siblings('ul').parent('li').addClass('hasChild');
        if (options.autoArrows) {
            $('.hasChild > a', $this)
            .find('strong').append('<span class="arrow">&nbsp;</span>');
        }
    });
}
})(jQuery);

可能是重复的问题,参考:为什么我的JavaScript中的PHP(或其他服务器端)代码无法工作?(https://dev59.com/VmYr5IYBdhLWcg3wOX66) - Quentin
1
你是在说 $screenWidth = '<script type="text/javascript">document.write(screen.availWidth);</script>'; 这段代码实际上可以通过为该变量分配一个数字值来工作吗? - Mark
1
这很有帮助,但它并没有真正解释为什么我可以使用 PHP 来 <? echo $screenWidth; ?> 并且毫无问题地得到结果,但是不能比较输出 <? if ($screenWidth <= "768") { //something } else { //something else } ?> - ScottD
1
@scd1982 是的,屏幕宽度是可见的,因为JavaScript被您的浏览器解析并包含在文档中。就PHP而言,$screenWidthstring(72)类型。PHP从未看到整数值,因为当您的浏览器看到网页时,PHP已经完成了工作。 - Mark
1
你的 <? echo $screenWidth; ?> 调用只显示数字的原因是因为浏览器没有显示其周围的脚本块。因此,出现了字符串(72)(72个字符)。这就是为什么你的比较不起作用的原因。$screenWidth 变量实际上是整个脚本块字符串。 - Barryrowe
显示剩余4条评论
5个回答

6
您最简单的选择可能是在DOM中填充两个选项,然后使用CSS3媒体查询根据屏幕大小来隐藏/显示适当的元素。
因此,您的HTML可能看起来像:
          <li class="login-link"><a href="login.php">Log in</a></li>
          <div id="fancy">
          <li id="login">
            <a id="login-trigger" href="#">Log in <span>&#x25BC;</span></a>
            <div id="login-content">
                <form>
                    <fieldset id="inputs">
                        <input id="username" type="email" name="Email" placeholder="Your email address" required>   
                        <input id="password" type="password" name="Password" placeholder="Password" required>
                    </fieldset>
                    <fieldset id="actions">
                        <input type="submit" id="submit" value="Log in">
                        <label><input type="checkbox" checked="checked"> Keep me signed in</label>
                    </fieldset>
                </form>
            </div>                     
        </li>

你的CSS可能如下所示:

.login-link, #login{
    display: none;
}
@media screen and (max-width: 767px){
    .login-link {
         display: block;
    }
    #login{
         display: none;
    }
}
@media screen and (min-width: 768px) {
    #login{
         display: block;
    }
    .login-link{
         display: none;
    }
}

编辑:修复#login引用。 编辑2:添加JSFiddle示例JSFiddle示例


这几乎满足我的要求了。在桌面视图中,“时髦”的下拉菜单出现(没有<a href>链接)。在移动视图中,菜单中出现<a href>链接和“时髦”的登录框。 - ScottD
我认为我见到的问题是,一旦屏幕调整大小到768以下,响应式jquery文件会获取所有<ul><li>并创建选择选项菜单。因此在移动版本中,我最终得到的是 <select>...<option value="login.php">登录</option><option value=#>登录 &#x25BC;</option>...</select>。 我正在将jquery响应式菜单文件添加到我的原始问题中。 - ScottD
1
你能把<a href>链接放在“fancy” <ul>之外吗?然后你可以设置CSS在<ul><a href>之间切换。这样,当你调用$("yourUlSelector").responsiveMenu();时,<a href>就不会被迭代了。 - Barryrowe
这就是我最终不得不做的。它并没有按照我想要的顺序显示,但我会调整CSS来实现。谢谢! - ScottD

5

PHP是在服务器端执行的,这意味着当你进行比较时,变量screenWidth包含的确切内容为:"document.write(screen.availWidth);"。而你的输出是在客户端执行的。


4
过去我们要使用JavaScript来制作响应式设计,但是自从CSS3开始可以使用@media来对视口变化进行响应。
例如:
@media screen and (max-width: 1280px) and (max-height: 1024px) {
    .splash {
        width: 100px;
    }
}
@media screen and (min-width: 1281px) and (max-width: 1920px) and (max-height: 960px) {
    .splash {
        width: 300px;
    }
}

1

一些想法:

我认为PHP不能直接与桌面进行交互。

最好的方法是让客户端通过JavaScript向您发送响应。在页眉中包含屏幕大小变量,立即将其发送回相同的页面,并将其作为cookie添加。如果cookie存在,则不要再次提交。

因此,第1步: 检查是否存在具有告知客户端屏幕大小的值的cookie。(或使用会话变量) 如果是,则运行它。 如果没有,则有一个JavaScript将您发送到具有标识窗口大小的查询字符串的相同页面。 第2步: 如果不存在cookie并且您拥有指示窗口大小的查询字符串,则创建cookie并相应地格式化。


1
很棒的“开箱即用”思路,但有更好的解决方案。 - lordvlad

0

你可以尝试一下

$userBrowserAtts = get_browser(null, true)

返回一个方便的数组,包含有关浏览器的各种信息。但要注意-这依赖于 $_SERVER['HTTP_USER_AGENT'],而这可以被欺骗。因此,这种方法并不是百分之百可靠的。我不知道它是否返回屏幕宽度,但您应该能够找出它是移动设备、平板电脑还是桌面电脑。
方便:

http://www.php.net/manual/en/function.get-browser.php

做这种事情的最佳方式是使用CSS3媒体查询,但如果服务器确实需要了解浏览器,那么这是你唯一能做的事情。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接