我有附加了javascript控件的小部件。

如果在加载小部件管理页面时该小部件存在,则该控件可以正常工作。

当我添加新的小部件时,它们无法正常工作,我得到了标记,但是没有javascript事件生效。

如果我保存新的小部件,则在重新加载表单时,控件将正确创建并且可以正常工作。

刷新页面也可以解决此问题,但仅适用于现有的小部件。新的小部件仍然存在此问题。

具体来说,我正在以下位置对select输入进行选择:


文档就绪
Ajaxcomplete

我已验证我的代码已按需在每个事件上运行,但结果未达到预期的结果。
https://gist.github.com/Tarendai/8466299

您会看到我有一个计数器,发现它可以转换的每个select元素都会增加。

注意:


加载小部件页面时,我可以看到JS控制台中的计数器按预期增加了。
添加新的小部件时,代码为运行,但是,它找不到能在其上运行的任何选择元素,如found.length为0所示。情况并非如此,因为该类型的每个新小部件都应具有选择元素
选择元素有一个可识别它们的类,一旦应用了selectize库以防止重复操作,该类将被删除d在现有的小部件上进行重新处理。
在使用selectize之前,我使用了具有相同问题的Select2
注释掉AJAX代码,我希望新的小部件具有标准的select输入。他们不。我不知道为什么会出现这种情况

那么如何在不告诉用户进行更改之前刷新/单击保存的情况下使selectize控件起作用?

评论

这是一个事件委托问题。您将需要研究使用jQuerys .on()方法。这需要您将事件绑定到文档。但是,现在不确定什么事件合适。最终,这是因为您的原始绑定代表了页面加载时DOM的初始版本,并且大多数情况下看不到通过ajax添加的新元素(小部件内容)。希望这会为您指明正确的方向,如果没有,我在工作时可以回答得更好。

这就是我的预期,也是为什么我添加了jQuery(document).ajaxStop(function(){部分,以便可以在新加载的小部件中初始化控件。但是,如果我删除该行,我希望新的小部件具有标准的HTML选择输入,但不= s

正如@ aaron-holbrook所说,通过使用窗口小部件更新和窗口小部件添加的事件,其方法是最干净的方法。我还要在@michaeljames代码中强调元素ID#widgets-right的使用。确保使用它来定位JS代码中的活动窗口小部件元素,否则您可能会得到重复的元素,因为您的代码还可能选择屏幕左侧的隐藏的非活动窗口小部件元素(添加窗口小部件时会被克隆)。

#1 楼

好消息,

我已修复它。那会教我在火车上用手机接听!

您对ajaxstop的使用是正确的。大部分情况下,使JS正常工作,您可能会看到CSS样式已初始化以及DOM中的更改。

这是因为未通过ajax加载窗口小部件内容,实际上它是从隐藏它的左侧列中克隆它,然后触发ajax调用以将窗口小部件的位置保存在右侧列中。这就解释了为什么ajaxstop可以工作,甚至克隆了思想内容。但是,由于左侧列中有小部件的隐藏版本,因此您的JS正在对此进行实例化。这样,当您将其拖到右侧列时,就得到了隐藏的小部件的变形副本。下面是更正的代码:

<script>
jQuery( document ).ready( function( $ ) {
    function runSelect() {
        var found = $( '#widgets-right select.testselectize' );
        found.each( function( index, value ) {

            $( value ).selectize();
                .removeClass( 'testselectize' )
                .addClass( 'run-' + window.counter );

            console.log( $val );
            window.counter++;
        } );
    }

    window.counter = 1;

    runSelect();

    $( document ).ajaxStop( function() {
        runSelect();
    } );
} );
</script>


评论


天哪,我需要测试一下<3

– Tom J Nowell♦
2014年1月17日14:18

非常优雅的解决方案,可以解决重大的头痛问题!

– Bosco
2014年1月17日在20:13

我建议不要在每个“ ajaxStop”事件上运行,而建议在“ widget-added”和“ widget-updated”事件上使用。

– Tyrun
2014年8月11日19:45在

#2 楼

正如@ aaron-holbrook所说,一种更清洁的方法是:

jQuery(document).on('widget-updated widget-added', function(){
    // your code to run
});


评论


可能应该使用jQuery而不是$

–马克·卡普伦
16年1月11日在10:26