填充破坏了 jQuery 选择器?

发布于 2024-08-09 19:58:26 字数 2128 浏览 1 评论 0原文

今天早上我花了 2 个小时试图弄清楚为什么我的 jQuery 函数在页面的一部分起作用,但在另一部分不起作用。

我最终将其范围缩小到容器上的垂直填充。

如果我的 CSS 中有这个:

div.collapsiblePanel {
padding: 0px 1%;
}

那么,通过 jQuery,我可以找到父 (.collapsiblePanel) 元素,并可以遍历该 div 并操作子元素。但是,如果我将样式表中的这一件事更改为:

div.collapsiblePanel {
padding: 5px 1%;
}

然后 jQuery 可以找到父级 (.collapsiblePanel),但无法遍历子级。

疯了,对吧?关于正在发生的事情有什么理论吗?我一直在思考这个问题,认为它一定是我的 jQuery 的问题,但最终它是一个 CSS 问题。

根据请求,添加一些标记/css/代码片段:

特定的 jQuery 函数(看似)不起作用:

function finishUp(ajaxContainer,originalContainer,loadingAlert) {  
    $(ajaxContainer).find("input.btnSave").css("border","3px solid red");
    var saveButtonn = $(ajaxContainer).find("input.btnSave");
    console.log(ajaxContainer);
    console.log(originalContainer);
    console.log(loadingAlert);
    console.log(saveButton);
    $(ajaxContainer).find("input.btnSave").css("border","3px solid red").click(function(){
        alert("you clicked the save button");
        savePanel($(this));
    });

};  

它所做的是,在之前的函数通过 AJAX 加载内容然后显示容器之后,该函数进入并附加按钮的单击事件。

正如你所看到的,我在那里有一堆额外的日志代码。当我的 CSS 垂直填充设置为“0”时,Firebug 会记录每个对象的正确对象名称。当我将 CSS 垂直填充更改为其他任何内容时,最后一个对象 (saveButton) 在 Firebug 中返回为空/空白。

HTML:

<div class="ajaxEditPanel editablePanel collapsiblePanel" style="display: block;">       
    <form>
         <fieldset class="sideLabels dividers">
         <legend>Edit Realtionship Information</legend>

              ...the form...
                <div class="formItem formButtons"
                    <input value="save" class="button btnSave" type="button">
                    <input value="cancel" class="button btnCancel" type="button">
                </div>                    
         </fieldset>        
    </form>
 </div> 

请注意,DIV 是由以前的 jQuery 函数创建并加载内容的。起初我认为这是一个计时问题,我试图将一个事件附加到尚未加载到 DOM 中的对象。然而,这并不能解释为什么相同的功能在页面的其他地方起作用。我可以更改的一个变量(使这项工作有效或无效)最终就是 CSS 填充。如果在当前函数起作用的页面部分中,我还向容器添加了一些垂直填充,它们也会破坏 jQuery 选择子元素的功能。

I spent 2 hours this morning trying to figure out why my jQuery function worked in one part of the page but not another.

I finally narrowed it down to vertical padding on a container.

If I had this in my CSS:

div.collapsiblePanel {
padding: 0px 1%;
}

then, via jQuery, I can find the parent (.collapsiblePanel) element and could traverse into that div and manipulate the child elements. However, if I change just this one thing in my style sheet to this:

div.collapsiblePanel {
padding: 5px 1%;
}

Then jQuery can find the parent (.collapsiblePanel) but is unable to traverse the children.

Crazy, right? Any theories as to what is going on? I was banging my head on this one thinking it HAD to be something with my jQuery but it ultimately was a CSS issue.

Per request, some more snippets of markup/css/code:

The specific jQuery function that wasn't (seemingly) working:

function finishUp(ajaxContainer,originalContainer,loadingAlert) {  
    $(ajaxContainer).find("input.btnSave").css("border","3px solid red");
    var saveButtonn = $(ajaxContainer).find("input.btnSave");
    console.log(ajaxContainer);
    console.log(originalContainer);
    console.log(loadingAlert);
    console.log(saveButton);
    $(ajaxContainer).find("input.btnSave").css("border","3px solid red").click(function(){
        alert("you clicked the save button");
        savePanel($(this));
    });

};  

What that's doing is, after previous functions load content via AJAX and then display the container, this function comes in and attaches a click event to the button.

As you can see I have a bunch of extra logging code in there. When my CSS vertical padding is set to '0', Firebug logs the proper object name of each of those. When I change my CSS vertical padding to anything else, the last object (saveButton) comes back as empty/blank in Firebug.

The HTML:

<div class="ajaxEditPanel editablePanel collapsiblePanel" style="display: block;">       
    <form>
         <fieldset class="sideLabels dividers">
         <legend>Edit Realtionship Information</legend>

              ...the form...
                <div class="formItem formButtons"
                    <input value="save" class="button btnSave" type="button">
                    <input value="cancel" class="button btnCancel" type="button">
                </div>                    
         </fieldset>        
    </form>
 </div> 

Note that that DIV is being created by previous jQuery functions and loaded with content. At first I thought it was a timing issue, where I was trying to attach an event to an object that hadn't yet loaded into the DOM. However, that didn't explain why the same exact functions worked elsewhere on the page. The one variable I could change that would make this work or not work ended up being that bit of CSS padding. If, in the parts of the page where the function current works, I also add some vertical padding to the container, they also break jQuery selecting the child elements.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

权谋诡计 2024-08-16 19:58:26

我相信我之前也遇到过类似的情况 - 这可能是一个计时问题,在 JS 被告知绑定到元素之后,DOM 的渲染会稍微变慢。在您的情况下,填充可能会使 Firefox 花费几毫秒的时间来渲染这些 div ,从而导致绑定在有任何内容可以绑定之前触发。我知道 Firebug 还可以减慢渲染过程,因为它会在某些点跳入以在其帧中渲染源。

要确认不是这样,请尝试在绑定代码周围添加 setTimeout(function(){ ... }, 500) (也可能关闭 firebug)以查看其之后是否绑定。如果是的话,那就是你的问题了。

另一种方法可能是将您的输入更改为链接并使用事件委托来触发事件: jQuery('.btnSave').live('click', function(){savePanel($('selector>for>panel) '));
})

I believe I've come across something similar to this before - it could be a timing issue where the DOM is rendered slighlty after the JS is being told to bind to the elements. In your case the padding may be making firefox take a few milliseconds longer to render those divs and therefore causing the binding to trigger before there is anything to bind to. I understand Firebug can also slow-down the rendering process since it jumps-in at points to render the source in its frame.

To confirm it isn't this, try adding a setTimeout(function(){ ... }, 500) around your binding code (also maybe turning firebug off) to see whether it binds after that. If it does, then there's your problem.

Another approach may be to change your inputs into links and use event delegation to trigger the event: jQuery('.btnSave').live('click', function(){savePanel($('selector>for>panel'));
})

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文