在JS糟糕的做法中使用PHP if / else吗?

时间:2013-04-03 22:09:18

标签: php jquery wordpress if-statement

我正在为WordPress构建一个自定义模板,并且我在几个地方使用了PHP if if语句,如页脚JS中的以下示例。它工作正常,但我想知道这是否被视为“不良做法”,如果是这样,有什么更好的方法来处理它?<​​/ p>

<script type="text/javascript">
var $submenu = $('.submenu');
// SUBMENU animation
<?php if ( in_category('Collection') == false ) { ?> // if not a Collection subpage
    $('.menu li a').each(function() { 
        if ( $(this).text() == 'Collection' ) { // If is Collection link show submenu on hover
            $(this).mouseenter(function() { 
                $submenu.slideDown(); 
            });
        } else { // else close submenu on hover over other menu links
            $(this).mouseenter(function() { 
                $submenu.slideUp(); 
            });
        }
    });
    $('.nav').mouseleave(function() { // close submenu
        $submenu.slideUp(); 
    });
<?php } else { ?> // If a Collection subpage always show subnav
    $submenu.show();
<?php } ?>
</script>

3 个答案:

答案 0 :(得分:2)

虽然混合使用PHP和JavaScript并没有什么问题,但我个人认为阅读和修改非常尴尬,而且它会使代码变得棘手。例如,如果您决定将该JavaScript导出到外部文件,这有很多好处:

<script src="myjs.js.php"></script>

如果您需要知道某些值以便计算in_category('Collection'),因为您必须开始使用GET参数(除非您依赖于会话变量,这可能变得非常复杂和不可预测,尤其是通过资产请求):

<script src="myjs.js.php?random_vars_required=123"></script>

另一点要警惕的是,当有一个JavaScript文件根据服务器端逻辑改变它的内容时,你必须小心浏览器的缓存(为了避免这些类型的问题,它基本上意味着您必须更改js文件的每个可能结果的请求URL)。即。

<script src="myjs.js.php?collection=true"></script>
<script src="myjs.js.php?collection=false"></script>

另一个缺点是通过将PHP与JS混合,您可能最终会在许多地方复制PHP代码,而这些代码与DRY主体相反。这就是为什么建议将数据导出到javascript变量&#34;是一个更好的主意。但是,如果可能的话,最好避免全局js命名空间中的变量。如果您需要跨多个JavaScript文件共享逻辑并且不希望将变量导出到每个文件的顶部,那么避免使用全局命名空间可能会很棘手。

另一种可能性

如果您正在测试的逻辑本质上纯粹是布尔值,并且它还以页面分类(或子区域分类)为中心,以下是处理您要实现的内容的一种很好的方法。它很好主要是因为它将PHP和HTML保持在一起,并且你的JS分开了。

以下内容应放在用于生成外部HTML的模板中:

<?php

    $classes = array();
    if ( in_category('Collection') ) {
      $classes[] = 'collection';
    }
    $classes = implode(' ', $classes);

?>
<!-- 
  obviously you'd render the rest of the html markup
  I've removed it for simplicity
//-->
<body class="<?php echo $classes; ?>"></body>

然后在你的JavaScript / jQuery中:

if ( $('body.collection').length ) {
  /// if collection sub page
}
else {
  /// else do otherwise
}

如果您不想在body元素中添加类,则可以始终根据页面的一个版本上已存在的内容而不是另一个版本上的内容来定义布尔检查。虽然我个人喜欢保持干净,只是在我知道HTML标记将来不会发生太大变化时才采用这种检查。

几乎所有大型世界今天都应该担心的浏览器都支持元素上的多个类。所以这意味着即使您有多个要检查的内容,只要它有意义,您可以将这些类放在htmlbody标记上并使用jQuery的Sizzle实现为你找到它们。

答案 1 :(得分:2)

构建javascript服务器端可能是我们已经完成的事情,尽管没有这样做的主要论据 - 即js不能(轻松)验证(例如.jsLint),而不能(容易)放入.js文件 - 没有必要允许浏览器只缓存两个或更多可能版本的脚本中的一个。

您可以考虑将客户端分支的服务器端分支进行权衡,这可以说代码更具可读性,但更重要的是,这是我最终建议的中间步骤(请耐心等待):

var $submenu = $('.submenu');
// SUBMENU animation
var isCollection = <?php echo in_category('Collection') ? 'false' : 'true' ?>;
if ( !isCollection ) { // if not a Collection subpage
    $('.menu li a').each(function() { 
        if ( $(this).text() == 'Collection' ) { // If is Collection link show submenu on hover
            $(this).mouseenter(function() {
                $submenu.slideDown(); 
            });
        } else { // else close submenu on hover over other menu links
            $(this).mouseenter(function() {
                $submenu.slideUp(); 
            });
        }
    });
    $('.nav').mouseleave(function() { // close submenu
        $submenu.slideUp();
    });
} else { // If a Collection subpage always show subnav
    $submenu.show();
}

然而,如果布尔isCollection可以通过其他方式确定(例如通过查询DOM的某些方面,例如data-xxx属性),那么你'用煤气做饭。只需要一个版本的js脚本;它可以很容易地用jsLint验证;如果需要,可以移动到.js文件中。

当然你需要在服务器端代码的其他地方设置data-xxx属性(或其他)(带有解释性注释),这可能是一个缺点,但可能不是很大。

也许不是所有的js都能接受这种方法,但我认为问题中的例子是。

在我看来,这是一个可行的方法。

答案 2 :(得分:1)

至少它不是伟大代码的标志。还有其他选择:

  • Generate一个JSON对象并用JavaScript解析它
  • 动态包含JS文件
  • 设置条件:

    if(<?= (int)$mybool ?>) {
        doSomething();
    }