繁体   English   中英

如何确定元素是否动态创建

[英]How to determine if an Element was created dynamically

我有一个使用jQuery,Backbone.js和一个用C#编写的REST-ish后端构建的现有系统。 该应用程序是SPA,其中包含要填写和导航的表格。 我的工作是构建一个“导航拦截器”以在应用程序上进行连接,以便系统检测当前视图中的字段是否已被修改,以便在用户导航时,将警告他字段已被修改并被要求保存或取消。变化。

我设计它的方式是使用jQuery。 为了简短起见,我在inputselect等上使用了一个选择器,然后将change事件绑定到它。 然后,我在链接和按钮上使用选择器,取消绑定所有点击事件,绑定我的“拦截器”(如果字段已更改,请在导航之前询问),然后在拦截器之后重新绑定所有点击事件。 我使用stopImmediatePropagation()取消常规的导航事件,从而导致围绕事件的包装。

这样做有两个问题:

  1. 在字段上调用.val()不会触发change事件,这很好,因为我是动态填充字段的。 问题在于,引导日期选择器似乎未使用.val()设置值,导致所有日期字段在初始化时均处于“已更改”状态。

  2. 动态创建的元素(例如:页面加载后在手风琴面板中创建的字段)不接受事件,导致表单无法触发导航拦截器的change事件。

我的问题是关于以上两个元素:

  1. 有没有一种方法可以确定特定字段是否为日期选择器,并将更改事件绑定到该字段,以便当我填充该更改事件时不会触发更改事件,但是当用户这样做时(我尝试在该字段上进行绑定) changeDate事件,但setDate方法似乎也触发了changeDate事件)?
  2. 有没有办法确定元素是否是动态创建的(例如:$(''))? 问题是我没有针对单个字段的特定选择器,所以我认为我不能使用委托( $(document).on('change', 'someFieldSelectorICannotKnow', function () {}); )。 我所拥有的只是jQuery元素的句柄$(this) .each(fn)迭代中的$(this) )。

#2在所有字段上使用事件委托解决,如果该字段不是表单字段,则跳过处理程序

NavigationInterceptor.prototype.bindChangeEventOnAllEditableFields = function () {
    var self = this;

    var fieldsSelector = $(this.configuration.selectors.formFields.join(', '));
    $(fieldsSelector).each(function () {
        var isFormField = !self.searchClassFromArrayInElement(self.configuration.classes.nonFormFieldClasses, $(this));

        if (isFormField && self.configuration.debug.highlight.fields.unchanged && $(this).attr('type') === 'radio') {
            $(this).parent().css('background-color', self.configuration.debug.highlight.fields.unchanged);
        } else if (isFormField && self.configuration.debug.highlight.fields.unchanged) {
            $(this).css('background-color', self.configuration.debug.highlight.fields.unchanged);
        }
    });

    $(document).on('change', fieldsSelector, function (event) {
        var field = $(event.target);
        var isFormField = !self.searchClassFromArrayInElement(self.configuration.classes.nonFormFieldClasses, field);

        if (isFormField) {
            self.hasFieldChanged = true;

            if (self.configuration.debug.highlight.fields.changed) {
                if (field.attr('type') === 'radio') {
                    field.parent().css('background-color', self.configuration.debug.highlight.fields.changed);
                } else {
                    field.css('background-color', self.configuration.debug.highlight.fields.changed);
                }
            }
        }
    });


    return this;
}
var unchangeable_classes = ['decorative', 'constant'];
$(document).on('change', 'input,select,textarea', function () {
    var $this=$(this); 
    for(var i =0;i<unchangeable_classes.length;++i){
       if($this.hasClass(unchangeable_classes[i]))
           return;
    } 
    global_changed = true;
});

为什么不行,应该行吗? (根据评论进行编辑。)

我的想法>>

1)一种在调用setDate()之后停止调用changeDate()的方法,您可以只调用event.stopPropogation() ,这样可以防止事件冒泡

2)在创建动态元素时,可以添加您希望的任何属性。 例如

var iDiv = document.createElement('div');
iDiv.isDynamic = true;

然后在遍历元素时,检查isDynamic属性

为什么不向元素添加良性类标记

$('#foo').addClass('bar');

然后您可以检查该类以查看它是否已创建

if ($('#foo').hasClass('bar'))
    alert('was created');

请注意,添加元素时,必须重新附加事件。 因此,如果您有一个全局文档事件,然后添加一个元素,那么除非您明确附加新元素,否则不会包含该元素。

我正在发布第一个问题的答案。

我所做的是修改引导程序的源代码。 像这样调用setDate

$('#myDateInput').datepicker('setDate', new Date());

该代码通过setDates函数,该函数调用updatesetValue ,第一个导致在日期选择器本身中设置日期,第二个仅在输入文本字段中设置值。 我所做的是删除对“ change”的调用,该调用会触发该字段上的change事件,并留下自定义事件“ dateChange”。 这导致我的代码在我调用setDate时不会触发change事件,而是在用户使用选择器本身设置日期时调用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM