0
<header>
<script type="text/javascript">
function hideit()
{

var x1 = document.getElementsByTagName("ol").item(0);
var x = document.getElementsByTagName("ol");
for (var i = 0; i < x.length; i++)
  x[i].style.display="none";
}
function showit()
{
var x1 = document.getElementsByTagName("ol").item(0);

var x=document.getElementsByTagName("ol");
for (var i = 0; i < x.length; i++)
 x[i].style.display="";
}
</script><header>
<body>
foreach $key (keys %{$stats_data{$out}})  {

    print $indexfd ("<input onclick=\"showit()\" type=\"button\" id=\"<?perl echo     $key; ?>\" value=\"showit\"><br><input onclick=\"hideit()\" type=\"button\" id=\"<?perl   echo $key; ?>\" value=\"hideit\"><br><b><ol id=$key>$stats_data{$out}{$key}<ol id=$key>  </b><br>");
        }</body>

我正在用 perl 创建一个 html 文档。我为每个 perl 变量(通过循环)编写了一个事件 mouseover 和 mouseout。但看起来事件同时控制了所有变量。我如何只编写一次事件但使其能够单独应用于每个项目:这就是我目前所拥有的

但是这个 html 在显示时,不允许我分别控制每个$key.

尽管确实为每个 $key 创建了按钮,但单击一个按钮可以控制$stats_data{$out}{$key}所有按钮。

我什至尝试将 id 传递给显示/隐藏脚本,但没有运气。

4

2 回答 2

7

您的代码看起来像是在尝试以使用 PHP 的方式将 Perl 与 HTML 混合。这在 Perl 中不起作用。

我尝试先修复您的 Perl 代码。这将打印到您的文件句柄(我省略了),但不会为您提供有效的 JavaScript 代码。我没有改变这一点,因为我不明白你想做什么。稍后再谈。

use strict;
use warnings;
# open of $indexfd filehandle goes here..

# print head of HTML page
print $indexfd <<HTML
<html>
  <header>
    <script type="text/javascript">
    function hideit() {
      var x1 = document.getElementsByTagName("ol").item(0);
      var x = document.getElementsByTagName("ol");
      for (var i = 0; i < x.length; i++)
        x[i].style.display="none";
    }
    function showit() {
      var x1 = document.getElementsByTagName("ol").item(0);
      var x=document.getElementsByTagName("ol");
      for (var i = 0; i < x.length; i++)
       x[i].style.display="";
    }
    </script>
  </header>
  <body>
HTML
;

# If I see this correctly, %stats_data looks like this:
my %stats_data = (
  'out1' => {
    'key1' => 'val1',
    'key2' => 'val2',
  },
  'out2' => {
    'key1' => 'val1',
    'key2' => 'val2',
  },
);
my $out = 'out1'; # you need the $out from somewhere
# print buttons for each data thingy - you'll want to sort them probably
foreach my $key (sort keys %{$stats_data{$out}})  {
  print $indexfd 
    qq~<input onclick="showit()" type="button" id="$key" value="showit"><br />~,
    qq~<input onclick="hideit()" type="button" id="$key" value="hideit"><br/>~,
    # Because $stats_data{$out} is a hash ref you need the -> operator here
    qq~<ol id="$key"><li><b>$stats_data{$out}->{$key}</b></li></ol><br/>~;
}

print $indexfd qq~<p>more html...</p></body></html>~;

所以有几点值得一提。

    print $indexfd ("<input onclick=\"showit()\" type=\"button\" id=\"<?perl echo     $key; ?>\" value=\"showit\"><br><input onclick=\"hideit()\" type=\"button\" id=\"<?perl   echo $key; ?>\" value=\"hideit\"><br><b><ol id=$key>$stats_data{$out}{$key}<ol id=$key>  </b><br>");

在您使用的这行相当长的代码中,<?perl echo $key; ?>它看起来像 php,但不起作用。您还使用<ol id=$key>了 which works 因为您使用了 double-quotes "..."。Perl 用 "-delimited 字符串中的变量替换它们的值。您不需要类似 php 的东西。为了节省您在 HTML 代码中转义所有双引号的工作,您可以使用qq-Operator。请参阅perlop了解更多信息。

我在评论中解释了%stats_data数据结构。

为了打印大量 HTML,我使用了HERE docs

现在让我们谈谈您的 JavaScript。

尽管确实为每个按钮创建了按钮$key,但单击一个按钮可以控制$stats_data{$out}{$key}所有按钮。

这是因为您设计hideit()showit()功能的方式。我不是很确定你想要实现什么。如果您查看我的%stats_data内容,您会发现“out1”中有几个键。这让 foreach 循环为每个键打印一组按钮。这两个按钮都具有与其 id 相同的键,ol 也是如此。这是不正确的。id-attribute 必须是唯一的。

此外,您的 html 中存在一些基本问题,我也冒昧地修复了这些问题。如果你打开一个<ol id="foo">容器,你需要像</ol>. 由于<ol>是块级元素,因此不应将内联元素放在<b>其外部,而应放在 ol 的<li>元素内(我省略了)。最好将 css ``style="font-weight: bold" 分配给 li 项目,或者更好地给它们类。

