1

我有一个带有三个文本框的表单。我想对他们每个人都有一个关键事件,不管他们先进入哪一个。下面是我的代码:

function showQuoteBox() {
var overlay = '<div id="overlay"></div>';
var quoteBox = '<form id="quoteForm" action="#"><h1>Get a quote from <INSTALLERS NAME></h1><fieldset id="user-details"><label for="inName">Name:</label><input type="text" id="inName" name="name" value="" /><label for="email">Email:</label><input type="email" id="inEmail" name="email" value=""  /><label for="phone">Phone:</label><input type="text" id="inPhone" name"phone" value=""  /><input type="submit" value="Get quote!" name="submit" class="submit" /></fieldset><div id="sent-details"><span id="nameText"><span id="emailText"><span id="phoneText"></span></div></form>'
jQuery(overlay).appendTo('body');
jQuery(quoteBox).appendTo('body');
jQuery(document).ready(function() {
    jQuery('#inName').keyup(function(){
        jQuery('#nameText').html(jQuery(this).val());
    });
    jQuery('#inEmail').keyup(function(){
        jQuery('#emailText').html(jQuery(this).val());
    });
    jQuery('#inPhone').keyup(function(){
        jQuery('#phoneText').html(jQuery(this).val());
    });
});
}

window.onkeyup = function (event) {
   if (event.keyCode == 27) {
      jQuery('#overlay').remove();
      jQuery('#quoteForm').remove();
   }
}

以上是单击按钮时调用的整个函数。它显示了带有三个输入的quoteBox。每个输入框都允许我输入文本,但它只会更新第一个输入的跨度区域。如果任何其他文本框具有值,则所有其他文本框都不会更新。

如果我选择先输入一封电子邮件,它将显示在跨度中,但是当我在任何其他文本框中输入一个值时,它就不会收听。

4

3 回答 3

1

您描述的行为 - 只有一个键盘似乎在工作 - 很可能是由于您已将 3 个 SPANS 嵌入到另一个中!

<div id="sent-details">
    <span id="nameText">
        <span id="emailText">
            <span id="phoneText"></span>
</div>

不仅如此,我没有看到他们被关闭。SPAN 标签不会自动关闭,每个浏览器都会尝试自我纠正或以不同的方式解释这一点。某些浏览器可能会尝试为您关闭它们。

因此,您的第一个按键事件要么覆盖其他 2 个 SPAN 元素,要么 JavaScript 无法找到这些元素,因为您的 HTML 无效。

您的 HTML 的正确语法是:

var quoteBox = '<form id="quoteForm" action="#">' +
  '<h1>Get a quote from <INSTALLERS NAME></h1>'+
  '<fieldset id="user-details">'+
      '<label for="inName">Name:</label>'+
      '<input type="text" id="inName" name="name" value="" />'+
      '<label for="email">Email:</label>'+
      '<input type="email" id="inEmail" name="email" value=""  />'+
      '<label for="phone">Phone:</label>'+
      '<input type="text" id="inPhone" name"phone" value=""  />'+
      '<input type="submit" value="Get quote!" name="submit" class="submit" />'+
  '</fieldset>'+
  '<div id="sent-details">'+
      '<span id="nameText"></span>'+  // closed tags here
      '<span id="emailText"></span>'+ // closed tags here
      '<span id="phoneText"></span>'+ // closed tags here
  '</div></form>';

更可持续和可维护的解决方案:

顺便说一句,在 JavaScript 变量中存储一长串 HTML 是一种非常不可持续的处理标记的方式,因为它会导致不可读性,而这正是导致这类错误的原因。相反,如果我要解决这个问题,我会将这个 HTML 放在页面上,但使用display:none. 然后,在函数showQuoteBox中,我将简单地使用 CSS 类或 id 选择器来取消隐藏该代码块。

由于 HTML 将位于它所属的 HTML 文档中,因此它不仅更易于维护,而且您还可以与您的 Web 设计师交朋友,他们不想尝试对您的 JavaScript 进行逆向工程。

<div id="overlay" style="display:none">
    <form id="quoteForm" action="#">
        <h1>Get a quote from <INSTALLERS NAME></h1>
            <fieldset id="user-details">
                <label for="inName">Name:</label>
                <input type="text" id="inName" name="name" value="" />
                <label for="email">Email:</label>
                <input type="email" id="inEmail" name="email" value=""  />
                <label for="phone">Phone:</label>
                <input type="text" id="inPhone" name"phone" value=""  />
                <input type="submit" value="Get quote!" name="submit" class="submit" />
            </fieldset>
           <div id="sent-details">
               <span id="nameText"></span>
               <span id="emailText"></span>
               <span id="phoneText"></span>
          </div>
      </form>
  </div>

function showQuoteBox() {
     // var overlay = '<div id="overlay"></div>';  <-- don't do this
     // var quoteBox

     // instead, use jQuery to unhide your HTML and keep it out of the JavaScript
     $('overlay').show();  

     // the rest of your code follows
     ...
 }

最后,看起来您将 keyup 事件代码包含在 functionshowQuoteBox中。页面加载完成并且 DOM 准备就绪后,jQuery 对象上的ready方法就会触发,因此在函数中注册该事件似乎有点奇怪。

在这种情况下,您在使用 jQuery 将一些 DOM 元素添加到已加载的页面时注册这些事件。因此, (document).ready 不仅没有必要,而且可能会出现问题。如果按照上一节中的步骤操作后仍然遇到问题,请考虑删除 document.ready 包装器,如以下代码块所示:

// don't put document.ready around this since it's in a function you're calling to show a form
jQuery('#inName').keyup(function(){
    jQuery('#nameText').html(jQuery(this).val());
});
jQuery('#inEmail').keyup(function(){
    jQuery('#emailText').html(jQuery(this).val());
});
jQuery('#inPhone').keyup(function(){
    jQuery('#phoneText').html(jQuery(this).val());
});
于 2012-05-10T01:29:26.477 回答
0

只是..做你正在做的事。只要将其包装在 $(document).ready 中就应该可以正常工作

于 2012-05-10T00:56:57.597 回答
0

由于您重复相同的行为,我认为您应该使用插件。我称之为模仿。它未经测试(因为没有 html 或 jsfiddle 可以解决),但它应该可以解决问题。

(function($) {
    $.fn.mimic = function(selector) {
        var $elementToMimic = $(selector);

        $.each(this, setupMimicEvents);

        function setupMimicEvents() {
            var $mimicer = $(this);

            $elementToMimic.on('keyup', mimicElement);

            function mimicElement() {
                var value = $elementToMimic.val();
                $mimicer.html(value);
            }
        } 

        return this;
    }
})(jQuery)

jQuery(function() {
    jQuery('#nameText').mimic('#inName');
    jQuery('#phoneText').mimic('#inPhone');
});

此外

如果你打算使用 jQuery,那么也将它用于 body 上的事件。我不确定您到底要做什么,但这似乎有点不对劲。

于 2012-05-10T01:12:29.700 回答