【问题标题】:Is it impossible to separate javascript from HTML?将javascript与HTML分开是不可能的吗?
【发布时间】:2009-07-08 11:25:48
【问题描述】:

具体来说,我说的是避免这种类型的代码:

<input type='text' id='title_33' class='title'
  onfocus='updateCharsLeft(33);' 
  onkeypress='updateCharsLeft(33);' />

在这里,我想将 onfocusonkeypress 事件句柄分别放在一个 .js 文件中。像这样:

$(document).ready(function()
  {
    $(".title").focus(updateCharsLeft);
    $(".title").keypress(updateCharsLeft);
);

但是这里的问题是文本框的 ID 需要传递给函数updateCharsLeft()。在该函数中必须从文本框的 ID 中提取 id 会很糟糕,所以实际上只在 HTML 代码中放入事件处理程序会更干净。

想法?

【问题讨论】:

  • 将 id 传递给更新函数的目的是什么?我也许可以提供更多信息。
  • 我认为您的标题或问题并不能真正反映您的要求 - 答案似乎类似于您似乎已经知道的“是的,将 HTML 与 Javascript 文件分开”。
  • 你的 updateCharsLeft() 函数是做什么的?

标签: javascript jquery code-organization


【解决方案1】:

你不能这样做吗:

$(document).ready(function()
  {
    $(".title").focus(function() {
        updateCharsLeft(this.id);
    });
    $(".title").keypress(function() {
        updateCharsLeft(this.id);
    });
);

或更简洁:

$(document).ready(function()
  {
    $(".title .another .someother .andAnother").focus(function() {
        updateCharsLeft(this.id);
    }).keypress(function() {
        updateCharsLeft(this.id);
    });
);

【讨论】:

  • 就像我在问题中所说的那样,必须使用 this.id 从函数中的“title_xx”中提取数字 id 会很糟糕。而且,这不是我需要设置事件处理程序的唯一元素,我需要在 10 个元素上设置它们,并且我不想在每个元素中复制用于从 this.id 中提取数字 id 的代码那些功能
  • @Click Upvote - 所以在你的选择器中指定多个元素,例如$('.title .foo .blah .g .f').keypress(blah...
  • 如果您不想使用上下文值(来自“this”对象),那么本质上您传入的值(“33”)就是幻数。如果你想重构你的代码以一种通用的方式绑定这些事件处理程序,你将需要使用一些上下文。您将必须传递 this.Id 并对其进行处理。除非……见下文……
  • 提取数字并不难 - 如果它们都是那种格式,你可以这样做。id.replace(/[^\d]/gi,"") 然后你'完成了。
【解决方案2】:

我之前不得不做类似的事情,并且对解析 ID 属性的值也不满意。我可以建议的最好的事情是您使用另一个属性作为您需要的值,例如 rel 属性:

<input type='text' id='title_33' class='title' rel='33' />

或者根据您对验证的虔诚程度,只需使用自定义属性:

<input type='text' id='title_33' class='title' myval='33' />

【讨论】:

  • 如何获取函数中rel的值?你能用 this.rel 吗?
  • 既然你已经在使用 jQuery,那就用 $(this).attr('rel')
【解决方案3】:

我绝对认为您应该将 JavaScript 和 HTML 分开。它会更容易找到/维护,您可以编辑一个地方而不是 10 个。不要重复自己。

我会考虑使用 jQuery 的 live 功能。如果您有 10 个文本输入,则以这种方式添加 20 个事件处理程序,而不是 2 个(一个用于页面上的每个焦点处理程序,一个用于页面上的每个按键处理程序)。

还有你对卡里姆的评论,我不明白你为什么要复制自己。只要您在命名约定中保持一致,传递 id 或在必要时使用正则表达式对其进行转换应该是微不足道的,例如,this.id.replace(/.*(\d+)$/,'')。但是,传递直接 DOM 元素引用并在您的函数中使用它可能会更好。

最后,您似乎认为这其中的某些方面会很糟糕。也许我错过了重点,但你能澄清一下 mainupaliting id 或 DOM 引用或你需要做的任何其他事情有什么困难吗?也许发布一个更长的代码示例来说明你接下来要做什么。

【讨论】:

  • 并不是说很难从 dom 元素的 id 中提取数字 id,只是需要在我的所有事件处理函数中重复此代码。
【解决方案4】:

如果你真的不想传递this.Id,那么你可以在输入标签中添加一个自定义属性...

<input type='text' id='title_33' idSuffix='33' class='title'/>

然后像这样设置事件处理程序...

$(document).ready(function()
{
    $(".title").focus(function() {
        updateCharsLeft(this.idSuffix);
    });
    $(".title").keypress(function() {
        updateCharsLeft(this.idSuffix);
    });
);

我个人喜欢自定义属性。它们提供了一种为 Html 标签提供自定义元数据并将其全部保存在标记中的方法。不过 Html 验证器不喜欢它们 :-(

【讨论】:

    【解决方案5】:

    我会尝试从单个 JavaScript 块中管理所有事件。只要您能够引用页面上的元素,这应该是可能的。

    【讨论】:

      【解决方案6】:

      您总是可以使用字符串函数来解析值并传递它,例如

      $(".title").focus(function() {
         var thisid = this.id;
         updateCharsLeft(thisid.substring(thisid.indexOf("_") + 1));
      });
      

      我不确定如果您必须对很多元素执行此操作会对性能产生什么影响。

      【讨论】:

        【解决方案7】:
        $(document).ready(function(){
            var update = function(){ updateCharsLeft(this.id.split("_")[1]); };
            $("input.title")
                .focus(update)
                .keypress(update);
        });
        

        【讨论】:

          【解决方案8】:

          这正是Unobtrusive Javascript technique 所关注的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-11-22
            • 2014-10-16
            • 2010-10-20
            • 1970-01-01
            • 2020-02-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多