我将对您尝试使用 JavaScript 执行的操作进行最后一次猜测。如果您有几段文本,并且想用按钮隐藏它们,您可以像我在这里的未经测试的代码那样做。

Javascript:

function toggle(id) {
  if (document.getElementById(id).style.display == 'block' ) {
    document.getElementById(id).style.display = 'none';
  } else {
    document.getElementById(id).style.display = 'block';
  }
}

HTML:

<div>
  <input type="button" name="toggle1" id="toggle1" onclick="toggle('p1')" />
  <p id="p1">Lorem ipsum dolor set ... foo a lot of text 1.</p>
  <input type="button" name="toggle2" id="toggle2" onclick="toggle('p2')" />
  <p id="p2">Lorem ipsum dolor set ... foo a lot of text 2.</p>
</div>

在这种情况下,该函数会检查段落是否显示。display-value 需要设置为“none”或“block”,因为 p 元素是块级元素。

如果您需要更多帮助,请尝试发布有关您在脚本中使用的数据的更多具体信息。

编辑: 在下面的代码中,我将 JS 函数更改为都将 id(键)作为参数。它们仅显示或隐藏与此键关联的列表。我更改了按钮的 ID,所以它们不一样。我还在每对按钮和列表周围添加了一个 div,以便更清楚地知道什么属于哪里。

use strict;
use warnings;
# open of $indexfd filehandle goes here..
my $indexfd;

# print head of HTML page
print $indexfd <<HTML
<html>
  <header>
    <script type="text/javascript">
    function hideit(key) {
      document.getElementById(key).style.display = "none";
    }
    function showit(key) {
      document.getElementById(key).style.display = "";
    }
    </script>
  </header>
  <body>
HTML
;

# If I see this correctly, %stats_data looks like this:
my %stats_data = (
  'out1' => {
    'key1' => 'val1',
    'key2' => 'val2',
  },
  'out2' => {
    'key1' => 'val1',
    'key2' => 'val2',
  },
);
my $out = 'out1'; # you need the $out from somewhere

foreach my $key (sort keys %{$stats_data{$out}})  {
  print $indexfd 
    qq~<div id="div_$key">\n~, # Add a div around the $key-elements
    qq~<input onclick="showit('$key')" type="button" id="btn_show_$key" value="showit">\n~,
    qq~<input onclick="hideit('$key')" type="button" id="btn_show_$key" value="hideit"><br/>\n~,
    qq~<ol id="$key"><li><b>$stats_data{$out}->{$key}</b></li></ol>\n~,
    qq~</div>\n~;
}

print $indexfd qq~<p>more html...</p></body></html>~;
于 2012-04-25T08:29:52.560 回答
1

看起来您需要 Perl 的模板模块之一,例如Template Toolkit。它允许您将 Perl 片段嵌入到较大的文档中,然后对其进行处理,以便 Perl 部分填充您需要的任何内容。

这是我的一个网站的一个例子。它使用包装文件来包含顶部和底部部分,并读取一个 XML 文件以获取要填充中间的数据:

[% 
        title   = "The Perl Review" 
        xml     = "raw/xml/tpr_issues.xml"
        sidebar = 1
%]

[% PROCESS top %]

<table class="content-table">
<tr>
        <td colspan class="2">  

<h2>Next issue: April 15</h2>

[% PERL %]

use XML::Twig;

my $twig = XML::Twig->new;   

$twig->parsefile( $stash->get( 'xml' ) ); 

my $root = $twig->root;

my $latest_issue = $root->first_child( 'release' );

my( $volume, $issue, $year, $season ) = 
        map { eval {$latest_issue->first_child( $_ )->text } }
                qw( volume issue year season );

my $articles = $latest_issue->first_child( 'articles' );

print <<"TEMPLATE";
        <A class="cover-link" href="/Subscribers/ThePerlReview-v${volume}i${issue}.pdf"><img 
                class="cover-image-medium" height="396" width="306" 
                src="/Images/covers/v${volume}i${issue}-cover-medium.png" /></a>
        </td>
        <td class="article-cell">
        <h2 id="issue-header">Issue $volume.$issue, $season $year</h2>

TEMPLATE

foreach my $article ( $articles->children( ) )
        {
        my @children = map { $_->tag } $article->children;

        my %hash = 
                map { 
                        $article->first_child( $_ )->tag,
                        $article->first_child( $_ )->text
                        } 
                map { $_->tag } $article->children;

        print qq|\t<p class="article-title"><span class="article-title">$hash{title}</span>|;
        print qq| (<a href="$hash{sample_page}">sample</a>)| if $hash{sample_page};
        print "<br />\n";
        print qq|\t\t<span class="article-author">$hash{author}</span></p>\n|;          
        }

[% END %]

[% PROCESS issue_note %]

        </td>
</tr>

</table>


[% PROCESS footer %]
于 2012-04-25T15:04:24.483 回答