如何使用jQuery选择将来存在的元素?

3

我有一个SVG,将要添加元素。在 mousemove 时,这些元素应该移动,所以我想选择未来存在的元素:

// #svgcanvas exist always
// #templine will exist in the future
$('#svgcanvas').bind('mousemove', function(e) {         
    $('#templine').setAttributeNS(null, "x2", e.pageX);
    $('#templine').setAttributeNS(null, "y2", e.pageY);
});

这里是在click事件中创建的#templine元素:

$('#svgcanvas').bind('click', function(e) {
    var line = document.createElementNS(xmlns, "line");
    line.setAttributeNS(null, "id", "templine");
    line.setAttributeNS(null, "x1", points[0].x);
    line.setAttributeNS(null, "y1", points[0].y);
    line.setAttributeNS(null, "x2", e.pageX);
    line.setAttributeNS(null, "y2", e.pageY);
    line.setAttributeNS(null, "style", "stroke:rgb(100,100,100)");
    document.getElementById('canvas').appendChild(line);
});

这段代码无法工作,因为在绑定时#templine不存在。有没有其他方法可以用jQuery解决这个问题?我已经尝试使用.live()代替.bind(),但在这种情况下并没有帮助。


2
不,如果这是你的问题,那肯定还有其他混乱的地方。$('#templine')将在每个事件上再次执行(顺便说一下,这可能会影响性能)。为什么你认为这是唯一的问题呢? - yankee
1
根据您的代码推测,可能会有多个“templine”元素,因此请使用“class”属性而不是“id”属性。 - bcoughlan
йЎәдҫҝиҜҙдёҖеҸҘпјҡдҪ зҡ„svgcanvas/clickеҮҪж•°зҡ„жңҖеҗҺ7иЎҢеҸҜд»Ҙзј©зҹӯдёә$(line).attr('id', '#templine').attr('x1',points[0].x).attr('y1', points[0].y).attr('x2', e.pageX).attr('y2', e.pageY).attr('style', 'stroke:rgb(100,100,100)').appendTo('#canvase');жҲ‘зӣёдҝЎгҖӮеҰӮжһңjQueryеңЁsvgдёҠжІЎжңүеҘҮжҖӘзҡ„иЎҢдёә... - yankee
@yankee:我希望$('#templine')在每次鼠标移动事件上都能执行,因为线条应该随着鼠标的移动而改变。所以我认为这是正确的。在你的建议之后,我会尝试缩短我的代码,谢谢。 - Jonas
@waitinforantrain:这段代码被简化了,我只会在第一次点击时创建一个带有id“templine”的单个元素。 - Jonas
3个回答

3
我能看到的问题是$('#templine')是一个jQuery对象,因此没有setAttributeNS方法。
请尝试使用以下代码替代:
$('#templine').attr("x2", e.pageX);
$('#templine').attr("y2", e.pageY);

很好的发现,但这不是OP提到的问题。 - Ruan Mendes
不是这样的,只有在单击#svgcanvas之后才会创建#templine。您不必再解释OP试图在jQuery对象上调用HTMLElement方法的问题。 - Ruan Mendes
@Juan:#templine 存在与否有什么关系吗?如果你试图在一个空的 jQuery 对象上调用一个函数,它只是不做任何事情。如果你调用一个不存在的函数,它会抛出一个错误并崩溃。 - gen_Eric
@Rocket:哇,我完全错过了那个。你可能想提议使用attr()而不是setAttributeNS... - yankee
@yankee:我不确定setAttributeNS的作用,因此我不知道正确的替代方法是什么,也不知道jQuery如何处理SVG元素。 - gen_Eric
显示剩余5条评论

3

试试这个:

$('#canvas').bind('click', function(e) {
    var line = document.createElementNS(xmlns, "line");
    line.setAttributeNS(null, "id", "templine");
    line.setAttributeNS(null, "x1", points[0].x);
    line.setAttributeNS(null, "y1", points[0].y);
    line.setAttributeNS(null, "x2", e.pageX);
    line.setAttributeNS(null, "y2", e.pageY);
    line.setAttributeNS(null, "style", "stroke:rgb(100,100,100)");
    document.getElementById('canvas').appendChild(line);
    $('#svgcanvas').bind('mousemove', function(e) {         
        line.setAttributeNS(null, "x2", e.pageX);
        line.setAttributeNS(null, "y2", e.pageY);
    });
});

另外,@Rocket的建议也是有效的。正在更新我的答案...

2
你应该采纳Rocket的建议:“$(...)[0].setAtttribute…” - Ruan Mendes
注意到了。我在发布答案后才注意到这一点。 - Mrchief
2
为了提高性能,我建议在每次鼠标移动时使用line.setAttributeNS而不是两次查询DOM。 - Ruan Mendes
谢谢再次提醒!显然今天我的头脑不太灵光,我会再次更新的! - Mrchief

0

两个选项:

  • 处理程序检查是否存在“#templine”,如果不存在,则不执行任何操作。
  • 在创建 #templine(在第二个处理程序的底部)之前,请勿安装处理程序

此外,不要连续两次调用 $('#templine'),请将结果保存在变量中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接