有没有一种可靠的、跨浏览器的方法在knockout中使用polyfills?

5
我们有一个网站,几乎完全由knockout驱动,我们需要支持所有主流浏览器,包括IE7(不包括IE6)及以上版本的Internet Explorer。
Chrome已经支持了我们实际关心的HTML5功能,而Modernizr则处理CSS hack得非常好。但是,有时我们仍然需要使用polyfills,其中两个值得注意的例子是placeholder属性和最近出现的details元素。
大多数polyfills都是基于jQuery插件的,这在理论上很好。不幸的是,它们也往往无法有效处理动态加载的内容——当您使用knockout(或任何模板引擎)时,这种情况就会很常见。更加复杂的是,我们将knockout用作真正的MVVM,因此没有合适的地方来插入一堆JS hack以重新加载插件(就我们的架构而言,这可能是一件好事,但在这个问题上令人沮丧)。
我们能够使用DOMNodeInserted事件(已弃用,我知道)在Firefox和IE9中提供半可靠的实现。不幸的是,在IE8中它不起作用,因为旧版IE不支持它,在这些浏览器中似乎几乎不可能复制。一开始onreadystatechange看起来很有前途,但事件往往会过早地触发-即使明确检查了readyState,而且polyfill也会错过目标,可以说。

我们唯一尝试过并在IE7/IE8中真正可靠的选项是使用重复的超时来每50毫秒重新运行polyfills。不幸的是,这也会消耗整个CPU,并将其增加到100毫秒甚至会导致UI中出现明显的延迟,因此不适合生产使用。

所以:是否有任何可靠的方法将传统的polyfill技术与动态内容和模板引擎(如knockoutjs)结合使用,可以在至少IE7的所有主要浏览器中工作?

< p > < em >(顺便说一句,我们最终使用了 Knockout 的 < code > afterRender 绑定来解决问题,但这有点让“polyfill”变得不太“poly”了。我希望有一种方法可以编写一次,然后就可以忘记它。)

使用特征检测可能没有跨浏览器实现占位符属性。你可能会想要使用IE的条件注释并忽略不支持它的其他浏览器。最简单的解决方案是不依赖于占位符(无论如何都不应该依赖它们),因此如果缺少它,用户也不会受到影响。占位符不应替换屏幕上的标签或格式提示,因为一旦输入内容,它就会消失,因此除非删除内容,否则标签或格式提示中的任何“帮助”值都将丢失。 - RobG
@RobG:恐怕我没有看到你的评论除了第一句话之外的相关性。当然,我们不依赖占位符 - 根据定义,它们实际上不是可以与任何行为相联系的属性,除了作为占位符。这并不意味着在大多数用户使用的一个浏览器中瘫痪功能是可以接受的。我认为你提出的解决方案并没有真正解决问题,也不会成为在所有浏览器中正确支持相同功能的商业道德理由。 - Aaronaught
关于条件注释的评论 - 如果我在问题中没有表述清楚,我很抱歉,但我们的挑战与仅在IE中执行代码毫无关系; 这个问题已经解决了多年。困难在于导致代码在初始页面加载后添加的标记或元素上执行 - 并且在IE中作为knockout / MVVM框架的一部分执行 - Aaronaught
我已经看到了你的问题,但是我没有答案,因此我发布了一条评论。我确定你已经意识到了以下内容,但我仍然会发布它。对于用户来说,很难区分占位符和值,并且由于两者的行为完全不同,它们可能会感到困惑和烦恼。因此,在不支持它们的浏览器中没有它们是一个合理的策略,这肯定不会造成瘫痪,甚至可能被视为一种优势。 - RobG
2
@RobG:评论部分不是用作一般讨论论坛,它的目的是为了请求和提供有关问题和答案的澄清。我几乎认为这不是适当的媒介来讨论placeholder属性的可用性,特别是因为我(故意)没有提及我们如何使用它,而且我们已经有一个[ux.se]网站来处理这个问题。我感谢您对这个主题的关注,但我宁愿不要有噪音,也不相信这会使其他成员受益。 - Aaronaught
1个回答

2
我解决同样的问题的方法是将大多数jQuery插件和行为,以及其他一般内容,封装在knockout绑定(http://knockoutjs.com/documentation/custom-bindings.html)中。因此,例如,我使用了一个placeholder“binding”在每个输入上,像这样<input data-bind="placeholder:'Some Placeholder Text'"/>,它只是设置了placeholder属性或根据需要执行一些IE hack。
更广泛的解决方案是增强knockout的绑定提供程序(http://www.knockmeout.net/2011/09/ko-13-preview-part-2-custom-binding.html)。绑定提供程序是遍历DOM(在加载和动态加载时)并识别绑定的东西。默认情况下,它基本上只是查找data-bind属性和ko注释,但您可以更改它以查找类似于占位符、日期或数字输入的输入类型等属性,并添加您的IE hack。

不太热衷于到处添加hack,但第二个选项看起来相当有前途。 - Aaronaught
@Aaronaught 自定义绑定不是黑客行为。它们是一种被鼓励的、正常的添加行为的方式。第一个选项是正确的选择。 - Kyeotic
@Tyrsius:当你需要特定的行为时,是的;对于填充(全局行为),则不太适用。 - Aaronaught
@Aaronaught 我不确定我是否理解你的意思。你提到的例子,placeholderdetails元素,都是自定义绑定的完美候选项。你认为哪些行为不适合放在绑定处理程序中? - Kyeotic
@Tyrsius:绑定是第一段所建议的 - 在各个地方添加类似于data-bind="placeholder: 'Blah'"这样的东西。那是一个hack。从整体上看,你可能不认为它是在特定情况下增强knockout行为的hack,但从解决每个问题而不是使用一个简单的polyfill的上下文来看,它是一个hack。第二个选项-更改KO绑定提供程序 - 对于KO本身来说更像是一个hack,但作为一个整体解决方案,它比较少有hack,因为它会像任何其他polyfill一样工作。 - Aaronaught
@Aaronaught 我理解,这确实有道理。我不同意改变绑定提供程序是一种hack,它是他们在2.0中故意添加的扩展点。甚至有关于如何做到这一点的文档。 - Kyeotic

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