jQuery无法更改JS可以更改的值,因为库已过期

jQuery cannot change a value where JS can because the library is out of date

本文关键字:因为 过期 JS jQuery      更新时间:2023-09-26

简单的答案:

我的代码库使用的jQuery库已经过时了。

如果您的是最新的,请尝试以下操作:

  1. 逐步浏览未缩小的jQuery版本,以查看问题是否在库内(10次中有9次可能不会(

  2. 当所有其他方法都失败时,只需编写一个纯JavaScript解决方案。


有时当我用jQuery在javscript中编写"类"时,jQuery将无法正常工作。 例如,今天我在输入选择上执行以下操作:

$(this).val(newValue);

这在 jFiddle 中工作得很好,但在我的项目中不起作用(两者都有 0 个脚本错误(。我试图尽可能地隔离代码,但无济于事,我无法让它工作。

对此的"解决方案"是直接编写javascript来设置值,并且它工作得很好。

我不是jQuery大师,但这不是我第一次在jQuery"失败"时编写直接的javascript解决方案。 有没有jQuery大师知道为什么会发生这样的事情? 有没有我不知道的调试jQuery的方法? 还有其他人在jQuery中遇到这些类型的问题吗? 如果是这样,您有解决方案吗?


更新

2011-8-25

我下载了最新版本的jQuery库并逐步浏览了它,只是发现该错误可能在jQuery 1.4.4和1.6.2之间得到解决。 我没有意识到处理大部分javascript的人没有使jQuery库保持最新状态。 在逐步浏览 jQuery 1.4.4 库后,似乎 jQuery 由于某种原因无法找到我的选择器,因此从未设置过该值。 此问题已在 1.6.2 中解决。

本周的教训...使您的 jQuery 库保持最新状态,并在内容不匹配时验证高级开发人员的陈述。

-

选择了我所做的答案,因为它是唯一真正帮助我诊断问题根源的答案。 虽然逐步浏览 jQuery 的未缩小版本是如此简单的解决方案,但我实际上应该在发布此问题之前完成此操作。 稍后我将发布我的发现,说明为什么它不起作用。


2011-8-24

我同意用户Sohnee的观点,即拥有重复的"名称"并不是不好的做法,在某些地方您确实需要它。

我觉得自己很愚蠢,因为发布的代码已经错误了将近一周了。 我已经更新了代码。 我将 init 函数移到了公共范围。


2011-8-22

虽然我对问题的核心是重复的名称感到部分满意,但我需要知道为什么重复的名称不好?

我知道在处理输入/css/等时,你通常除了 ID 是唯一的和代表组的类。 我不认为有任何关于名字的规则,但如果有人能向我解释为什么重复的名字是不好的习惯,我会认为这是这个问题的答案。


2011-8-16

至于目前的答案,我不认为这是冲突。 jQuery工作得很好。 绑定正在触发,导致在两个实现中调用函数。

问题行是

$(overrideSelector).each(
    function(){         
        $(this).val(newVal);
    }
);

例如,如果我在 .each(( 中控制台化newVal,它将有一个值,让我们说"A"。
然后,如果我控制台注销$(this).val()它将是"B"。然后运行$(this).val(newVal);。 之后,如果我做一个控制台日志$(this).val()它仍然是"B"。

在评论中,有人提到我可能用错了this这个词。 这两个在Chrome的控制台上都返回了0个javascript错误。我将给出以下代码片段是有问题的。 我将编写原文,然后用javascript替换它。

我知道名字是一样的,但这没关系。 我正在处理的页面是一个巨大的表单,克隆的选择只是为了让用户不必滚动回表单的另一部分。

.HTML:

<div id='overrideHolder'>
</div>
<select name='mySelect'>
    <option value='A'>A</option>
    <option value='B'>B</option>
</select>

jQuery(这不起作用(:

var someClass = (function(){
    var overrideSelector = '[name="mySelect"]';
    ...
    return{
        init : function(){
            $(overrideSelector).clone().appendTo('#overrideHolder');
            $(overrideSelector).each(
                function(){
                    $(this).bind(
                                 'change', 
                                 {}, 
                                 function(){
                                        someClass.overrideTryAgain(this);
                                 }
                    );
                }
            );
        }
        overrideTryAgain : function(element){
            var newVal = $(element).val();
            $(overrideSelector).each(
                function(){         
                    $(this).val(newVal);
                }
            );
            ...
         },
         ...
    } 
})();
$(document).ready(function(){
    someClass.init();
}

Javascript(这有效(:

var someClass : (function(){
    var overrideSelector = '[name="mySelect"]';
    ...
    return{
        init : function(){
            $(overrideSelector).clone().appendTo('#overrideHolder');
            $(overrideSelector).each(
                function(){
                    $(this).bind(
                                 'change', 
                                 {}, 
                                 function(){
                                        someClass.overrideTryAgain(this);
                                 }
                    );
                }
            );
        }
        overrideTryAgain : function(element){
            // NOTE: Using javascript instead of jQuery because jQuery was not duplicating the selected value properly
            var newValue = $(element).get(0);
            newValue = newValue.selectedIndex;
            $(overrideSelector).each(
                function(){
                    var currentSelect = $(this).get(0);
                    currentSelect.options[newValue].selected = true;
                }
            );
            ...
        },
        ...
    }
})();
...
$(document).ready(function(){
    someClass.init();
}

我试图从您的代码中重现该问题,但像其他人一样无法这样做。因此,似乎有一些外部因素在干扰:冲突,标记的东西,但通常不明显的东西。

这听起来像是源代码步进的工作。针对未缩小的jQuery运行此操作,并使用调试器(例如内置的Chrome调试器或Firebug(跟踪违规行,以查看jQuery内部发生了什么。这应该揭示出了什么问题,无论是jQuery错误还是你自己的代码/标记中你以前没有看到的东西。

你必须确保你选择了正确的元素。为此,您可以使用Chrome console.log来查看您尝试设置值的DOM节点。

HTML上重复的名称是不好的,原因很简单。当表单发送到服务器时,其中的输入元素被提交,通过一个对象发送值,该对象的关键是 DOM 名称。如果您有重复的名称,则对象不会使用唯一键绑定值。您可以以不同的形式使用相同的名称,这是允许的。

您可以查看表单控件 (w3.org( 的 html 规范,以获取有关控件名称和复选框行为的详细信息。

WebForms 应用程序需要注意的是:整个页面是一个表单,永远不要使用相同的名称......

首先,确保包含jquery库。 然后尝试使用 jQuery 对象,而不是$某些库在其代码中使用$。 另请查看jQuery.noConflict()方法:

http://api.jquery.com/jQuery.noConflict/

如果目的只是在选择之间克隆和"同步"值,那么您的解决方案似乎有点太复杂了。首先,您可能不需要所有的每个循环,因为 $(overrideSelector( 会自动为您执行此操作。无论如何,这里是您代码的简化版本(如果我错过了您的代码应该做什么的目的,请告诉我(

var someClass = new function() {
         var overrideSelector = '[name="mySelect"]';
        this.init = function() {
            $(overrideSelector).clone().appendTo('#overrideHolder');
            $(overrideSelector).live("change", function() {

                $(overrideSelector).val($(this).val())
            })
        }
    }
    $(document).ready( function() {
        someClass.init();
    })

关于更新,这对我来说似乎总是更可靠:

$(overrideSelector).each(
    function(i, element){         
        $(element).val(newVal);
    }
);

我正在研究这个问题,但我无法让它与您的代码一起使用,但我尝试自己实现它......

这对你有用吗?

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
</head>
<body>
    <div id='overrideHolder'>
    </div>
    <select name='mySelect'>
        <option value='A'>A</option>
        <option value='B'>B</option>
    </select>
    <input id="addSelect" type="button" value="Add select" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
    <script type="text/javascript">
        (function ($) {
            var _constants = {
                selector: 'select[name="mySelect"]'
            };
            var _methods = {
                init: function () {
                    var $select = $(_constants.selector).live('change', function (e) {
                        var $this = $(this);
                        var val = $(this).val();
                        $(_constants.selector).not($this).val(val);
                    });
                    _methods.cloneSelect($select);
                    $('#addSelect').click(function (e) {
                        _methods.cloneSelect($(_constants.selector).eq(0));
                    });
                },
                cloneSelect: function ($select) {
                    $select.clone().appendTo('#overrideHolder');
                }
            };
            //shorthand for $(document).ready
            $(function () {
                _methods.init();
            });
        })(jQuery);
    </script>
</body>
</html>

在更深层次上存在问题。

  1. 你不能简单地克隆选择,你不应该有两个同的元素
  2. 将原件
  3. 和克隆件分开处理,无需侦听原件上的更改或重置副本上的值
  4. 删除 .each 调用,jQuery 已经在内部为您完成了此操作
  5. $(element(.get(0( === element.你把它放进去,然后把它拿出来。

也就是说,你可以按照Michal的建议尝试一些东西:

var mySelect = $(overrideSelector)
var mySelectClone = mySelect.clone().appendTo('#holder')
mySelectClone.bind('change', function(){
  addressValidation.overrideTryAgain(this)
})
...
overrideTryAgain : function(element){
  var newVal = $(element).val()
  mySelect.val(newVal)
}

另外,您是否比较了两个版本的输出?

overrideTryAgain : function(element){
    var newVal = $(element).val()
    var newVal2 = element.options[element.selectedIndex].value
    console.log("jQuery: "+ newVal)
    console.log("DOM: "+ newVal2)
    $(overrideSelector).val(newVal);
    ...
},

如果你的选项值包括空字符串或其他虚假值("0"等(,你就受到了伤害。

我看到重复的命名表单元素会导致问题,所以我会尝试消除这些问题。

在这种情况下,我还建议非常小心val()方法。它在你的代码中看起来不错,但很容易盯着一些期望事物的代码,忘记val()只返回第一个匹配元素的值(在 DOM 中(。

我试图复制你的问题,但不能。您可以进行相当多的简化,以揭示问题:

  • 使用change而不是bind('change',{}
  • 消除each呼叫
  • newVal传递到overrideTryAgain方法中,而不是元素。不需要该元素,这将使测试/调试更容易。

        var selector = "[name=mySelect]";
        var holder = "#overrideHolder";
        ...
        $(selector).clone().appendTo(holder);
        ...
        $(selector).change(function () {
            overrideTryAgain($(this).val());
        });
        var overrideTryAgain = function (newVal) {
            $(selector).val(newVal);
        }
    

在不同的 HTML 输入标签中有重复的"名称"不好吗? - 如果是这种情况,那么单选按钮会很糟糕。

jQuery不能改变JS不能的值

jQuery在执行您的要求方面没有任何问题,如果没有完整的代码,几乎不可能确定 - 这工作得很好。

此语句由以下小提琴 http://jsfiddle.net/EeQEN/支持,该小提琴只是对所提供代码的简化。

var overrideSelector = '[name="mySelect"]';
var overrideTryAgain = function(element) {
    var newVal = $(element).val();
    $(overrideSelector).each(function() {
        $(this).val(newVal);
    });
};
$(overrideSelector).clone().appendTo('#overrideHolder');
$(overrideSelector).each(function() {
    $(this).bind('change', {}, function() {
        overrideTryAgain(this);
    });
});

我已经尝试了所有最新版本的jQuery,除非它是特定浏览器的错误(您尚未指定(,否则我怀疑问题出在可变范围的韭菜上。

如果您不相信,请提供问题的功能示例,我相信可以确定确切的问题。

一条建议供将来参考,不要重新查询 DOM;缓存所有选定的元素,并且永远不要通过循环通过元素来应用事件 - 使用委托并允许事件冒泡,这不仅会提高性能,还会使您的代码更易于维护。

在许多表单元素上具有相同的名称属性实际上是有效的,这实际上是某些表单元素设计的工作方式,例如单选按钮。这也是一些服务器端语言被设计为工作的方式,例如php中的数组式命名name="country[]"

使用重复的名称并不是不好的做法 - 您只需要知道,当您按名称获取元素时,您不会处理唯一元素。实际上,document.getElementsByName("sharedName") 返回一个结果数组,即使您只有一个具有指定名称的元素也是如此。

因此,这不是一个不好的做法的问题,而是你的代码(或你正在使用的框架中包含的代码(是否理解这种非唯一性的问题。

我认为你可能有一些运气来实现jQuery Class。

我把你用的类放在jsfiddle中,即便如此,它也提出了一堆问题。括号不是在所有地方都闭合的,然后你尝试在函数内部定义方法,当它们没有链接在一起时。

var someClass = function(){
 ...
})();

缺少"函数"左侧的括号,并尝试在结尾括号中放入jQuery。

var someClass = (function(){
 ...
})(jQuery);

除此之外,我认为您无法定义正常的"方法">

init : function(){
overrideTryAgain : function(element){

就像在父函数中一样。